Simples Failover-Cluster mit Floating IP realisieren

Immer wieder kommt es vor, dass der Wunsch aufkommt, die Verfügbarkeit eines internen Dienstes zu erhöhen. Mitunter ist das das allererste Mal, dass die Beteiligten sich überhaupt mit dem Thema Clustering auseinandersetzen müssen. Leider herrscht immernoch die Meinung vor, dass Clustering ein komplexes Thema sei, das man am besten weit nach hinten schiebt - dabei wird es umso einfacher, je früher man sich darum Gedanken macht. Denn dann kann man seine Anwendungen von vorne herein darauf vorbereiten, in einem Cluster lauffähig zu sein.

An dieser Stelle würde ich gern einmal eine simple Lösung zeigen, wie es möglich ist, ohne Einsatz eines Loadbalancers ein einfaches Failover-Cluster mit einer Floating IP (auch als virtuelle IP bezeichnet) zu realisieren.

In einer einfachen Form gibt es zwei Maschinen im Netzwerk, die die gleiche Aufgabe erfüllen und sich eine gemeinsame IP-Adresse teilen. Wenn eine der beiden Maschine startet, prüft sie, ob die gemeinsame IP-Adresse bereits verwendet wird. Ist das nicht der Fall, dann nimmt sie sich die IP-Adresse. Startet nun die zweite Maschine, so bekommt diese mit, dass die IP-Adresse bereits verwendet wird und schaltet sich in einen Wartezustand. In diesem prüft sie regelmäßig, ob die IP-Adresse noch verwendet wird. Sobald das nicht mehr der Fall ist, übernimmt sie die IP-Adresse und nutzt sie selbst.

Dieses Vorgehen kann man noch entsprechend gegen fälschliche IP-Adressübernahmen absichern: Beispielsweise sollte man mehr als nur einmal prüfen, ob die IP-Adresse noch verwendet wird, bevor man sie übernimmt. Ebenso kann man sich Protokolle überlegen, damit mehr als nur zwei Knoten im Failover-Cluster existieren können (z.B. durch die Einführung einer Knotengewichtung oder durch dynamische Reihenfolgen). Durch den Einsatz von STONITH-Mechanismen kann man zudem dafür sorgen, dass Clusterknoten mit einer Fehlfunktion das Cluster nicht stören, indem man sie zur Not gewaltsam aus dem Cluster entfernt. Aber für unser simples Beispiel geht es auch erstmal ohne.

Um einen einfachen, für den Client transparenten, Failover hinzukriegen, brauchen wir unter Linux im Grunde zwei Tools: "ip" und "arping". Das ip-Tool ist standardmäßig vorhanden und wird dazu verwendet, die Floating IP an ein Netzwerkinterface zu binden (z.B. "eth0"). Das arping-Tool muss man hingegen erst installieren. Dabei ist Vorsicht geboten, denn es gibt zwei verschiedene Implementierungen, wobei uns nur die aus den iputils der Linux Foundation interessiert - denn nur diese kennt den "-U" Parameter für Unsolicited ARP Requests (auch "Gratuitous ARP Messages" oder "ARP Announcements" genannt). Sinn und Zweck dieser ARP Requests ist es, den angeschlossenen Systemen mitzuteilen, dass IP-Pakete, die an die Floating IP gerichtet werden, nun an ein anderes Gerät zu routen sind.

Die folgenden beiden Befehle sind unter Linux ausreichend, um eine IP-Adresse zu übernehmen (wobei ihr "<IP>" durch die Floating IP und "<Interface>" durch den Namen des Netzwerkinterfaces ersetzen müsst):

1
2
  sudo /bin/ip addr add <IP>/32 dev <Interface>
  sudo /usr/bin/arping -U -c 5 -q -I <Interface> <IP>

Im unten stehenden Video habe ich einmal aufgenommen, wie das PHP-Script in der Datei "~/failover.phs" die oben beschriebene Funktionalität ausführt. Beim ersten Starten prüft es, ob die Floating IP ("192.168.123.10") in Verwendung ist und übernimmt diese. Der zweite Aufruf bekommt mit, dass die Floating IP in Verwendung ist und versetzt sich in den Wartemodus. Der permanent laufende Ping rechts oben zeigt, dass trotz des Herunterfahrens des ersten Rechners die IP-Adresse weiterhin verwendbar bleibt. In den CURL-Aufruf rechts unten sieht man, dass die HTTP-Anfragen zwar über dieselbe IP-Adresse gestellt, jedoch von verschiedenen Servern beantwortet werden.

Ausfallsichere Grüße, Kenny

P.S.: Ja, mit dem gleichen Knowhow kann man auch Angriffe auf Netzwerkdienste fahren, indem man die Pakete, die an den Dienst gerichtet sind, über den eigenen Rechner umleitet.

Schreibe einen Kommentar

Um Ihnen beim weiteren Kommentieren auf dieser Webseite die erneute Eingabe Ihrer Daten zu ersparen, wird beim Absenden Ihres Kommentars ein Cookie an Ihren Browser gesendet und von diesem gespeichert. Mit dem Absenden eines Kommentars auf dieser Webseite stimmen Sie der Speicherung und Übertragung dieses Cookies explizit zu.

Pflichtfelder sind mit * markiert.