🎨 Sysprovider Code
Sysprovider LogoWiki
🇪🇸Hosting español para ecommerce

Configuración de HAProxy con balanceo de carga y failover automático

Actualizado el 24 de diciembre de 2025

Introducción

En el ecosistema del hosting y la administración de servidores, la alta disponibilidad y la distribución eficiente de la carga de trabajo son pilares fundamentales para garantizar la continuidad del servicio. HAProxy (High Availability Proxy) se ha consolidado como la solución de facto para el balanceo de carga y la terminación de conexiones TCP/HTTP, destacando por su eficiencia, bajo consumo de recursos y robustez en entornos de producción.

Este artículo técnico profundiza en la configuración de HAProxy para implementar un sistema de balanceo de carga con failover automático. Abordaremos desde los fundamentos de su arquitectura hasta la puesta en marcha de un clúster de servidores web (backend) que tolere fallos sin degradación del servicio. No se trata de una guía superficial; cada directiva, algoritmo y ajuste será analizado en detalle, explicando el por qué de cada decisión.

Arquitectura y Conceptos Fundamentales

Antes de escribir una sola línea de configuración, es crucial comprender los componentes que intervienen. HAProxy opera bajo un modelo de proxy inverso y se compone de cuatro elementos esenciales: frontend, backend, defaults y global.

El Flujo de una Petición

  1. Cliente: Realiza una solicitud (HTTP, HTTPS, TCP) a la dirección IP y puerto del frontend.
  2. Frontend: Es el punto de entrada. Define las direcciones IP, puertos y protocolos que HAProxy escuchará. Aquí se aplican reglas de enrutamiento (ACLs) y se selecciona el backend al que se enviará el tráfico.
  3. Backend: Es el grupo de servidores reales que atienden las peticiones. Define los algoritmos de balanceo, las comprobaciones de estado (health checks) y la configuración de persistencia de sesión.
  4. Servidor: Cada instancia individual (ej. un servidor web Apache o Nginx) que forma parte del backend.

Tabla de Algoritmos de Balanceo Comunes

AlgoritmoDirectivaDescripciónCaso de Uso Típico
Round Robinbalance roundrobinDistribuye las peticiones secuencialmente entre los servidores. Es el más simple y efectivo cuando todos los servidores tienen capacidades similares.Cargas de trabajo homogéneas.
Least Connectionsbalance leastconnEnvía la nueva petición al servidor con el menor número de conexiones activas. Ideal para peticiones de larga duración o que consumen recursos variables.Aplicaciones con WebSockets o APIs REST pesadas.
Source IP Hashbalance sourceCalcula un hash de la IP del cliente para asignarlo siempre al mismo servidor. Garantiza persistencia de sesión sin necesidad de cookies.Aplicaciones que requieren afinidad de sesión basada en IP.
URI Hashbalance uriHash de la URI de la petición. Útil para caching, ya que la misma URL siempre irá al mismo servidor.Balanceo de cachés (Varnish, Squid).
Random (Two Choices)balance randomSelecciona dos servidores al azar y elige el que tenga menos carga (conexiones). Ofrece una excelente distribución sin el overhead de leastconn.Cargas de trabajo muy dinámicas y de alto rendimiento.

Nota importante sobre la persistencia de sesión: Aunque balance source proporciona persistencia basada en IP, no es infalible (problemas con NAT o proxies). Para aplicaciones web modernas, se recomienda usar cookies de aplicación (manejadas por la app) o las cookies de persistencia de HAProxy (cookie), que son más fiables y no dependen de la dirección IP del cliente.

Instalación y Configuración Base

Asumimos un sistema basado en Debian/Ubuntu. Los comandos son similares en CentOS/RHEL usando yum o dnf.

Paso 1: Instalación de HAProxy

sudo apt update
sudo apt install haproxy -y

¿Por qué? Los repositorios oficiales de Debian/Ubuntu contienen paquetes estables de HAProxy. La instalación desde los repositorios del sistema garantiza actualizaciones de seguridad gestionadas por el equipo de mantenimiento de la distribución.

Paso 2: Verificar la Instalación y la Versión

haproxy -v

Salida esperada (ejemplo):


HAProxy version 2.6.12-1ubuntu0.2 2024/01/15 - https://haproxy.org/

Paso 3: Configuración Inicial del Archivo Principal

El archivo de configuración principal es /etc/haproxy/haproxy.cfg. HAProxy permite dividir la configuración en múltiples archivos dentro de un directorio (ej. /etc/haproxy/conf.d/), pero para este artículo trabajaremos con un único archivo monolítico para mayor claridad.

