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/.