Keepalived

Keepalived setzt das Virtual Router Redundancy Protocol (VRRP) um und bringt damit einen schlanken HA-Failover-Mechanismus auf Layer 3. Zusätzlich kann es Linux IP Virtual Server (IPVS) für Layer-4-Load-Balancing konfigurieren. Im typischen Linuxfabrik-Einsatz wird Keepalived vor einem HAProxy-Cluster betrieben, um die Frontend-VIP zwischen den HAProxy-Nodes wandern zu lassen.

VRRP unterstützt Versionen 2 und 3. Dieser Artikel behandelt VRRP v2, weil die LFOps-Rolle keepalived darauf aufsetzt und v2 in RHEL-Umgebungen der Standard ist.

Begriffe
  • Floating IP / VIP: die IP-Adresse, die zwischen den HA-Knoten wandert. Immer nur ein Knoten hält sie zur gleichen Zeit (der Master).

  • Gratuitous ARP: Beim Übernehmen der VIP schickt der neue Master unaufgefordert ein ARP-Paket ins LAN, damit Switches ihre MAC-Adress-Tabellen aktualisieren und der Layer-2-Traffic sofort zum neuen Master läuft.

  • IP Protocol 112 (VRRP): VRRP ist weder TCP noch UDP, sondern eine eigene IP-Protokollnummer. Wichtig bei Firewall-Regeln.

  • Preemption: Kommt ein ausgefallener höher-priorisierter Master zurück, zieht er die VIP wieder an sich. Per Default aktiviert; per nopreempt deaktivierbar.

  • Priority: ein Integer zwischen 1 und 254 (plus der Sonderwert 255 für den „Owner“ der VIP). Die höchste Priority gewinnt die Master-Wahl.

  • VRID (Virtual Router ID): eindeutige ID einer VRRP-Gruppe pro Netzwerksegment. Muss bei Master und Backup identisch sein.

  • VRRP Advertisement: Multicast-Paket, das der Master periodisch versendet (per Default 1x pro Sekunde). Backup-Knoten nehmen ein fehlendes Advertisement als Master-Ausfall wahr.

Grundlagen

Die Master-Wahl läuft simpel:

  1. Alle Knoten in derselben VRID-Gruppe lesen die priority-Direktive ihrer eigenen Config.

  2. Der Knoten mit der höchsten Priority sendet als erstes ein Advertisement und wird Master.

  3. Die anderen Knoten gehen in den Backup-Modus.

  4. Der Master versendet pro advert_int (default: 1 Sekunde) ein Advertisement.

  5. Fehlen drei Advertisements in Folge, wählen die Backups einen neuen Master.

Ein VRRP-Advertisement enthält:

  • Virtual Router ID (Gruppen-ID)

  • Priority des Absenders

  • Auth Type und Authentication String (bei auth_type PASS ein 8-Zeichen-Passwort)

  • Advertisement Interval

  • IP Address(es) der VIPs, die der Master hält

Die Zieladresse des Advertisements ist per Default die Multicast-IP 224.0.0.18 (IP-Protokoll 112). In Netzwerken, die Multicast nicht zuverlässig routen, wird er auf dem lokalen Segment wie Broadcast-Traffic behandelt.

Warnung

auth_type PASS übermittelt das Passwort in Klartext im VRRP-Paket und schützt nur gegen Konfigurationsfehler, nicht gegen aktive Angreifer im selben Broadcast-Segment. Für echten Schutz das VRRP-Segment von nicht-vertrauenswürdigen Hosts fernhalten. Nur die ersten 8 Zeichen des Passworts werden überhaupt verwendet.

Installation und Basis-Konfiguration

Keepalived liegt in den Standard-Repos.

dnf --assumeyes install keepalived
keepalived --version

VRRP muss auf der Host-Firewall freigegeben werden. Mit firewalld:

firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept'
firewall-cmd --reload

Damit ein Service (z.B. HAProxy) auf einer VIP lauschen darf, die aktuell nicht auf dem Interface konfiguriert ist, muss ip_nonlocal_bind aktiviert werden:

/etc/sysctl.d/99-keepalived.conf
net.ipv4.ip_nonlocal_bind = 1
sysctl --load /etc/sysctl.d/99-keepalived.conf

Grundkonfiguration für zwei Knoten, die sich eine VIP 192.0.2.26/24 teilen. Master und Backup authentifizieren sich gegenseitig per Passwort:

