TL;DR — Kurzzusammenfassung
Vollständige HAProxy-Anleitung für TCP- und HTTP-Load-Balancing mit Hochverfügbarkeit. ACLs, Health Checks, SSL, Stick Tables und Keepalived-VRRP-Failover.
HAProxy ist die Referenzimplementierung für Open-Source-Load-Balancing. Während Nginx auch als Webserver dient und Caddy die Benutzerfreundlichkeit priorisiert, wurde HAProxy speziell für Proxying und Load-Balancing entwickelt — und das zeigt sich in jedem Benchmark. Dieser Leitfaden behandelt den vollständigen HAProxy-Stack: Architektur, Installation auf Ubuntu und RHEL, Feinabstimmung von global und defaults, Frontend/Backend-Konfiguration mit ACLs, alle Balancing-Algorithmen, TCP- und HTTP-Health Checks, SSL/TLS-Terminierung, die Statistikseite, Stick Tables, Rate Limiting, rsyslog-Integration und eine vollständige keepalived-VRRP-Konfiguration für Hochverfügbarkeit mit zwei Knoten.
Voraussetzungen
Stelle sicher, dass du folgendes hast:
- Ubuntu 22.04/24.04 oder RHEL 9/AlmaLinux 9 mit sudo-Zugriff
- Mindestens zwei Backend-Anwendungsserver
- Zwei HAProxy-Knoten (für den Hochverfügbarkeitsabschnitt mit keepalived)
- Grundkenntnisse in TCP/IP und HTTP
- HAProxy 2.6 oder neuer (LTS-Version empfohlen)
HAProxy-Architektur
HAProxy läuft als einzelner ereignisgesteuerter Prozess (oder eine konfigurierbare Anzahl von Prozessen/Threads). Alle E/A-Operationen sind nicht-blockierend und gemultiplext, sodass HAProxy Zehntausende gleichzeitiger Verbindungen mit minimalem RAM verarbeiten kann.
Eine Konfigurationsdatei hat vier Hauptsektionstypen:
- global — prozessweite Einstellungen (maxconn, log, chroot, user/group, nbthread)
- defaults — Standardeinstellungen, die von allen Frontends und Backends geerbt werden
- frontend — hört auf eingehende Verbindungen; wendet ACLs an und leitet Datenverkehr zu Backends weiter
- backend — definiert den Server-Pool, Balancing-Algorithmus und Health-Check-Parameter
- listen — kombiniertes Frontend+Backend, nützlich für die Statistikseite oder einfache TCP-Proxies
Der Datenverkehrsfluss ist: Client → Frontend → ACL-Auswertung → use_backend-Regel → Backend → Server.
Installation
Ubuntu / Debian
sudo apt update
sudo apt install haproxy -y
haproxy -v
Für eine neuere LTS-Version das offizielle PPA hinzufügen:
sudo add-apt-repository ppa:vbernat/haproxy-2.8 -y
sudo apt install haproxy=2.8.\* -y
RHEL / AlmaLinux / Rocky Linux
sudo dnf install haproxy -y
haproxy -v
sudo systemctl enable --now haproxy
Global- und Defaults-Konfiguration
Öffne /etc/haproxy/haproxy.cfg und ersetze den Standardinhalt durch eine produktionsreife Basis:
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
maxconn 50000
nbthread 4
tune.ssl.default-dh-param 2048
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
retries 3
timeout connect 5s
timeout client 30s
timeout server 30s
timeout http-keep-alive 10s
timeout check 5s
maxconn 3000
Wichtige Parameter erklärt:
maxconn 50000— globales Verbindungslimit; je nach verfügbarem RAM anpassen (~1 MB pro 1000 Verbindungen)nbthread 4— vier Threads auf einem Quad-Core-System ausführenoption dontlognull— Logs für Health Checks ohne Payload unterdrückenoption forwardfor—X-Forwarded-For-Header in Proxy-Anfragen einfügenretries 3— Wiederholungsversuche bei fehlgeschlagenen Verbindungen, bevor ein Server als ausgefallen markiert wirdtimeout connect 5s— maximale Zeit für eine TCP-Verbindung zu einem Backend
Frontend-Konfiguration
Ein Frontend definiert, worauf HAProxy hört und wohin es den Datenverkehr weiterleitet:
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
http-request redirect scheme https unless { ssl_fc }
http-request set-header X-Forwarded-Proto https if { ssl_fc }
# ACL-Definitionen
acl is_api path_beg /api/
acl is_static path_beg /static/ /assets/ /images/
acl host_admin hdr(host) -i admin.example.com
# Routing-Regeln
use_backend api_backend if is_api
use_backend static_backend if is_static
use_backend admin_backend if host_admin
default_backend app_backend
Häufig verwendete ACL-Matcher:
| Matcher | Beispiel | Prüft |
|---|---|---|
path_beg | path_beg /api/ | URI beginnt mit /api/ |
path_end | path_end .php | URI endet auf .php |
hdr(host) | hdr(host) -i api.example.com | Host-Header (Groß-/Kleinschreibung ignoriert) |
src | src 10.0.0.0/8 | Client-IP-Bereich |
method | method POST | HTTP-Methode |
Backend-Konfiguration
Ein Backend definiert den Server-Pool und die Verteilung des Datenverkehrs:
backend app_backend
balance roundrobin
option httpchk GET /health HTTP/1.1\r\nHost:\ app.example.com
server app1 10.0.0.10:8080 weight 3 maxconn 500 check inter 2s fall 3 rise 2
server app2 10.0.0.11:8080 weight 3 maxconn 500 check inter 2s fall 3 rise 2
server app3 10.0.0.12:8080 weight 1 maxconn 200 check inter 2s fall 3 rise 2
server app_backup 10.0.0.20:8080 backup check inter 5s fall 2 rise 1
Balancing-Algorithmen
| Algorithmus | Direktive | Geeignet für |
|---|---|---|
| Round-Robin | balance roundrobin | Kurze, gleichmäßige Anfragen |
| Gewichtetes RR | balance roundrobin + weight N | Server mit unterschiedlicher Kapazität |
| Wenigste Verbindungen | balance leastconn | Variable Antwortzeiten |
| Quell-IP-Hash | balance source | Session-Affinität nach Client-IP |
| URI-Hash | balance uri | Cache-Server |
| Header-Hash | balance hdr(User-Agent) | Routing nach HTTP-Header |
Health Checks
TCP-Health-Check (Standard)
HAProxy öffnet eine TCP-Verbindung, um zu prüfen, ob der Port aktiv ist:
backend tcp_backend
balance leastconn
server db1 10.0.0.30:5432 check inter 3s fall 2 rise 1
server db2 10.0.0.31:5432 check inter 3s fall 2 rise 1
HTTP-Health-Check
Für HTTP-Backends die Anwendung auf einen gesunden Statuscode überprüfen:
backend app_backend
option httpchk GET /health HTTP/1.1\r\nHost:\ app.example.com
http-check expect status 200
server app1 10.0.0.10:8080 check inter 2s fall 3 rise 2
server app2 10.0.0.11:8080 check inter 2s fall 3 rise 2
SSL/TLS-Terminierung
HAProxy terminiert SSL im Frontend und leitet unverschlüsseltes TCP oder HTTP an die Backends weiter. Zertifikat und privaten Schlüssel in eine PEM-Datei kombinieren:
cat fullchain.pem privkey.pem > /etc/haproxy/certs/example.com.pem
chmod 600 /etc/haproxy/certs/example.com.pem
Multi-Zertifikat-SNI (ein Verzeichnis, HAProxy wählt automatisch das richtige Zertifikat):
frontend https_front
bind *:443 ssl crt /etc/haproxy/certs/
http-request set-header X-Forwarded-Proto https
http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
default_backend app_backend
Statistikseite
Die integrierte HAProxy-Statistikseite bietet Echtzeit-Verbindungsmetriken:
listen stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:changeme
stats show-legends
stats show-node
stats hide-version
Zugriff unter http://dein-server:8404/stats. Den Port mit einer Firewall-Regel schützen:
sudo ufw allow from 10.0.0.0/8 to any port 8404
sudo ufw deny 8404
Stick Tables für Session-Persistenz
Stick Tables verfolgen Client→Server-Zuordnungen im gemeinsamen Speicher:
backend app_backend
balance roundrobin
stick-table type ip size 100k expire 30m
stick on src
server app1 10.0.0.10:8080 check
server app2 10.0.0.11:8080 check
Für Cookie-basierte Persistenz:
backend app_backend
balance roundrobin
cookie SERVERID insert indirect nocache
server app1 10.0.0.10:8080 cookie app1 check
server app2 10.0.0.11:8080 cookie app2 check
Rate Limiting mit Stick Tables
HAProxys Stick Tables verwalten auch Rate Limiting ohne externe Abhängigkeiten:
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/
stick-table type ip size 200k expire 10s store http_req_rate(10s)
http-request track-sc0 src
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
default_backend app_backend
Protokollierung mit rsyslog
HAProxy protokolliert über einen Syslog-Socket. Konfiguriere rsyslog, um HAProxy-Logs in eine dedizierte Datei zu schreiben.
Erstelle /etc/rsyslog.d/49-haproxy.conf:
$AddUnixListenSocket /dev/log
:programname, startswith, "haproxy" {
/var/log/haproxy.log
stop
}
sudo systemctl restart rsyslog
sudo systemctl restart haproxy
HAProxy mit Keepalived für VRRP-Failover
keepalived führt VRRP aus, um eine virtuelle IP zwischen zwei HAProxy-Knoten zu teilen. Wenn der primäre Knoten ausfällt, übernimmt der Standby-Knoten die virtuelle IP innerhalb von einer bis zwei Sekunden.
Keepalived installieren
sudo apt install keepalived -y # Ubuntu
sudo dnf install keepalived -y # RHEL
Primärer Knoten — /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass s3cur3p4ss
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
chk_haproxy
}
}
Standby-Knoten — /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass s3cur3p4ss
}
virtual_ipaddress {
192.168.1.100/24
}
}
sudo systemctl enable --now keepalived
ip addr show eth0 | grep 192.168.1.100
Load-Balancer-Vergleich
| Funktion | HAProxy | Nginx | Traefik | Envoy | AWS ALB |
|---|---|---|---|---|---|
| TCP-Load-Balancing | Ja (nativ) | Ja | Ja | Ja | Ja |
| Aktive Health Checks | Ja (integriert) | Nur Plus | Ja | Ja | Ja |
| Statistik-Oberfläche | Integriert | stub_status | Dashboard | Admin API | CloudWatch |
| Rate Limiting | Stick Tables | limit_req | Middleware | Filters | WAF |
| SSL-Terminierung | Ja | Ja | Ja | Ja | Ja |
| HA/VRRP | Via keepalived | Via keepalived | Nicht integriert | Nicht integriert | Verwaltet |
| Ressourcenbedarf | Sehr gering | Gering | Mittel | Hoch | Verwaltet |
| Am besten geeignet | TCP+HTTP HA | Web + Cache | Container | Service Mesh | AWS-nativ |
Zusammenfassung
HAProxy ist der Goldstandard für TCP- und HTTP-Load-Balancing in Linux-Umgebungen. Wichtigste Erkenntnisse:
- Passe
maxconn,nbthreadund Timeouts in denglobal- unddefaults-Sektionen zuerst an - Erstelle ACLs im Frontend mit
path_beg,hdr()undsrc; leite zu Backends mituse_backendweiter - Wähle
leastconnfür HTTP-APIs,roundrobinfür gleichmäßigen Datenverkehr, undsourceoder Stick Tables für Session-Persistenz - Füge immer
check inter 2s fall 3 rise 2zu jeder Serverzeile undoption httpchkzu HTTP-Backends hinzu - Terminiere SSL im Frontend mit einer kombinierten PEM-Datei; mehrere Zertifikate in einem Verzeichnis für automatisches SNI
- Verwende Stick Tables für Session-Persistenz und Rate Limiting ohne externe Abhängigkeiten
- Kombiniere HAProxy mit keepalived VRRP für Failover in unter einer Sekunde zwischen zwei Knoten