Forgot your password?

Forgot your username?

All about IT, Web and Development.
By users for users.

Layer 4 Load Balancing mit IPVS und Debian / Ubuntu



IPVS (=IP Virtual Server) implementiert eine Lastverteilung auf Layer 4 in Kernel Ebene. Hierdurch ist das System im Vergleich zu Layer 7 Loadbalancern auch auf schwächeren Systemen sehr performant.



Sowohl die offizielle Dokumentation als auch diverse Anleitungen im Internet sind größtenteils extrem lückenhaft und gnadenlos veraltet.


Architektur


Zur Veranschaulichung soll das nachfolgende Diagramm der zu Grunde liegenden Infrastruktur dienen.



Betriebsmodi


IPVS bietet verschiedene Methoden zum Versenden- und Empfangen der Pakete an.
Hier möchte ich auf die drei gängigen Methoden näher eingehen.

Network Address Translation (NAT)


Am Loadbalancer eingehende Pakete werden durch Abänderung der Zieladresse an den Backend Server weitergeleitet. Dieser Beantwortet die Anfrage und sendet diese an den Loadbalancer zurück, welcher das Paket an den Client weiterleitet.

Hier liegt auch schon der häufigste Fehler in den Dokumentationen. Ohne weitere Änderungen an den Systemeinstellungen und IPTables NATting laufen die Pakete vom Backend Server direkt an den Client, da IPVS nicht die Quelladresse verändert. Dieser verwirft die Pakete, da sie von einer unbekannten Quelladresse (Backend Server) kommen.

Die NAT Methode eignet sich (richtig eingerichtet) besonders für Fälle in denen keine Änderungen an den Backend Servern bzw. der dahinterliegenden Infrastruktur vorgenommen werden können/dürfen.


IP Tunneling (IP-IP)


Im IP-IP Betrieb sendet IPVS die Requests an die Backend Server über einen IP Tunnel. Diese antworten dann direkt an den anfragenden Client.


Beim Direct Routing werden die Pakete vom Loadbalancer direkt an die Backend Server weitergeleitet. Die Pakete werden dabei nicht durch NAT angepasst.

Hierdurch müssen die Backend Server so konfiguriert werden, dass sie den Traffic der virtuellen IP Adresse des Loadbalancers entgegen nehmen können. Die Antworten werden auch hier wieder direkt vom Backend Server an den Client gesendet.


Installation


Die Installationspakete sind in den meisten Distributionen bereits enthalten. Zur besseren Verwaltung und Konfiguration installieren wir zusätzlich Ldirectord.

apt-get install ldirectord ipvsadm


Konfiguration


Im Folgenden richten wir eine NAT Konfiguration ein. Somit sind keine Änderungen an den Backend Servern notwendig.

nano /etc/ldirectord.cf
checktimeout=10
checkinterval=2
autoreload=no
logfile="/var/log/ldirectord.log"
quiescent=yes

virtual=192.168.1.120:80
   real=192.168.1.11:80 masq
   real=192.168.1.12:80 masq
   real=192.168.1.13:80 masq
   fallback=127.0.0.1:80 masq
   scheduler=rr
   protocol=tcp
   checktype=ping


Hier eine kurze Erklärung der verwendeten Konfigurationsparameter.


  • checktimeout - Zeit in Sekunden bis ein Server als Down deklariert wird

  • checkinterval - Rhythmus der Prüfung

  • autoreload - Neuladen des Dienstes bei Änderungen in der Konfigurationsdatei

  • logfile - Pfad zur Logdatei

  • quiescent - Bei yes werden beim Entfernen eines Backend Servers dessen offene Verbindungen noch weitergeführt, keine neuen Verbindungen mehr


Im nachfolgenden Abschnitt setzen wir die eigentliche Konfiguration von Front- und Backend.
Über den virtual Parameter wird die Frontend Adresse des Loadbalancers definiert. Darunter befindet sich die Auflistung der Backend Server. Über das nachfolgende masq wird der NAT Modus festgelegt.

Die fallback Definition dient im Falle eines Totalausfalls der Backend Server.


Scheduler


Der Parameter scheduler legt die Art der Lastverteilung fest. Hier die gängigsten Parameter. Weitere können der Manpage von ipvsadm entnommen werden.


  • rr - Round Robin

  • wrr - Weighted Round Robin

  • lc - Least Connection

  • wlc - Weighted Least-Connection

  • sh - Source Hashing


Protocol


Über protocol wird das Protokoll des Dienstes festgelegt (TCP oder UDP).


Checktype


Hierdurch wird festgelegt wie die Erreichbarkeit der Backend Server festgestellt werden soll. In diesem Beispiel wählen wir ping aus.


Systemeinstellungen


Wie bereits oben erwähnt sind noch einige Anpassungen an den Systemeinstellungen und dem NATing notwendig.


Um die Weiterleitung der Pakete zu ermöglichen muss das IP Forwarding aktiviert werden. Zur Manipulation der Pakete für NAT muss das Connection Tracking für IPVS aktiviert werden. Andernfalls lassen sich die Pakete mit IPTables nicht abfangen.

echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/ipvs.conf
echo "net.ipv4.vs.conntrack=1" >> /etc/sysctl.d/ipvs.conf



IPTables


Damit die Backend Server die Antworten an den Loadbalancer versenden muss die Quelladresse der Pakete in die des Loadbalancers geändert werden. Dies kann auf zwei Wege umgesetzt werden.

Per Masquerading (empfohlen)

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Per SNAT Regel

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.1.120

Hierdurch wird bei allen Paketen, welche die Schnittstelle eth0 verlassen die Quelladresse angepasst.

Die Schnittstelle eth0 muss dabei durch die Schnittstelle ersetzt werden, welche mit den Backend Servern verbunden ist. Sie kann aber auch ganz weggelassen werden, wodurch die Regel auf allen Interfaces greift (Vorsicht!).


Test


Zum Test der gesamten Konfiguration können wir das Cluster mit Apache Benchmark testen:

ab -n 1000 -c 20 http://192.168.1.120:80/


Hochverfügbarkeit / Redundanz



Dies kann beispielsweise mit einem Keepalived Cluster umgesetzt werden.


Fazit


Die zu IPVS bzw. Ldirectord zu findende Dokumentation ist meist total veraltet und grausig. Besonders im Bereich NAT finden sich nur unzählige Diskussionen ohne Ergebnisse. Viele Einstellungen musste ich mühsam mit Wireshark / tcpdump zusammen kratzen und testen.


Michael Kostka

Fachinformatiker / Systemintegration
Ich schreibe hier regelmäßig zu den Themen Android, Web, Linux und Hardware.

Raspberry Pi Starter Kit
DataCloud

Leave a comment

I have read the privacy policy and agree to electronically store and process my input data to answer the request.