Alerta de seguridad: Por defecto, HAProxy escucha en todas las interfaces (0.0.0.0). Asegúrate de que el firewall del sistema (iptables, nftables, ufw) restrinja el acceso a los puertos del frontend solo a las IPs necesarias. Nunca expongas el puerto de estadísticas (stats) a Internet.

Configuración del Failover Automático: Health Checks

El failover automático es la capacidad de HAProxy para detectar que un servidor backend ha fallado y enrutar el tráfico exclusivamente a los servidores saludables. Esto se logra mediante health checks.

Tipos de Health Checks

TipoDirectivaDescripción
Passivooption tcp-checkVerifica que el puerto TCP del servidor esté abierto y acepte conexiones. Rápido, pero no verifica la lógica de la aplicación.
Activooption httpchkRealiza una petición HTTP (ej. GET /health) y espera un código de respuesta específico (ej. 200). Verifica que el servidor web y la aplicación estén funcionando.
SSLoption ssl-hello-chkEnvía un "Client Hello" SSL/TLS para verificar que el servidor responde correctamente en el handshake.
Personalizadooption tcp-check + tcp-check send/expectPermite definir secuencias de comandos TCP para verificar servicios no estándar (bases de datos, Redis, etc.).

Ejemplo Práctico: Health Check HTTP para Servidores Web

Configuraremos un health check activo que solicite la ruta /health a cada servidor backend. Esta ruta debe ser implementada en la aplicación para devolver un código 200 solo cuando la aplicación esté completamente funcional (base de datos conectada, caché disponible, etc.).

backend web_servers
    # Algoritmo de balanceo: Round Robin con pesos
    balance roundrobin

    # Health Check HTTP
    option httpchk GET /health HTTP/1.1\r\nHost:\ web.example.com

    # Intervalo de chequeo y tolerancia a fallos
    server web1 192.168.1.10:80 check inter 2000 rise 2 fall 3 weight 10
    server web2 192.168.1.11:80 check inter 2000 rise 2 fall 3 weight 10
    server web3 192.168.1.12:80 check inter 2000 rise 2 fall 3 weight 10

Desglose de parámetros del servidor:

  • check: Habilita el health check para este servidor.
  • inter 2000: Intervalo entre chequeos en milisegundos (2 segundos). Un valor bajo detecta fallos rápido, pero genera más carga en el servidor y en HAProxy. Para entornos de alta criticidad, se puede bajar a 1000ms.
  • rise 2: Número de chequeos exitosos consecutivos necesarios para considerar al servidor como UP (operativo). Evita que un servidor se marque como disponible tras una fluctuación momentánea.
  • fall 3: Número de chequeos fallidos consecutivos para marcar al servidor como DOWN (inactivo). Un valor de 3 con inter 2000 significa que HAProxy tardará 6 segundos en detectar un fallo y redirigir el tráfico.
  • weight 10: Peso del servidor en el algoritmo de balanceo. Si todos tienen el mismo peso, el tráfico se distribuye equitativamente. Se puede ajustar para servidores más potentes (ej. weight 20).

¿Por qué option httpchk y no option tcp-check? Un servidor web puede tener el puerto 80 abierto (TCP OK) pero la aplicación puede estar colapsada o en un bucle infinito. Un health check HTTP que solicita una URL específica es la única forma de garantizar que el servicio de aplicación está respondiendo correctamente.

Implementación de Failover Automático: Escenario Completo

Construyamos un escenario real: un frontend HTTPS que balancea peticiones a tres servidores web Nginx, con failover automático y terminación SSL en HAProxy (SSL offloading).

Estructura del Archivo de Configuración

global
    # Configuración global del proceso
    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

    # Tuning de rendimiento
    maxconn 4096
    tune.ssl.default-dh-param 2048

defaults
    log global
    mode http
    option httplog
    option dontlognull
    option http-server-close
    option forwardfor except 127.0.0.0/8
    option redispatch
    retries 3
    timeout http-request 10s
    timeout queue 1m
    timeout connect 10s
    timeout client 1m
    timeout server 1m
    timeout http-keep-alive 10s
    timeout check 10s
    maxconn 3000

frontend www_https
    bind *:443 ssl crt /etc/ssl/certs/example.com.pem
    bind *:80 name http_redirect
    redirect scheme https code 301 if !{ ssl_fc }

    # ACLs para enrutamiento
    acl is_api hdr_end(host) -i api.example.com
    acl is_static hdr_end(host) -i static.example.com

    use_backend api_servers if is_api
    use_backend static_servers if is_static
    default_backend web_servers

frontend stats
    bind *:8080
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:changeme_strong_password
    stats admin if LOCALHOST

