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

7 Answers 7

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.

1
  • 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, 2020 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
1
  • 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, 2015 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

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
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
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .