Simples Failover-Cluster mit Floating IP realisieren

18.09.2015 yahe administration legacy linux security

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 immer noch 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 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 die 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 Parameter "-U" 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):

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

Ich habe mir testweise ein PHP-Skript geschrieben, das 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. Wenn die IP-Adresse frei werden sollte, übernimmt das wartende PHP-Skript die IP-Adresse. Ein Screencapture des Tests habe ich bei Youtube hochgeladen. Der permanent laufende Ping rechts oben zeigt, dass trotz des Herunterfahrens des ersten Rechners die IP-Adresse weiterhin verwendbar bleibt. Im CURL-Aufruf rechts unten sieht man, dass die HTTP-Anfragen zwar über dieselbe IP-Adresse gestellt, jedoch von verschiedenen Servern beantwortet werden.

Mit dem gleichen Know-how kann man übrigens auch Angriffe auf Netzwerkdienste fahren, indem man die Pakete, die an den Dienst gerichtet sind, über den eigenen Rechner umleitet.


Search

Categories

administration (40)
arduino (12)
calcpw (2)
code (33)
hardware (16)
java (2)
legacy (113)
linux (27)
publicity (6)
review (2)
security (58)
thoughts (21)
windows (17)
wordpress (19)