Einen VRRP Cluster mit keepalived unter Linux einzurichten ist einfacher, wie man denkt, wenn man nur die Grundfunktionen (z.B. eine “hochverfügbare” IP-Adresse) braucht.
Das Beispiel ist ein Cluster unter Debian, das auf zwei LXC Containern unter Proxmox VE läuft. Die Container sind auf unterschiedliche Nodes des Proxmox Clusters verteilt. Die Funktion, die der Cluster bereit stellt, ist ein Haproxy Loadbalancer, der auf der Cluster-VIP läuft.
Installation
Die Installation ist schnell passiert:
sudo apt update && sudo apt install keepalived
Schon fertig.
Konfiguration
Die Konfigurationsdatei /etc/keepalived/keepalived.conf muss vor der ersten Verwendung angepasst werden. Dieses Beispiel unten ist die denkbar einfachste Konfiguration, mit der lediglich eine virtuelle IP-Adresse bereit gestellt wird, auf der dann ein entsprechender Dienst “lauschen” kann. Das kann theoretisch jede beliebige Anwendung sein, die über TCP/IP kommuniziert.
global_defs {
router_id proxy
script_user root
enable_script_security
}
vrrp_instance proxy {
state MASTER
interface eth0
virtual_router_id 42
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass abc123
}
virtual_ipaddress {
192.168.12.14
}
notify /etc/keepalived/notify.sh
}
Die Konfiguration ist auf beiden Cluster-Knoten identisch, bis auf die Einträge “state” (einer MASTER, der andere BACKUP) und “priority”. Letztere sollte sich auf jeden Fall unterscheiden, erstere kann, aber muss nicht. Mit state ist hier eigentlich “initial state” gemeint, also der Status, den die Cluster-Software annimmt, nachdem sie gestartet ist.
Mit der priority ist das so: Maximum ist 255, die höhere gewinnt (wird MASTER). Die unter virtual_ipaddress konfigurierte Adresse ist die Cluster-VIP, die jeweils immer nur auf dem Knoten aktiv ist, der gerade den MASTER-Status innehat.
Weitere Konfiguration-Optionen siehe Dokumentation.
Ein Wort zur Sicherheit
Angriffe auf VRRP sind zwar nicht trivial aber machbar, daher sollte man in einer produktiven Umgebung zum Beispiel keine Passwort-Authentisierung verwenden und eventuell noch weitere Sicherheitsmaßnahmen zur Absicherung des Systems (lokale Firewall, separates Netz für VRRP-Traffic etc.) ergreifen.
Status-Wechsel
Bei einem Status-Wechsel (wechsel zwischen MASTER/BACKUP Status) führt der keepalived-Daemon das mit der Option notify konfigurierte Skript aus. Im Beispiel-Skript wird der Haproxy-Dienst auf dem Master gestartet und auf dem Backup gestoppt.
#!/bin/bash
ENDSTATE=$3
NAME=$2
TYPE=$1
case $ENDSTATE in
"BACKUP") # Perform action for transition to BACKUP state
systemctl stop haproxy
echo $3 > /var/run/keepalived.state
exit 0
;;
"FAULT") # Perform action for transition to FAULT state
echo $3 > /var/run/keepalived.state
exit 0
;;
"MASTER") # Perform action for transition to MASTER state
systemctl start haproxy
echo $3 > /var/run/keepalived.state
exit 0
;;
*) echo "Unknown state ${ENDSTATE} for VRRP ${TYPE} ${NAME}"
echo $3 > /var/run/keepalived.state
exit 1
;;
esac
Zusätzlich schreibt das Skript noch den Status in eine Datei. Warum, sehen wir im Abschnitt “Monitoring”.
Cluster-Status abfragen
Den Status des Clusters (und ein paar statistische Werte) kann man abfragen, indem man einen
dem Prozess mit kill -USR1
ein Signal schickt, dass ihn dazu veranlasst, diese Daten
nach /tmp/keepalived.data zu schreiben. Dort steht auch der aktuelle Cluster-Status drin,
den man mit dem folgenden Skript auslesen und ausgeben kann.
#!/bin/bash
#
# check vrrp cluster state
# djonz nov 2018
# remove old data file if any
if [ -f /tmp/keepalived.data ]; then
rm /tmp/keepalived.data
fi
# tell keepalived to dump data and wait a bit
kill -USR1 $(cat /var/run/keepalived.pid)
sleep 1
# cluster state output
if [ -f /tmp/keepalived.data ]; then
STATE=`cat /tmp/keepalived.data | grep -A 5 'VRRP Topology' | grep State | awk '{print $3}'`
echo "$STATE"
else
echo "Unable to determine cluster state!"
fi
Monitoring
Der Cluster-Status lässt sich zum Beispiel per SNMP monitoren. Dafür muss man allerdings auf dem Cluster noch einen SNMP Daemon laufen lassen, was nicht jeder möchte.
Mit CheckMK lässt sich das aber mit einem simplen lokalen Check erledigen. Dafür dient die
echo $3 > /var/run/keepalived.state
Zeile im Notify-Skript.
#!/bin/bash
STATE=`cat /var/run/keepalived.state`
CODE="0"
case $STATE in
"MASTER")
CODE="0"
STRING="Master"
;;
"BACKUP")
CODE="1"
STRING="Backup"
;;
*)
CODE="2"
STRING="Kaputt!"
;;
esac
echo "$CODE \"VRRP State\" - $STRING"
Dazu muss der CheckMK Agent installiert sein. Das Skript kommt dann in das Verzeichnis /usr/lib/check_mk_agent/local/.