backend web_servers
    balance roundrobin
    option httpchk GET /health HTTP/1.1\r\nHost:\ web.example.com
    http-request set-header X-Forwarded-Proto https if { ssl_fc }

    server web1 192.168.1.10:80 check inter 2000 rise 2 fall 3 weight 10
    server web2 192.168.1.11:80 check inter 2000 rise 2 fall 3 weight 10
    server web3 192.168.1.12:80 check inter 2000 rise 2 fall 3 weight 10

backend api_servers
    balance leastconn
    option httpchk GET /api/health HTTP/1.1\r\nHost:\ api.example.com
    server api1 192.168.1.20:3000 check inter 1000 rise 2 fall 3 weight 5
    server api2 192.168.1.21:3000 check inter 1000 rise 2 fall 3 weight 5

backend static_servers
    balance uri
    option httpchk HEAD /health HTTP/1.1\r\nHost:\ static.example.com
    server static1 192.168.1.30:80 check inter 3000 rise 3 fall 5 weight 20
    server static2 192.168.1.31:80 check inter 3000 rise 3 fall 5 weight 20

Análisis Detallado de la Configuración

Sección global:

  • stats socket: Permite la administración dinámica de HAProxy (ej. poner servidores en mantenimiento) a través de un socket Unix. Es una práctica de seguridad excelente, ya que no expone una interfaz de red.
  • tune.ssl.default-dh-param 2048: Fuerza el uso de parámetros Diffie-Hellman de 2048 bits para mejorar la seguridad en el handshake SSL. Sin esta línea, HAProxy usa 1024 bits por defecto, lo cual es inseguro.

Sección defaults:

  • option http-server-close: Cierra la conexión del lado del servidor después de cada petición, pero mantiene la conexión del lado del cliente (Keep-Alive). Reduce el consumo de conexiones en los servidores backend.
  • option forwardfor: Añade la cabecera X-Forwarded-For con la IP real del cliente. Esencial para logs de acceso y aplicaciones que necesitan la IP origen.
  • option redispatch: Si un servidor falla y hay una sesión persistente, HAProxy puede redirigir la petición a otro servidor (rompiendo la persistencia). Esto es mejor que devolver un error 503.
  • timeout http-request 10s: Tiempo máximo para que el cliente envíe la petición HTTP completa. Protege contra ataques de conexión lenta (Slowloris).

Sección frontend www_https:

  • bind *:443 ssl crt ...: Escucha en todas las interfaces en el puerto 443, usando el certificado SSL/TLS combinado (certificado + clave privada) en un solo archivo .pem.
  • redirect scheme https code 301 if !{ ssl_fc }: Redirige automáticamente todo el tráfico HTTP (puerto 80) a HTTPS, devolviendo un código 301 (Moved Permanently). Esto es SEO-friendly y seguro.
  • ACLs: Usamos hdr_end(host) para enrutar basándonos en el dominio. Esto permite servir múltiples aplicaciones desde el mismo HAProxy.

Sección backend web_servers:

  • http-request set-header X-Forwarded-Proto https if { ssl_fc }: Añade la cabecera X-Forwarded-Proto para indicar al servidor backend que la conexión original era HTTPS. Es crucial para que las aplicaciones generen URLs correctas (ej. redirecciones con https://).
  • Health Check: El health check solicita /health con el Host header web.example.com. Esto simula una petición real y verifica que el virtual host esté funcionando.

Mecanismos Avanzados de Failover y Tolerancia a Fallos

1. Backup de Servidores

Puedes definir servidores de respaldo que solo reciban tráfico si todos los servidores principales fallan.

backend web_servers
    server web1 192.168.1.10:80 check
    server web2 192.168.1.11:80 check
    server backup1 192.168.1.100:80 check backup

2. Failover de HAProxy (Alta Disponibilidad del Balanceador)

HAProxy en sí mismo puede ser un punto único de fallo (SPOF). Para solventarlo, se utiliza Keepalived o Pacemaker para gestionar una IP virtual (VIP) que flota entre dos nodos HAProxy.

# Instalar keepalived
sudo apt install keepalived -y

Configuración de Keepalived (MASTER):

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass mi_contraseña_segura
    }
    virtual_ipaddress {
        192.168.1.200/24 dev eth0
    }
}

¿Por qué? Si el nodo HAProxy primario falla, Keepalived detecta la ausencia de anuncios VRRP y promueve al nodo secundario, que asume la IP virtual. El cliente no percibe interrupción alguna.

3. Drenaje de Conexiones (Maintenance Mode)

Cuando necesitas reiniciar un servidor backend sin perder peticiones activas, puedes marcarlo como MAINT (maintenance) a través

¿Necesitas ayuda?Son dos de nuestros técnicos, Agustín y Mikel, y están disponibles para resolver cualquier problema.

Hablar con ellos ahora
Agustín y Mikel