sábado, 16 de mayo de 2020

[EN] How to update backend servers on HAproxy using HAproxy API (and not reloading config)

The HAproxy API is a great tool to interact with the configuration, updating it without the need to reload after every change (which is completely safe as stated here). In this case, I am just going to add and remove a backend server, so you can see how it works and how powerful it could be

I am going to use netcat instead of socat, but the result will be very similar.

When you configure your HAproxy, make sure that the backend block will have the server definition, which is going to be something like

> server-template websrv 1-100 192.168.122.1:80 check disabled

where

    server-template is the section of the block
    websrv will be the name of the backend servers, followed by a number
    1-100 is the range for that number that will complete the name of the backend servers
    192.168.122.1 will be an template address, but make sure that you have nothing there (you can set any IP you want)
    80 is the port you are balancing the traffic
    check disabled is an option, but we don't really want the check to be enabled because the host IP won't pass the check

You can add more options if you need, but that's a basic example.

Another important thing you need to know or count with is the number of sockets your HAproxy will have, because you'll have to inform all of them about the changes you are going to make. Keep that in mind.

Once your haproxy starts, you have no backend server listening, and you need to any some; remember that the idea is that you run a background process to update those servers.
The commands to enable and add a new backend server are

> echo "set server #BACKEND_BLOCK/#WEBSRV_NUMBER addr #IP_ADDRESS port #PORT" | nc -U #SOCKET
> echo "set server #BACKEND_BLOCK/#WEBSRV_NUMBER state ready" | nc -U #SOCKET

where
    #BACKEND_BLOCK is the backend block's name
    #WEBSRV_NUMBER is the backend server's name on haproxy
    #IP_ADDRESS is the IP of that new backend server
    #PORT is the port
    #SOCKET is the HAproxy socket you are talking to

After running the first command, your HAproxy will notify the changes (IP and port if they have changed), and after running the second command there will be no output.

> echo "set server backend/server50 addr 1.1.1.1 port 8080" | nc -U /var/run/haproxy.sock

IP changed from '192.168.122.1' to '1.1.1.1', port changed from '80' to '8080' by 'stats socket command'

> echo "set server backend/server50 state ready" | nc -U /var/run/haproxy.sock


and this way your HAproxy instance will start to send traffic to that backend server. If you have more that one instances of HAproxy running, you'll have to spread the changes to all of them; the command would be the same, just change the socket you are talking to.


In the case you want to put a server in maintenance state (so disable it), the command would be

> echo "set server backend/server50 state maint" | nc -U /var/run/haproxy.sock

Besides ready and maint, there is a thrird state of haproxy: drain; in this state the backend server is removed from the Load Balancer, but still allowed it to be checked and to accept new persistent connections.

Source: HAproxy.com