HAProxy e Keepalived: Load Balancer com Alta Disponibilidade para PME
Neste artigo
1. Introdução
O HAProxy (High Availability Proxy) é um dos balanceadores de carga código aberto mais rápidos e fiáveis do mercado. Combinado com o Keepalived, que implementa o protocolo VRRP para failover automático, obtém-se uma solução de alta disponibilidade robusta sem custos de licenciamento — ideal para pequenas e médias empresas (PME).
Uma PME com dois ou três servidores web precisa de distribuir o tráfego entre eles e garantir que, se o balanceador principal cair, um secundário assuma automaticamente o endereço IP virtual. É exactamente isto que HAProxy + Keepalived entrega: load balancing na camada 4 (TCP) ou 7 (HTTP) com failover transparente em segundos.
ℹ Porquê HAProxy + Keepalived para PME?
Soluções comerciais como F5 BIG-IP ou Citrix ADC custam milhares de euros. HAProxy e Keepalived são gratuitos, código aberto (GPLv2), consomem poucos recursos (correm em VMs de 1 vCPU / 512 MB RAM) e suportam centenas de milhares de ligações simultâneas.
A topologia típica para PME é active-passive: dois nós balanceadores (lb1 e lb2) partilham um IP virtual (VIP). O lb1 é o MASTER e processa todo o tráfego; o lb2 fica em BACKUP pronto para assumir. Se o lb1 cair, o Keepalived detecta a falha em 3 segundos e o lb2 assume o VIP. Em active-active, ambos os nós processam tráfego simultaneamente usando DNS round-robin ou múltiplos VIPs — mais complexo mas dobra a capacidade.
| Componente | Função | Porta típica |
|---|---|---|
| HAProxy | Balanceamento de carga L4/L7 | 80 / 443 |
| Keepalived | Failover com VRRP (IP virtual) | Protocolo 112 (VRRP) |
| Backend web | Servidores Nginx/Apache reais | 8080 / 8443 |
2. Instalar HAProxy
O HAProxy está disponível nos repositórios oficiais das principais distribuições Linux. Em Debian/Ubuntu, a instalação é directa com apt. Em RHEL/CentOS/AlmaLinux usa-se dnf.
2.1 Debian e Ubuntu
# Actualizar repositórios e instalar
sudo apt update
sudo apt install -y haproxy keepalived
# Verificar versão instalada
haproxy -v
# HAProxy versão 2.6.x
2.2 RHEL, AlmaLinux e Rocky Linux
# Instalar via dnf
sudo dnf install -y haproxy keepalived
# Activar arranque no boot
sudo systemctl enable haproxy keepalived
⚠ Atenção
As versões nos repositórios base podem ser antigas. Para HAProxy 2.8+ (recomendado), adicionar o PPA oficial em Ubuntu: sudo add-apt-repository ppa:vbernat/haproxy-2.8 ou compilar a partir do código-fonte disponível em haproxy.org.
Após a instalação, o ficheiro de configuração principal fica em /etc/haproxy/haproxy.cfg. O Keepalived usa /etc/keepalived/keepalived.conf. Ambos devem ser configurados em ambos os nós (lb1 e lb2).
3. Configurar Load Balancing L4/L7
O HAProxy opera em duas modalidades: modo L4 (TCP), que balanceia ligações raw sem inspeccionar o conteúdo HTTP, e modo L7 (HTTP), que analisa cabeçalhos, cookies e URLs para decisões mais inteligentes. Para a maioria das PME, o modo L7 (HTTP) é o mais adequado pois permite persistência por cookie, encaminhamento por URL e compressão.
3.1 Configuração base (modos L4 e L7)
# /etc/haproxy/haproxy.cfg
global
log /dev/log local0
maxconn 4096
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
timeout connect 5s
timeout client 30s
timeout server 30s
retries 3
# Frontend HTTP (modo L7)
frontend web_http
bind *:80
default_backend servidores_web
# Backend com 3 servidores reais
backend servidores_web
balance roundrobin
option httpchk GET /health
server web1 192.168.1.101:8080 check
server web2 192.168.1.102:8080 check
server web3 192.168.1.103:8080 check
# Alternativa: modo L4 (TCP) para base de dados
frontend db_front
bind *:3306
mode tcp
default_backend db_back
backend db_back
mode tcp
balance leastconn
server db1 192.168.1.201:3306 check
server db2 192.168.1.202:3306 check
3.2 Algoritmos de balanceamento
| Algoritmo | Como funciona | Quando usar |
|---|---|---|
| roundrobin | Distribui pedidos em ronda | Servidores com capacidade igual |
| leastconn | Envia para o servidor com menos ligações | Ligações longas (BD, WebSocket) |
| source | Hash do IP de origem (afinidade) | Sessões sticky sem cookies |
| uri | Hash do URL (cache locality) | CDN, caching reverse proxy |
3.3 Health checks e persistência por cookie
# Health check HTTP personalizado
backend servidores_web
balance roundrobin
option httpchk GET /health HTTP/1.1\r\nHost:\ localhost
http-check expect status 200
cookie SERVERID insert indirect nocache
server web1 192.168.1.101:8080 check cookie s1
server web2 192.168.1.102:8080 check cookie s2
server web3 192.168.1.103:8080 check cookie s3
# Parâmetros de health check avançados
# inter — intervalo entre checks (2s por defeito)
# rise — checks bem-sucedidos para marcar UP (2)
# fall — checks falhados para marcar DOWN (3)
# Check a cada 2s, considera UP após 2 sucessos, DOWN após 3 falhas
server web1 192.168.1.101:8080 check inter 2s rise 2 fall 3
A directiva cookie SERVERID insert injecta um cookie no cliente que garante que pedidos subsequentes vão sempre para o mesmo servidor. Isto é essencial para aplicações que guardam estado de sessão localmente (PHP sessions, Django, etc.). O httpchk envia um pedido HTTP real ao backend e verifica o código de resposta — mais fiável que um simples check TCP.
4. SSL Termination
No SSL termination, o HAProxy termina a ligação HTTPS, descifra o tráfego e comunica com os backends por HTTP simples. Isto reduz a carga nos servidores web (não precisam de processar TLS) e centraliza a gestão de certificados num único ponto. A alternativa é SSL passthrough (modo TCP), onde o HAProxy repassa a ligação cifrada directamente ao backend sem descifrar.
4.1 Configuração com certificados Let’s Encrypt
# /etc/haproxy/haproxy.cfg — secção frontend HTTPS
frontend web_https
bind *:443 ssl crt /etc/haproxy/certs/app.pt.pem alpn h2,http/1.1
redirect scheme https code 301 if !{ ssl_fc }
# Extrair certificado + chave combinados
# cat /etc/letsencrypt/live/app.pt/fullchain.pem \
# /etc/letsencrypt/live/app.pt/privkey.pem \
# > /etc/haproxy/certs/app.pt.pem
# chmod 600 /etc/haproxy/certs/app.pt.pem
# Headers de segurança
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains"
http-response set-header X-Content-Type-Options nosniff
http-response set-header X-Frame-Options DENY
default_backend servidores_web
# Redireccionar HTTP para HTTPS
frontend web_http
bind *:80
redirect scheme https code 301 if !{ ssl_fc }
4.2 Múltiplos certificados (SNI)
# Directório com todos os certificados PEM combinados
# Um ficheiro por domínio: app.pt.pem, blog.pt.pem, loja.pt.pem
frontend web_https
bind *:443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1
# Routing por SNI (Server Name Indication)
acl is_loja hdr(host) -i loja.pt
acl is_blog hdr(host) -i blog.pt
use_backend loja_web if is_loja
use_backend blog_web if is_blog
default_backend servidores_web
💡 Dica
O parâmetro alpn h2,http/1.1 activa HTTP/2 no HAProxy. Os backends continuam a receber HTTP/1.1 (o HAProxy faz a conversão). Para renovar certificados Let’s Encrypt automaticamente, criar um hook no certbot que combina os ficheiros PEM e recarrega o HAProxy: systemctl reload haproxy.
5. Keepalived — Failover com VRRP
O Keepalived implementa o protocolo VRRP (Virtual Router Redundancy Protocol, RFC 5798) para gerir um endereço IP virtual (VIP) partilhado entre dois ou mais nós. O nó MASTER detém o VIP e responde a ARP. Os nós BACKUP monitorizam o MASTER através de anúncios VRRP multicast a cada 1 segundo. Se 3 anúncios consecutivos falham (3 segundos), o BACKUP com maior prioridade assume o VIP.
5.1 Topologia active-passive
# /etc/keepalived/keepalived.conf — NÓ lb1 (MASTER)
global_defs {
router_id LB1
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass MinhaSenhaVRRP2026
}
virtual_ipaddress {
192.168.1.100/24
}
# Track script: verificar se HAProxy está a correr
track_script {
check_haproxy
}
}
# Script de verificação do HAProxy
vrrp_script check_haproxy {
script "/etc/keepalived/check_haproxy.sh"
interval 2
fall 2
rise 2
}
# /etc/keepalived/keepalived.conf — NÓ lb2 (BACKUP)
global_defs {
router_id LB2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass MinhaSenhaVRRP2026
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
check_haproxy
}
}
vrrp_script check_haproxy {
script "/etc/keepalived/check_haproxy.sh"
interval 2
fall 2
rise 2
}
O script de verificação check_haproxy.sh confirma que o HAProxy está activo. Se o HAProxy cair mas o nó continuar online, o track_script reduz a prioridade do nó em 50 pontos, forçando o failover para o BACKUP:
#!/bin/bash
# /etc/keepalived/check_haproxy.sh
# Verifica se o HAProxy está a processar ligações
if pidof haproxy > /dev/null; then
exit 0
else
exit 1
fi
# Tornar executável:
# chmod +x /etc/keepalived/check_haproxy.sh
5.2 Topologia active-active
Em active-active, cada nó é MASTER de um VIP diferente e BACKUP do outro. O tráfego é distribuído entre os dois VIPs via DNS round-robin ou um registo DNS por geolocalização. Se um nó cair, o outro assume ambos os VIPs:
# lb1: MASTER do VIP 192.168.1.100, BACKUP do VIP 192.168.1.101
vrrp_instance VI_1 {
state MASTER
virtual_router_id 51
priority 150
virtual_ipaddress { 192.168.1.100/24 }
}
vrrp_instance VI_2 {
state BACKUP
virtual_router_id 52
priority 100
virtual_ipaddress { 192.168.1.101/24 }
}
# lb2: MASTER do VIP 192.168.1.101, BACKUP do VIP 192.168.1.100
vrrp_instance VI_1 {
state BACKUP
virtual_router_id 51
priority 100
virtual_ipaddress { 192.168.1.100/24 }
}
vrrp_instance VI_2 {
state MASTER
virtual_router_id 52
priority 150
virtual_ipaddress { 192.168.1.101/24 }
}
| Feature | Active-Passive | Active-Active |
|---|---|---|
| VIPs | 1 | 2 (um por nó) |
| Capacidade | 50% (1 nó idle) | 100% (ambos activos) |
| Complexidade | Baixa | Média (DNS round-robin) |
| Failover | Automático (<3s) | Automático (ambos VIPs) |
| Recomendado para | PME (simplicidade) | Alto tráfego |
6. Estatísticas e Monitorização
O HAProxy inclui um painel de estatísticas web integrado que mostra em tempo real o estado de cada backend, ligações activas, taxa de pedidos, erros e tempo de resposta. Para PME, este painel é frequentemente suficiente sem precisar de ferramentas externas.
6.1 Activar o painel de estatísticas
# Adicionar ao haproxy.cfg
listen stats
bind *:8404
mode http
stats enable
stats uri /stats
stats realm HAProxy\ Estatisticas
stats auth admin:SenhaForte2026
stats admin if TRUE
stats refresh 10
Aceder em http://192.168.1.100:8404/stats com as credenciais definidas. O stats admin if TRUE permite accionar drain/UP/DOWN nos backends directamente pelo painel.
6.2 Métricas por socket e Prometheus
# Activar socket de runtime em haproxy.cfg
global
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
# Comandos via socket (CLI)
echo "show info" | sudo socat /run/haproxy/admin.sock -
echo "show servers state" | sudo socat /run/haproxy/admin.sock -
echo "show sess" | sudo socat /run/haproxy/admin.sock -
# Para Prometheus, usar haproxy_exporter
# Exporta métricas no endpoint /metrics
# haproxy_exporter --haproxy.scrape-uri=unix:/run/haproxy/admin.sock
# Disponível em http://localhost:9101/metrics
| Métrica | Descrição | Valor saudável |
|---|---|---|
| scur (current sessions) | Ligações activas por servidor | Distribuído igualmente |
| econ (connection errors) | Erros de ligação ao backend | 0 |
| eresp (response errors) | Erros HTTP do backend | 0 |
| rtime (response time) | Latência média (ms) | < 200ms |
| qmax (max queue) | Máximo de pedidos em fila | 0 (sem gargalo) |
7. Erros Comuns e Lista de verificação
A maioria dos problemas com HAProxy e Keepalived resulta de configurações incorrectas, falta de verificação de sintaxe ou problemas de rede (firewall, ARP, multicast). Abaixo os erros mais frequentes e a lista de verificação final.
7.1 Erros frequentes
⚠ VIP não responde após failover
Causa: o firewall bloqueia o protocolo VRRP (protocolo 112). Solução: permitir VRRP em ambos os nós — sudo iptables -A INPUT -p vrrp -j ACCEPT ou sudo firewall-cmd --add-protocol=vrrp --permanent no firewalld.
⚠ Erro “Cannot bind socket” no arranque
Causa: outro processo já ocupa a porta (Nginx, Apache) ou o VIP ainda não foi atribuído pelo Keepalived. Solução: parar o processo conflituoso ou adicionar bind *:80 em vez de bind 192.168.1.100:80 para que o HAProxy escute em todas as interfaces.
⚠ Split-brain (ambos os nós como MASTER)
Causa: perda de conectividade entre os nós. Ambos se consideram MASTER e respondem por ARP, causando conflito. Solução: garantir que os nós estão na mesma VLAN/L2, usar garp_master_delay e configurar preempt_delay 5 para evitar flapping.
⚠ Backends marcados como DOWN sem razão aparente
Causa: o health check httpchk envia um Host header inválido. Solução: especificar o header Host correctamente: option httpchk GET /health HTTP/1.1\r\nHost:\ app.pt e confirmar que o endpoint /health responde 200.
7.2 Comandos de diagnóstico
# Verificar sintaxe do HAProxy antes de reiniciar
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
# Verificar estado do Keepalived e VRRP
sudo systemctl status keepalived
sudo journalctl -u keepalived -f
# Verificar qual nó tem o VIP
ip addr show eth0 | grep 192.168.1.100
# Verificar tabela ARP do cliente
arp -n | grep 192.168.1.100
# Capturar anúncios VRRP (protocolo 112)
sudo tcpdump -i eth0 -n vrrp
# Testar load balancing (deve ir rodando entre backends)
for i in $(seq 1 10); do curl -s -I http://192.168.1.100/ | head -1; done
# Verificar ligações activas no HAProxy
echo "show sess" | sudo socat /run/haproxy/admin.sock -
7.3 Lista de verificação de implantação
| Passo | Verificação | Comando |
|---|---|---|
| 1 | Sintaxe HAProxy válida | haproxy -c -f haproxy.cfg |
| 2 | Keepalived activo em ambos os nós | systemctl status keepalived |
| 3 | VIP atribuído ao MASTER | ip addr show eth0 |
| 4 | Firewall permite VRRP | iptables -L -n | grep vrrp |
| 5 | Health checks a funcionar | Painel stats: backends UP |
| 6 | Certificado SSL válido | openssl s_client -connect VIP:443 |
| 7 | Teste de failover manual | Parar HAProxy no MASTER e verificar VIP |
| 8 | Persistência de sessão | Cookie SERVERID presente no navegador |
✓ Resumo
HAProxy + Keepalived oferece alta disponibilidade profissional sem custos de licenciamento. Para uma PME com 2-3 servidores web, a topologia active-passive com um VIP e failover VRRP em 3 segundos é simples de implementar e robusta. As chaves do sucesso: health checks HTTP reais (não só TCP), track_script no Keepalived para detectar falhas do HAProxy, e firewall configurado para permitir o protocolo VRRP.
Artigos relacionados no kbase.pt