Tabla de contenido
Hello again! Today we are going to talk about basic HTTP routing and balancing with HAProxy.
What is HAProxy?
HAProxy is a software that allows us to perform load balancing via HTTP or TCP (it does not allow UDP balancing).
- Allows SSL configured on HAProxy and/or on the backend
- IPv6 support
- Supports ACL
- Supports VirtualHosts
- You can configure healthchecks or status check of the backends.
- Enables HTTP Keep-Alive
Main working modes
It has two ways of working:
- TCP mode: You can balance between several SSH, MySQL, SMTP, etc. servers.
- HTTP mode: Using HTTP and HTTPS standards you can perform balancing between several web servers and modify the connection headers.
You can balance based on the following policies:
- Roundrobin: balances between the different backend servers.
- Leastconn: Balances taking into account that the number of redirected connections is balanced among the backends. Recommended for long connections
- Source: The request can be balanced so that depending on the IP of the request the following ones always go to the same backend.
Some applications may require the user to connect to the same backend server. This is achieved through Sticky Sessions by using the appsession parameter in the backend that requires it.
Ejemplo de balanceo por defecto
By default the mode will be Roundrobin.
root@haproxy:~# cat /etc/haproxy/haproxy.cfg global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http frontend web1 bind *:80 mode http use_backend web1 default_backend web1 backend web1 mode http server s1 172.17.0.3:80 server s2 172.17.0.4:80 root@haproxy:~#
In the example port 80 of all the IPs of the machine is balanced and destined to the backend web1 which is composed by the servers s1 (172.17.0.3) and s2 (172.17.0.4). To see it better in the examples that we will make, the s1 is Nginx and the s2 is Apache:
[ger-pc ~]# curl -s 172.17.0.3|grep nginx -i|head -n 1 <title>Welcome to nginx!</title> [ger-pc ~]# curl -s 172.17.0.4|egrep "apache|nginx" -i|head -n 1 <address>Apache/2.4.52 (Debian) Server at 172.17.0.4 Port 80</address> [ger-pc ~]#
The haproxy server is configured on IP 172.17.0.2. If requests are made it balances between the 2 backends:
[ger-pc ~]# curl -s 172.17.0.2|egrep "apache|nginx" -i|head -n 1 <title>Welcome to nginx!</title> [ger-pc ~]# curl -s 172.17.0.2|egrep "apache|nginx" -i|head -n 1 <address>Apache/2.4.52 (Debian) Server at 172.17.0.2 Port 80</address> [ger-pc ~]# curl -s 172.17.0.2|egrep "apache|nginx" -i|head -n 1 <title>Welcome to nginx!</title> [ger-pc ~]# curl -s 172.17.0.2|egrep "apache|nginx" -i|head -n 1 <address>Apache/2.4.52 (Debian) Server at 172.17.0.2 Port 80</address> [ger-pc ~]#
Example of various types of balancing
To modify the type of balancing, the statement balance is specified together with the name of the type of balancing:
backend web1 mode http balance roundrobin server s1 172.17.0.3:80 weight 2 server s2 172.17.0.4:80 weight 1
Each server has a weight defined by the weight statement and the number of its weight. The higher the weight number, the more likely it is to receive requests. In the previous example the server s1, will receive more requests.
backend web1 mode http balance source server s1 172.17.0.3:80 server s2 172.17.0.4:80
backend web1 mode http balance leastconn server s1 172.17.0.3:80 server s2 172.17.0.4:80
The healthchecks are tests that are performed to know the status of the backend servers to know if they are available and thus redirect only the requests to those that are in good condition.
If one of these servers goes down, with the basic configuration we have set up above, by not doing health checks, requests could be redirected to the backend that is down.
This can be solved by adding checks to the backend using the check parameter in the server statement that defines the backend server:
backend web1 mode http server s1 172.17.0.3:80 check server s2 172.17.0.4:80 check
Active Healthchecks are the ones that are performed by default when we only specify the word check as in the previous example. This type of checks are performed periodically to the backends.
The structure is as follows:
server nombre host:puerto check inter tiempo fall numero rise numero
The default check parameters are made in this way with the :
backend web1 mode http server s1 172.17.0.3:80 check inter 2s fall 3 rise 2 server s2 172.17.0.4:80 check inter 2s fall 3 rise 2
The meaning of the check parameters are as follows:
- inter: Set the time of separation between checks (default 2 seconds)
- fall: Number of checks to mark as down a backend that was working.
- rise: Number of checks to mark as optimal a backend that was down.
You can learn more about healthchecks at https://www.haproxy.com/blog/how-to-enable-health-checks-in-haproxy/