In einer high-availability Umgebung (HA) sind nicht nur die loadbalncer redundant, sondern auch die dahinter liegenden Backend-Server.
Das Szenario ist, dass es zwei Loadbalancer (lb01 und lb02) gibt. Diese haben je eine eigene IP-Adresse und „teilen“ sich eine dritte virtuelle IP-Adresse (VIP), welche in einem failover-Fall mittels keepalived von einem System auf das andere System transferiert wird.
Im backend gibt es zwei gleiche Webserver (web01 und web02). HAProxy verteilt die requests auf einen der beiden Webserver, sofern beide verfügbar sind.
Es kann also sowohl einer der Loadbalancer, wie auch einer der Webserver ausfallen.
Inhalt
Installation
[stextbox id=“note“ caption=“Firewall Einstellungen“]
Wenn man ein host firewall hat, müssen noch bestimmte Regeln hinzugefügt werden um den VRRP (keepalived) Traffic zu erlauben. Im Minum ist das Protokoll vrrp (Port 112) traffic.
Nachfolgende einige iptables Regeln um auch multicast traffic zu erlauben:
-A INPUT -i eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT -A INPUT -i eth0 -d 224.0.0.0/8 -p 51 -j ACCEPT -A INPUT -i eth0 -s 192.168.10.0/30 -j ACCEPT -A OUTPUT -o eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT -A OUTPUT -o eth0 -d 224.0.0.0/8 -p 51 -j ACCEPT -A OUTPUT -o eth0 -s 192.168.10.0/30 -j ACCEPT |
Das Netzwerk „192.168.10.0/30“ sollte dabei mit dem ersetzt werden, was auf den keepalived nodes (nicht die VIPs) verwendet wird.
[/stextbox]
Die IP Adressen sehen wie folgt aus:
Loadbalancer:
- lb01: IP: 192.168.10.1
- lb01: IP: 192.168.10.2
- VIP: 192.168.10.3
Webserver:
(Auf den Webservern läuft eine Applikation, welche die Ports 8080 (HTTP) und 8443 (HTTPS) benutzen. Bei „normalen“ Webservern wäre es hier 80 (HTTP) und 443 (HTTPS)
- web01: IP: 192.168.80.1 (HTTP-Port: 8080 )
- web02: IP: 192.168.80.2 (HTTPS-Port: 8443)
Zunächst werden die benötigten Komponenten auf den beiden loadbalancern lb1 und lb2 installiert:
yum install keepalived haproxy
systemctl enable keepalived
systemctl enable haproxy
Nun müssen noch die Kernel-Parameter net.ipv4.ip_forward (IP-Forwarding einschalten) und net.ipv4.ip_nonlocal_bind gesetzt werden.
net.ipv4.ip_nonlocal_bind ermöglicht es, dass Programme sich an eine IP „binden“ können, welche es auf dem System (noch) gar nicht gibt.
sysctl -w net.ipv4.ip_forward="1"
sysctl -w net.ipv4.ip_nonlocal_bind="1"
Nun wird auf dem ersten loadbalancer (lb01) keepalived Konfiguriert:
/etc/keepalived/keepalived.conf
global_defs {
router_id lb01
}
vrrp_script check_haproxy {
script "/usr/bin/killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance web-prod {
state MASTER
interface eth0
virtual_router_id 1
priority 100
virtual_ipaddress {
192.168.10.3
}
track_script {
check_haproxy
}
}
Und auf dem zweiten loadbalancer (lb02)
/etc/keepalived/keepalived.conf
global_defs {
router_id lb02
}
vrrp_script check_haproxy {
script "/usr/bin/killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance web-prod {
state BACKUP
interface eth0
virtual_router_id 1
priority 99
virtual_ipaddress {
192.168.10.3
}
track_script {
check_haproxy
}
}
Der Unterschied ist im zweiten steht der STATE auf BACKUP und die priority auf 99; der Rest beleibt gleich.
Mittels den check_haproxy Script wird geprüft ob der HAProxy läuft und falls nicht ein failover initiert.
[stextbox id=“tip“ caption=“Tipp check script“]
Um zu schauen ob ein Prozess noch läuft kann auf systemd Systemen anstelle vom simplen:
/usr/bin/killall -0 haproxy |
auch das intelligentere:
systemctl is-active --quiet haproxy |
verwendet werden. Es gibt 0 zurück, wenn der daemon/service läuft und eine höhere Zahl, wenn der daemon/service nicht läuft.
[/stextbox]
Nun wird die HAProxy Konfiguration gemacht, welche auf beiden loadbalancern (lb01 und lb02) gleich ist:
global
log 127.0.0.1 local1
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode http
log global
option httplog
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
listen stats
bind :9000
mode http
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /haproxy_stats
# stats auth Username:Password
frontend web-prod-http
bind 192.168.10.3:80
default_backend web-prod-http
backend web-prod-http
balance roundrobin
server web01 192.168.80.1:8080 check
server web02 192.168.80.2:8080 check
frontend web-prod-https
bind 192.168.10.3:443
default_backend web-prod-https
backend web-prod-https
balance roundrobin
server web01 192.168.80.1:8443 check
server web02 192.168.80.2:8443 check
Hier gehört immer eine Frontend-Definiton zur gleichnamigen Backend-Definition.
Das frontend bindet sich auf die VIP und das backend beinhaltet alle (gleichen) Server, welche im round-robin Verfahren loadbalanced werden.
Im obigen Szenario passiert folgendes:
- Benutzer ruft die virtuelle IP auf: http://192.168.10.3/
; diese befindet sich je nachdem auf lb01 oder lb02.
- Der zuständige Loadbalancer transferieret den request abwechslungsweise (round-robin) auf: 192.168.80.1:8080 und 192.168.80.2:8080
Quellen
- haproxy community edition Configuration Manual
- haproxy.com: Configuration Manual (von der bezahlten „Enterprise“ Version, welche von der freien „Community“ Version leicht abweichen kann)
- haproxy.com: The Four Essential Sections of an HAProxy Configuration
- haproxy.com: Performing Health Checks
- RedHat: Load Balancer Administration Guide
- RedHat: Keepalived and high availability: Advanced topics
- tobru.ch: Keepalived Check and Notify Scripts
- e-mc2.net: Keepalived – A documentation nightmare
- certdepot.net: Configure a high available load-balancer
- digitalocean.com: How To Use HAProxy As A Layer 4 Load Balancer for WordPress Application Servers
- gridscale.io: Loadbalancing mit HAProxy
- Redundant Firewalls with High-Availability & Load-Balancing
Transparent proxying
- Transparent Proxying and Binding with HAProxy Load Balancer
- High availability haproxy (transparent mode) service with keepalived (https://www.devconsole.info/high-availability-haproxy-transparent-mode-service-keepalived-centos-6-6/)
- HAProxy TCP Transparent Mode Remote Servers (https://serverfault.com/questions/788726/haproxy-tcp-transparent-mode-remote-servers)
Hi Steven
Da fehlen noch zwei (je nach Setup) wesentliche Zeilen 😉
firewall-cmd –add-rich-rule=’rule protocol value=“vrrp“ accept‘ –permanent
firewall-cmd –reload
Gruss
Thomas
Hallo,
Port 80443, echt jetzt?
Grüße
Danke für den Hinweis, ich habe diese (offensichtlich falsche) notation korrigiert.