50

I have haproxy running as my load-balancer and from the stats web interface that comes with haproxy, I can put a web server into maintenance mode (and bring it back out again) - which is great!

However, I also want to be able to perform that same action from the command line (for use in some automated deployment workflows). Is this possible, and if so how?

Many thanks

isNaN1247
  • 1,615
  • 3
  • 15
  • 20

7 Answers7

64

Update (28 Aug 2012): I now tend to use haproxyctl nowadays, which utilizes the methods described below.


I've fixed it after a little more research, for anyone else with the same issue:-

You can add a unix socket in your config, then interact with that (here are the possible commands).

To set up:

sudo nano /etc/haproxy/haproxy.cfg

In your 'global' section add in:

stats socket /etc/haproxy/haproxysock level admin

Restart your haproxy daemon (e.g. sudo service haproxy restart)

Now you need socat (if you don't have it, just apt-get install socat on Ubuntu).

Now all you need to do is fire off this command to take down a node:

echo "disable server yourbackendname/yourservername" | socat stdio /etc/haproxy/haproxysock

To bring it back up replace disable with enable in the command above.

Marc Climent
  • 277
  • 6
  • 14
isNaN1247
  • 1,615
  • 3
  • 15
  • 20
  • Hi. May I know why most of the time it doesn't work? I am using Haproxy 1.8. EG: Although it is showing weight "0 (initial 60)", the interface still showing weight 60 and connections still flow through. – neobie Mar 31 '20 at 17:48
21

In addition to beardwizzle's echo method, you can also do this interactively:

root@ny-lb01:/etc/haproxy# sudo socat readline /var/run/haproxy.stat 

prompt
> set timeout cli 1d
> disable server foo/web01
> help
Unknown command. Please enter one of the following commands only :
  clear counters : clear max statistics counters (add 'all' for all counters)
  clear table    : remove an entry from a table
  help           : this message
  prompt         : toggle interactive mode with prompt
  quit           : disconnect
  show info      : report information about the running process
  show stat      : report counters for each proxy and server
  show errors    : report last request and response errors for each proxy
  show sess [id] : report the list of current sessions or dump this session
  show table [id]: report table usage stats or dump this table's contents
  get weight     : report a server's current weight
  set weight     : change a server's weight
  set timeout    : change a timeout setting
  disable server : set a server in maintenance mode
  enable server  : re-enable a server that was previously in maintenance mode
Kyle Brandt
  • 82,107
  • 71
  • 302
  • 444
  • 7
    A _big_ pitfall here is that Debian's socat does not support "readline" though it says so in the man page. They patched it out due to a licence clash between libreadline (GPL) and OpenSSL. In this case you use `socat /var/run/haproxy.stat stdio` for every single command – bentolor May 29 '15 at 16:24
9

On the off chance that you only have access to netcat (nc) you can use it to interact with HAProxy's socket file in a similar fashion to socat.

$ echo "show info" | nc -U /var/lib/haproxy/stats | head -10
Name: HAProxy
Version: 1.5.2
Release_date: 2014/07/12
Nbproc: 1
Process_num: 1
Pid: 29745
Uptime: 0d 0h14m35s
Uptime_sec: 875
Memmax_MB: 0
Ulimit-n: 8034

To disable a server:

$ echo "enable server bk_dservers/ds02" | nc -U /var/lib/haproxy/stats

Take care to make sure that the socket file has the appropriate level of access to perform the above. Mainly something like this:

stats       socket /var/lib/haproxy/stats level admin

Otherwise you'll get permission denied errors:

$ echo "disable server bk_dservers/ds02" | nc -U /var/lib/haproxy/stats
Permission denied

$

References

slm
  • 7,355
  • 16
  • 54
  • 72
7

The easy way is:

1 - Configure your web server to return 503 code if a file named maintenance.html (for example) exists. With apache you can do it as follows:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{ENV:REDIRECT_STATUS} !=503
  RewriteCond "/var/www/maintenance.html" -f
  RewriteRule ^(.*)$ /$1 [R=503,L]
</IfModule>

2 - Configure your haproxy backend to check an URL instead of only checking a port as follows:

backend site
    balance roundrobin
    option httpchk GET /index.html
    server myserver1.example.com 192.0.2.1:80 cookie S1 check inter 2000 fall 3
    server myserver2.example.com 192.0.2.2:80 cookie S2 check inter 2000 fall 3

3 - Restart your webserver and load balancer.

4 - Put your web server in maintenance mode.

touch /var/www/maintenance.html

5 - Remove your web server from maintenance mode.

rm -f /var/www/maintenance.html
Patrick Mevzek
  • 9,273
  • 7
  • 29
  • 42
mijhael3000
  • 136
  • 2
  • 4
2

You can also temporarily "remove" the health check page from one server, to get the endpoint down and then publish your application.

1

In HAProxy 1.8 you can also use set server state:


put the server in maintenance (or drain) mode:

echo "set server backend_name/sever_name state maint" | socat stdio /path_to_admin_socket_file
echo "set server backend_name/sever_name state drain" | socat stdio /path_to_admin_socket_file

put the server back to ready mode:

echo "set server backend_name/sever_name state ready" | socat stdio /path_to_admin_socket_file
lainatnavi
  • 158
  • 7
0

If you have debian, readline does not work, netcat is a better option for interactive:

user@server:/etc/haproxy$ sudo nc -U /etc/haproxy/haproxysock
prompt
> show info
Name: HAProxy
Version: 1.7.11-1ppa1~xenial
Release_date: 2018/04/30
Nbproc: 1
Process_num: 1
Pid: 12307
Uptime: 0d 10h33m22s
...

Non Interactive:

echo "show info;show stat" | sudo nc -U /etc/haproxy/haproxysock