Hochverfügbarkeit mit Keepalived

Wer schon einmal mit mehreren Servern gearbeitet hat, kennt das Problem: Ein Dienst soll zwecks Ausfallsicherheit auf mehreren Servern laufen und parallel unter einer festen IP erreichbar sein. Natürlich mit Failover.

An dieser Stelle kommt Keepalived ins Spiel. Das kleine, aber mächtige Tool übernimmt die Verwaltung von Floating IPs (oder Virtual IPs, kurz VIPs) und sorgt so für Hochverfügbarkeit für theoretisch beliebige Dienste.

Wie funktioniert das?

Keepalived setzt auf das VRRP-Protokoll (Virtual Router Redundancy Protocol), um eine virtuelle IP-Adresse an genau einen Master-Knoten zu vergeben.

Wenn der Master ausfällt, erkennt Keepalived das automatisch und weist die IP einem Backup-Knoten zu. Meistens passiert das innerhalb von wenigen Sekunden. Dienste hinter dieser IP bleiben dadurch durchgängig erreichbar.

Typische Szenarien

DNS

Ein Klassiker. DNS hat zwar an sich durch die Angabe mehrerer DNS-Server schon auf der Ebene Ausfallsicherheit integriert, hier lässt sich aber auch Keepalived gut einsetzen. Zwei (oder mehr) Server sind dabei identisch eingerichtet und können beide jederzeit DNS-Anfragen beantworten.

Keepalived sorgt hier nun für eine virtuelle IP, die immer auf einen der beiden Server gebunden ist und damit beim Ausfall des aktuell aktiven Servers innerhalb von kurzer Zeit auf den zweiten umgeschaltet wird.

Webserver

Eigentlich exakt das selbe Prinzip wie bei DNS, hier müssen nur die Website-Daten auch auf einem gemeinsamen Storage liegen oder anderweitig allen Nodes bekannt sein.

Keepalived und Docker Swarm

Hier wirds cool.

Swarm hat Mesh Routing. Das heißt, dass jede Node Anfragen zu einem Service entgegen nehmen kann und intern dann zum richtigen Knoten weiterleitet. Heißt, es ist egal, welche Node man anspricht, die Antwort kommt auf jeden Fall.

In Verbindung mit Keepalived kann man so Services in Docker Swarm wirklich hochverfügbar machen. Die virtuelle IP zeigt immer auf einen der Knoten, das interne Mesh-Routing erledigt dann den Rest. Wenn ein Knoten ausfällt, wird die IP umgeschaltet, parallel sorgt Swarm dafür, dass alle Services weiterhin verfügbar sind und bei Bedarf auf einem anderen Knoten neu gestartet werden.

DNS-Einträge können damit immer auf die virtuelle IP eingestellt werden, alles weitere passiert automatisch.

Beispielkonfiguration

Hier eine kurze Beispielconfig:

Node swarm-1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
global_defs {
        router_id swarm-1
}

vrrp_instance VI_SWARM {
    state MASTER
    interface eth0
    virtual_router_id 60
    priority 255
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass meinsicherespw
    }
    virtual_ipaddress {
        192.168.1.60/24
    }
}

Node swarm-2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
global_defs {
        router_id swarm-2
}

vrrp_instance VI_SWARM {
    state BACKUP
    interface eth0
    virtual_router_id 60
    priority 254
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass meinsicherespw
    }
    virtual_ipaddress {
        192.168.1.60/24
    }
}

Die router_id ist hierbei immer Node-spezifisch. Die virtual_router_id ist letztendlich die Instanzkennung. Bei mir ist swarm-1 normalerweise der Master, hier ist durch die höhere Priorität auch ein Fail-Back (also das Zurückschalten von einer der anderen Nodes zurück zu swarm-1) konfiguriert. Wenn die Prioritäten identisch sind, passiert kein Fail-Back.

Die restlichen Optionen sind weitestgehend selbsterklärend, ansonsten findet man im Internet auch genügend Informationen zu Keepalived.

Kubernetes

Bei Kubernetes lässt sich dieses Konstrukt mit MetalLB im Layer-2-Modus ziemlich identisch umsetzen. Die Erkennung von ausgefallenen Nodes läuft etwas anders, aber das Endergebnis (virtuelle IP, unter der immer eine Node erreichbar ist) ist das selbe.

Fazit

Mir gefällt das Setup in dieser Kombination wirklich gut. Swarm kümmert sich um die Services, Keepalived sorgt für eine einheitliche IP für alle Services. Und dabei braucht Keepalived auch fast nichts an Ressourcen.