Important
Aquest article és obsolet i pot contenir informació desactualitzada. Si us plau, consulta la documentació més recent per obtenir informació actualitzada.
HAProxy és un programari que ens permet equilibrar la càrrega entre diversos servidors. Se sol utilitzar per equilibrar la càrrega de serveis web, però pot equilibrar la de qualsevol servei que funcioni amb el protocol TCP. En aquest article us mostrarem diverses configuracions d'HAProxy, inclosa la gestió de les galetes. Pot semblar una ximpleria, però pot provocar que el nostre web falli. Imagina que tens 2 servidors web, que d'ara endavant anomenarem frontals. Quan l'usuari arriba per primera vegada al teu web, ho fa al frontal-01. Quan l'usuari es registra, es crea una galeta. L'usuari continua navegant i, de sobte, HAProxy envia el trànsit al frontal-2. En aquest servidor no existeix la galeta i, per tant, se li tancarà la sessió :(. Si configurem HAProxy adequadament, això no passarà.
Instal·lació d'HAProxy
La configuració mínima per poder equilibrar la càrrega és de 3 servidors: HAProxy + 2 frontals web. L'avantatge d'utilitzar HAProxy és que en qualsevol moment pots afegir més frontals.
Un altre avantatge d'utilitzar HAProxy és que podem restringir l'accés als frontals a través de la IP pública, de manera que no siguin accessibles directament. Amb les ordres següents ja podem instal·lar HAProxy.
# apt update
# apt upgrade
# apt install haproxy
# mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.orgConfiguració bàsica
Ara ja podem crear el nostre primer fitxer de configuració executant: vi /etc/haproxy/haproxy.cfg
global
daemon
maxconn 256
user haproxy
group haproxy
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
log global
mode http
option tcplog
option dontlognull
maxconn 8000
timeout connect 5s
timeout client 300s
timeout server 300s
retries 3
timeout check 10s
timeout queue 1m
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
listen test_kb
bind *:80
mode http
stats enable
stats auth cda:cda
balance roundrobin
server frontend-01 10.20.10.54:80 #IP privada frontal-01
server frontend-02 10.20.10.56:80 #IP privada frontal-02Ara que ja tenim la configuració feta, hem de reiniciar el servei d'HAProxy. Ho farem cada vegada que canviem la configuració.
# systemctl restart haproxyConsultar les estadístiques
Per consultar les estadístiques via web, modificarem la configuració següent amb vi /etc/haproxy/haproxy.cfg:
listen stats
bind *:8083
mode http
stats enable
stats uri /stats
stats realm HAProxy\ Statistics
stats auth haproxy:TestKBAra anirem al navegador i obrirem el web http://IP_Publica_HAProxy:8083/stats. Ens demanarà un nom d'usuari i una contrasenya; hi indicarem haproxy i TestKB.
Si volem que la pàgina d'estadístiques s'actualitzi automàticament cada 10 minuts, podem afegir la directiva
stats refresh 10mComprovar l'estat i controlar les galetes
Podem fer que un usuari accedeixi sempre al mateix frontal. En el nostre exemple ens basarem en una variable de PHP, però podem utilitzar qualsevol variable.
Una altra característica important d'HAProxy és que pot comprovar si un frontal està caigut o sobrecarregat i desconnectar-lo temporalment. Editarem la configuració amb vi /etc/haproxy/haproxy.cfg
listen test_kb
bind *:80
mode http
stats enable
stats auth cda:cda
balance roundrobin
option httpchk GET /index.php HTTP/1.0
http-check expect rstatus (2|3)[0-9][0-9]|503
cookie PHPSESSID prefix indirect nocache
server frontend-01 10.20.10.54:80 check maxconn 4000 fall 3 cookie L1
server frontend-02 10.20.10.56:80 check maxconn 4000 fall 3 cookie L2Afegir un certificat SSL de Let's Encrypt per a HAProxy
Ara que tenim HAProxy en funcionament, és el moment adequat per fer unes modificacions perquè el nostre lloc web amb equilibri de càrrega estigui protegit amb un certificat. Alguns aspectes que cal tenir en compte són:
- HAProxy i Let's Encrypt no poden utilitzar els mateixos ports 80 i 443. Modificarem Let's Encrypt i la renovació automàtica perquè utilitzin un port diferent.
- HAProxy no pot llegir el certificat SSL en diversos fitxers tal com es generen automàticament. Modificarem el certificat SSL perquè HAProxy el pugui llegir.
- Crearem una regla de filtratge a HAProxy perquè les renovacions de Let's Encrypt funcionin i la resta de peticions s'enviïn al backend.
- Crearem un script per permetre la renovació automàtica del certificat i l'adaptarem per utilitzar-lo amb HAProxy.
Primer de tot instal·larem Let's Encrypt amb les ordres següents:
# add-apt-repository -y ppa:certbot/certbot
# apt-get update
# apt-get install -y certbotAra editarem el fitxer següent:
# vi /etc/haproxy/haproxy.cfgI el deixarem de la manera següent:
global
daemon
maxconn 256
user haproxy
group haproxy
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
log global
mode http
option tcplog
option dontlognull
maxconn 8000
timeout connect 5s
timeout client 300s
timeout server 300s
retries 3
timeout check 10s
timeout queue 1m
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
listen test_kb
bind *:80
bind *:443 ssl crt /etc/ssl/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host.pem
# Forcem HAProxy a redirigir a HTTPS
redirect scheme https code 301 if !{ ssl_fc }
# Indiquem que les peticions de Lets Encrypt vagin al bloc backend letsencrypt
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt if letsencrypt-acl
#Indiquem que la resta de peticions vagin al bloc servidoresBackend
default_backend servidoresBackend
#backend de lets encrypt
backend letsencrypt
server letsencrypt 127.0.0.1:8888
#backend per defecte
backend servidoresBackend
mode http
stats enable
stats auth cda:cda
balance roundrobin
option httpchk GET /index.php HTTP/1.0
http-check expect rstatus (2|3)[0-9][0-9]|503
cookie PHPSESSID prefix indirect nocache
server frontend-01 10.20.10.8:80 check maxconn 4000 fall 3 cookie L1
server frontend-02 10.20.10.9:80 check maxconn 4000 fall 3 cookie L2
#backend d'estadístiques d'HaProxy
listen stats
bind *:8083
mode http
stats enable
stats uri /stats
stats realm HAProxy\ Statistics
stats auth haproxy:TestKBEn aquest codi, l'identificador "edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host" s'ha de substituir pel nom de domini que s'utilitzi per al web, i les IP dels servidors s'han de substituir per les que tingueu configurades als vostres servidors.
El pas següent és generar el certificat SSL de Let's Encrypt per al nostre domini, que posteriorment configurarem a HAProxy. L'ordre que cal executar és:
# certbot certonly --standalone -d edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host --non-interactive --agree-tos --email soporte@clouding.io --http-01-port=8888Com podeu veure, utilitzem el port 8888 perquè no entri en conflicte amb HAProxy.
Ara hem de crear el directori i el fitxer on desarem el certificat SSL adaptat perquè HAProxy el pugui llegir. Per fer-ho, executarem:
# mkdir -p /etc/ssl/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host
# cat /etc/letsencrypt/live/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/fullchain.pem /etc/letsencrypt/live/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/privkey.pem | tee /etc/ssl/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host.pemAmb això ja tenim el certificat adaptat, que s'utilitza a la configuració anterior d'HAProxy en aquesta línia:
bind *:443 ssl crt /etc/ssl/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host.pemPerquè el certificat de Let's Encrypt es renovi automàticament, haurem de crear un petit script i afegir-lo al crontab perquè s'executi una vegada al mes:
# crontab -eI hi afegim la línia següent:
0 0 1 * * root bash /opt/renovar-certificados.shAra creem l'script:
# vi /opt/renovar-certificados.shi hi afegim el contingut següent:
#!/usr/bin/env bash
# Renovar el certificat
certbot renew --force-renewal --tls-sni-01-port=8888
# Adaptem el certificat per a haproxy
bash -c "cat /etc/letsencrypt/live/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/fullchain.pem /etc/letsencrypt/live/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/privkey.pem | tee /etc/ssl/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host.pem"
# Recarreguem haproxy
service haproxy reloadFinalment, hauríem de comprovar que Let's Encrypt serà capaç de renovar el certificat executant:
# certbot renew --tls-sni-01-port=8888