Enrutamiento y balanceo básico HTTP con HAProxy

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

Cada 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:80

Leastconn

backend web1
    mode http
    balance leastconn
        server s1 172.17.0.3:80 
        server s2 172.17.0.4:80

Healthchecks

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/

 

Deja una respuesta