Preserve backend server status when reloading haproxy

haproxy

Because I have a large pool of https certificates that changes from day to day (massive multitenant application with many domains), I have a script that may reload haproxy at nearly random times. This works fine.

I also set backend servers to MAINT when I am deploying new versions of applications to them. This also works fine.

The trouble is that if the reload happens, any servers that I had set to MAINT status are instead reloaded as READY. This lets customers see waits or even error messages.

Is there a way to preserve the current status of backend servers when reloading haproxy?

Best Answer

Not sure which version you're using, the following needs HAProxy >= 1.6~:

You might want to have a look at the load-server-state-from-file directive, which allows

seamless reloads of HAProxy.

This directive points HAProxy to a file where server state from previous running process has been saved. That way, when starting up, before handling traffic, the new process can apply old states to servers exactly has if no reload occured. [...]

(That's just an excerpt, for more details follow the link.)

Using this, your config could look like (only relevant parts shown):

global
  server-state-file /var/lib/haproxy/server-state
  stats socket /var/lib/haproxy/stats

defaults
  load-server-state-from-file global

Your reload command could then look like the following:

socat /var/lib/haproxy/stats - <<< \"show servers state\" > /var/lib/haproxy/server-state && systemctl reload-or-restart haproxy

That is:

  • Connect to the stats socket via socat, get the states of the servers and / or backends and write to the state file.
  • After this, if all went well, reload or restart HAProxy.