/etc/keepalived/keepalived.conf (Master, server01)
global_defs {
    notification_email {
        root@example.com
    }
    notification_email_from noreply@server01.example.com
    smtp_server localhost
    smtp_connect_timeout 30
}

vrrp_instance VI_1 {
    state MASTER
    interface ens160
    virtual_router_id 51
    priority 255
    advert_int 1
    smtp_alert
    authentication {
        auth_type PASS
        auth_pass linuxfabrik
    }
    virtual_ipaddress {
        192.0.2.26/24
    }
}
/etc/keepalived/keepalived.conf (Backup, server02)
global_defs {
    notification_email {
        root@example.com
    }
    notification_email_from noreply@server02.example.com
    smtp_server localhost
    smtp_connect_timeout 30
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens160
    virtual_router_id 51
    priority 200
    advert_int 1
    smtp_alert
    authentication {
        auth_type PASS
        auth_pass linuxfabrik
    }
    virtual_ipaddress {
        192.0.2.26/24
    }
}

Direktiven im Überblick:

state

MASTER oder BACKUP. Reine Dokumentations-Information - den tatsächlichen Master bestimmt die priority.

interface

Das Interface, auf dem VRRP-Advertisements gesendet und die VIP konfiguriert wird.

virtual_router_id

Muss auf allen Knoten derselben VRRP-Gruppe identisch sein.

priority

Höchste Priority gewinnt. Konvention: 255 für den Master, 200 für den Backup. Der Abstand gibt Spielraum für Tracking-basierte Anpassungen.

advert_int

Sekundenabstand zwischen Advertisements. 1 ist sinnvoll.

smtp_alert

Sendet bei jedem Zustandswechsel eine Mail an die Adressen in notification_email.

virtual_ipaddress

Die VIPs, die der Master übernimmt. Mehrere Adressen pro Instanz sind erlaubt.

Auf beiden Knoten starten:

systemctl enable --now keepalived

Die VIP erscheint auf dem Master-Interface. Kontrolle:

ip --brief address show ens160

Tracking

Ohne weitere Konfiguration führt nur der komplette Netzwerk-Ausfall eines Knotens zu einem Failover. Das ist in der Regel zu grob: ein Service kann abstürzen, obwohl der Host selbst noch antwortet. Keepalived bringt vier Tracking-Mechanismen mit, die die effektive priority eines Knotens zur Laufzeit anpassen.

Prinzip: ein positiver weight-Wert wird auf die Priority aufaddiert, solange der Tracking-Check positiv ist. Fällt er, wird der Wert abgezogen - und der Knoten verliert gegen einen Backup, dessen Tracking noch intakt ist.

track_process

Failover, wenn ein bestimmter Prozess (z.B. httpd) auf dem Master nicht mehr läuft:

/etc/keepalived/keepalived.conf
vrrp_track_process track_httpd {
    process httpd
    weight 10
}

vrrp_instance VI_1 {
    state MASTER
    interface ens160
    virtual_router_id 51
    priority 244
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass linuxfabrik
    }
    virtual_ipaddress {
        192.0.2.26/24
    }
    track_process {
        track_httpd
    }
}

Solange httpd läuft, meldet der Master Priority 244 + 10 = 254. Fällt httpd, sinkt sie auf 244 - und der Backup mit priority 250 übernimmt.

track_file

Für Applikationen, die ihren Gesundheitszustand in eine Datei schreiben:

/etc/keepalived/keepalived.conf
vrrp_track_file track_app_file {
    file /opt/my_app/health
}

vrrp_instance VI_1 {
    ...
    track_file {
        track_app_file weight 1
    }
}

Keepalived liest den Datei-Inhalt als Ganzzahl. Der Wert wird mit weight multipliziert und zur Priority addiert. Enthält die Datei z.B. 5, wird die Priority um 5 * 1 = 5 angehoben.

track_interface

Typisches Beispiel: ein Load Balancer hat ein Frontend- und ein Backend-Interface. Fällt das Backend-Interface aus, soll die VIP wandern:

/etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    ...
    track_interface {
        ens192 weight 5
    }
}

Solange ens192 UP ist, wird die Priority um 5 angehoben.

track_script

Ein externes Health-Check-Skript, das bei Erfolg 0 und sonst einen Fehlercode zurückliefert:

/etc/keepalived/keepalived.conf
vrrp_script keepalived_check {
    script "/usr/local/bin/keepalived_check.sh"
    interval 1
    timeout 5
    rise 3
    fall 3
}

