Tabla de contenido
¡Hola de nuevo! Hoy vamos a hablar de enrutamiento y balanceo básico HTTP con HAProxy.
¿Qué es HAProxy?
HAProxy en un software que nos permite ejecutar balanceos de carga mediante HTTP o TCP (no permite balancear UDP).
Características
- Permite SSL configurado en HAProxy y/o en el backend
- Soporta IPv6
- Admite ACL
- Soporta VirtualHosts
- Puede configurar healthchecks o comprobacion de estado de los backends
- Permite HTTP Keep-Alive
Modos de trabajo principales
Tiene dos formas de funcionar:
- Modo TCP: Puede balancear entre varios servidores SSH, MySQL, SMTP, etc.
- Modo HTTP: Utilizando los estándares de HTTP y HTTPS puede ejecutar balanceo entre varios servidores web y modificar las cabeceras de la conexión.
Formas de balanceo
Puede balancear en base a las siguientes políticas:
- Roundrobin: balancea entre los distintos servidores backend.
- Leastconn: Balancea teniendo en cuenta que el número de conexiones redirigidas se haga de forma equilibrada entre los backends. Se recomienda para conexiones largas
- Source: Se puede balancear la petición para que dependiendo de la IP de la petición las siguientes vayan siempre al mismo backend.
Sticky sessions
Algunas aplicaciones pueden necesitar que el usuario se conecte al mismo servidor backend. Esto se consigue a través de Sticky Sessions utilizando el parámetro appsession en el backend que lo requiera.
Ejemplo de balanceo por defecto
Por defecto el balanceo será 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:~#
En el ejemplo se balancea el puerto 80 de todas las IPs de la maquina y se destinan al backend web1 que está compuesto por los servidores s1 (172.17.0.3) y s2 (172.17.0.4). Para verlo mejor en lo ejemplos que hagamos, el s1 es es Nginx y el s2 es 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 ~]#
El servidor de haproxy está configurado en la IP 172.17.0.2. Si se le hacen peticiones balancea entre los 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 ~]#
Ejemplo de varios tipos de balanceo
Para modificar el tipo de balanceo se especifica la sentencia balance acompañado del nombre del tipo de balanceo:
Roundrobin
backend web1
mode http
balance roundrobin
server s1 172.17.0.3:80 weight 2
server s2 172.17.0.4:80 weight 1Cada servidor tiene un peso definido por la sentencia weight y el número de su peso. A mayor numero de peso mas posibilidades tiene de recibir peticiones. En el ejemplo anterior el servidor s1, recibirá mas peticiones.
Source
backend web1
mode http
balance source
server s1 172.17.0.3:80
server s2 172.17.0.4:80Leastconn
backend web1
mode http
balance leastconn
server s1 172.17.0.3:80
server s2 172.17.0.4:80Healthchecks
Los healthchecks o comprobaciones de salud, son pruebas que se realizan para conocer el estado de los servidores de backend para saber si están disponibles y así redirigir solo las peticiones a los que estén en buen estado.
Si uno de estos servidores se cae, con la configuración básica que hemos puesto anteriormente, al no hacer comprobaciones, podrían redirigirse peticiones al backend que está caído.
Esto se puede solucionar añadiendo comprobaciones al backend utilizando el parámetro check en la sentencia server que define el servidor de backend:
backend web1 mode http server s1 172.17.0.3:80 check server s2 172.17.0.4:80 check
Healthchecks activos
Los Healthchecks activos son los que se efectúan por defecto cuando solo especificamos la palabra check como en el ejemplo anterior. Este tipo de comprobaciones se realizan de forma periódica a los backends.
La estructura es la siguiente:
server nombre host:puerto check inter tiempo fall numero rise numero
Los parámetros de check defecto se hacen de esta forma con los :
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
El significado de los parámetros de check son los siguientes:
- inter: Establece el tiempo de separación entre comprobaciones (por defecto 2 segundos)
- fall: Número de comprobaciones para marcar como caido un backend que funcionaba
- rise: Número de comprobaciones para marcar como optimo un backend que estaba caido.
Se puede ver más acerca de los healthchecks en https://www.haproxy.com/blog/how-to-enable-health-checks-in-haproxy/