vrrp_instance VI_1 {
    ...
    track_script {
        keepalived_check
    }
}

Direktiven im vrrp_script:

  • interval: Wie oft das Skript läuft, in Sekunden.

  • timeout: Maximale Laufzeit des Skripts.

  • rise: Anzahl erfolgreicher Läufe, bis der Check als „healthy“ gilt.

  • fall: Anzahl fehlgeschlagener Läufe, bis der Check als „unhealthy“ gilt.

Notifications

Neben smtp_alert (Mail an notification_email bei jedem Zustandswechsel) bringt Keepalived notify_*-Hooks mit, die bei Zustandswechseln ein Skript aufrufen. Damit lässt sich z.B. ein abhängiger Dienst beim Wechsel in den Master-Zustand neu starten.

/etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    ...
    notify_master "/usr/local/bin/keepalived_notify.sh master"
    notify_backup "/usr/local/bin/keepalived_notify.sh backup"
    notify_fault  "/usr/local/bin/keepalived_notify.sh fault"
    notify_stop   "/usr/local/bin/keepalived_notify.sh stop"
    # gesamte Zustandsmatrix in einem Skript:
    notify        "/usr/local/bin/keepalived_notify.sh"
}

Das generische notify-Skript erhält vier Argumente:

  • $1: Instance-Typ (INSTANCE oder GROUP)

  • $2: Name der Instanz, z.B. VI_1

  • $3: neuer Zustand (MASTER, BACKUP, FAULT, STOP)

  • $4: aktuelle Priority

Beispiel-Skript, das den Übergang nach Syslog schreibt und HAProxy neu startet, sobald wir Master werden:

/usr/local/bin/keepalived_notify.sh
#!/usr/bin/env bash
set -euo pipefail

logger --tag keepalived "$1 $2 transitioned to $3 (priority $4)"

if [[ "$3" == "MASTER" ]]; then
    systemctl reload haproxy || true
fi

Cheat Sheet

systemctl status keepalived
systemctl restart keepalived

# configuration check (as of Keepalived 2.x)
keepalived --config-test

# current VRRP state (on the master you will see the VIP attached)
ip --brief address show

# observe VRRP traffic
tcpdump --interface any proto 112

# follow the log
journalctl --unit keepalived --follow

Troubleshooting

Beide Knoten halten die VIP gleichzeitig („Split Brain“)

Die VRRP-Advertisements kommen bei den Knoten nicht an. Typische Ursachen: Host-Firewall blockiert IP-Protokoll 112, ein Switch filtert Multicast, oder die Knoten stehen in unterschiedlichen VLANs. Prüfen mit tcpdump --interface any proto 112 auf beiden Seiten.

Ein Knoten meldet FAULT state

Entweder ist das in interface konfigurierte Interface ausgefallen, oder ein Tracking-Check (Prozess/Datei/Interface/Skript) ist dauerhaft fehlgeschlagen. Ursache in journalctl --unit keepalived nachlesen.

Zwei VRRP-Gruppen im selben Segment stören sich

Jede VRRP-Gruppe braucht eine eindeutige virtual_router_id pro Netzwerksegment. Gleiche IDs in verschiedenen Gruppen führen dazu, dass Knoten fremde Advertisements als eigene lesen und Fehlzustände auslösen.

VIP wandert nicht zurück nach Reparatur des Masters

nopreempt ist aktiv, oder der Backup hat durch Tracking eine höhere effektive Priority als der reparierte Master. systemctl restart keepalived auf dem Backup erzwingt ein Neu-Election.

auth_pass scheinbar falsch, obwohl das Passwort stimmt

Nur die ersten 8 Zeichen werden verwendet. Längere Passwörter werden still abgeschnitten - Master und Backup müssen in den ersten 8 Zeichen übereinstimmen.

Keepalived aus Quellen bauen

Falls eine neuere Version als die der Distribution benötigt wird:

dnf --assumeyes install gcc make openssl-devel

VER=2.3.1
wget https://www.keepalived.org/software/keepalived-${VER}.tar.gz
tar --extract --file keepalived-${VER}.tar.gz

cd keepalived-${VER}
./configure
make
make install

keepalived --version

Danach die mitgelieferte systemd-Unit (keepalived.service) installieren bzw. anpassen. Für Produktiv-Systeme ist das Distributionspaket vorzuziehen - das eigene Kompilieren bringt Update-Schmerzen mit sich.