Im ersten Teil dieses Blogs haben wir HAProxy auf einem Virtual Load Balancer-Knoten in der E2E Cloud eingerichtet. Wir haben HAProxy auch so konfiguriert, dass Anfragen mithilfe einer Round-Robin-Richtlinie an Back-End-Webserver weitergeleitet werden.
In diesem zweiten und abschließenden Teil dieses Blogs werden wir einige erweiterte Konfigurationseinstellungen durchgehen, die die meisten Websites erfordern:Sitzungsbindung und sicherer Zugriff auf die Website mit SSL. Aber bevor wir dies tun, werden wir zeigen, wie unsere einzelne HAProxy-Instanz dank ACLs eine große Website mit vielen Webanwendungen bedienen kann. Während wir dabei sind, werden wir einige zusätzliche Konfigurationsoptionen ansprechen, wie etwa die gewichtete Round-Robin-Richtlinie, und mit Hinweisen auf andere wichtige Überlegungen für eine Produktionsbereitstellung abschließen.
Load-Balancer-Setup für mehrere Webanwendungen
Viele große Websites bestehen aus mehreren Clustern von Webservern, wobei jeder Cluster eine andere Webanwendung hostet. Beispielsweise kann es eine Website mit Hauptinhalt zusammen mit einer Website für Spaß und Unterhaltung geben. HAProxy ist in der Lage, Anfragen basierend auf URL-Mustern und Zugriffskontrolllisten an den richtigen Cluster weiterzuleiten (ACLs).
Um diese Funktion zu veranschaulichen, erstellen wir zunächst zwei neue Webserver-Knoten in der E2E-Cloud mit den Namen „webserver3“ und „webserver4“. Wie üblich installieren wir Apache-Webserver und PHP-Pakete auf den beiden neuen Knoten. Dann implementieren wir eine zweite PHP-Anwendung unter der URL „/fun/films.php“ auf nur diese beiden neu hinzugefügten Knoten . (Die zweite Anwendung verwendet Sitzungspersistenz und ihre Funktionalität wird im nächsten Abschnitt erklärt.)
Also haben wir die folgenden Knoten (4 Webserver und einen Load Balancer) auf unserem Dashboard sichtbar:
Abbildung 1:Webserver für mehrere Webanwendungen
HAProxy muss also Client-Anfragen für die URL ‚/fun/films.php‘ nur an einen der Knoten ‚webserver3‘ und ‚webserver4‘ weiterleiten, sonst kann die Anfrage überhaupt nicht bedient werden. Um diese Anforderung zu erfüllen, ändern wir die HAProxy-Konfiguration (/etc/haproxy/haproxy.cfg) und erstellen ein weiteres Backend (mit dem Namen „Filme“), das nur aus den beiden neuen Webserver-Knoten besteht. Dies ist zusätzlich zu dem bestehenden Backend mit dem Namen „site“.
Abbildung 2:Backend-Konfiguration für eine neue Anwendung
Dann führen wir in der bestehenden Frontend-Konfiguration eine ACL wie unten gezeigt ein. Das bedeutet, dass jeder URL-Pfad, der mit „/fun“ beginnt, an das Backend namens „films“ geleitet wird, während alle anderen Anfragen standardmäßig auf dem (bereits vorhandenen) Backend namens „site“ landen (bestehend aus Nodes nur 'websrv1' und 'websrv2').
Abbildung 3:Frontend-Konfiguration mit ACL
Abbildung 4:HAProxy-Lastausgleich mit ACLs
Erweiterte Konfigurationseinstellungen
Gewichtete Round-Robin-Richtlinie :Beim Vornehmen von Änderungen für ACLs haben wir eine Gewichtung eingeführt zu jedem Server. In der Produktion können verschiedene Server unterschiedliche Rechenleistung haben, sodass HAProxy durch die Verwendung von Gewichtungen mehr Anfragen an leistungsfähigere Server weiterleiten kann. (In unserem Fall sind alle Webserver-Knoten ähnlich und alle Gewichtungen gleich, aber wir können dies als Vorlage verwenden und in einem anderen Szenario anpassen.)
Max. Verbindungen pro Server :Zweitens haben wir auch den ‚maxconn‘-Parameter auf Backend-Server-Ebene verwendet , sodass jeder Server die Anzahl der Verbindungen auf das für seine Rechenleistung angemessene Maß beschränken kann. Das globale „maxconn“ sollte größer sein als die Gesamtsumme der Werte dieses Parameters auf Serverebene (wodurch etwas Platz für das Hinzufügen weiterer Webserver-Knoten für die Skalierbarkeit bleibt).
Session-Stickiness
Die neue PHP-Anwendung verwendet zufälligerweise PHP-Sitzungen. Jedes Mal, wenn ein Client auf diese Anwendung zugreift, liefert er den Namen eines Lieblingsfilms (über einen HTTP-GET-Parameter namens „fav“), der der PHP-Sitzung hinzugefügt wird. Der Server antwortet mit der bisher gesammelten Liste der Lieblingsfilme (einzigartig für jeden Client).
- session_start();
- $fav =$_GET[‘fav’];
- if ( isset( $_SESSION[‘favoriten’] ) ) {
- $_SESSION[‘Favoriten’] .=‘ , ‘;
- $_SESSION[‘Favoriten’] .=$fav;
- } sonst {
- $_SESSION[‘favorites’] =$fav;
- }
- $msg =‚Meine Lieblingsfilme:‘. $_SESSION[‘Favoriten’];
- ?>
-
Meine Lieblingsfilme - echo $msg;
- ?>
PHP-Sitzungen können lokal für eine Webserverinstanz sein (es sei denn, Sitzungspersistenz oder -replikation sind aktiviert). Wenn also derselbe Client zufällig zu unterschiedlichen Zeiten an verschiedene Backend-Webserver-Instanzen weitergeleitet wird, wenn er eine Reihe von Anfragen stellt, können seine Sitzungsdaten unvorhersehbar werden. Aber ein Client kann gezwungen werden, „zu bleiben“ ‘ zu einer einzelnen Webserver-Instanz innerhalb der Dauer einer Sitzung.
Eine Möglichkeit, dies in HAProxy einzurichten, besteht darin, den Parameter ‚appsession‘ in der entsprechenden Backend-Konfiguration (in unserem Fall ‚films‘ ) einzuführen. Verschiedene Arten von Anwendungen verwenden unterschiedliche HTTP-Cookies für die Sitzungsverwaltung. Bei PHP-Anwendungen heißt dieses Cookie „PHPSESSID“. Durch die Einstellung von „appsession“ ordnet HAProxy jedem einen einzelnen Webserver zu „PHPSESSID“ (diejenige, in der diese Sitzung erstellt wurde) und leitet wiederholte Client-Anfragen mit derselben Sitzungs-ID an denselben Webserver weiter, solange er läuft oder die Sitzung abgelaufen ist .
- appsession PHPSESSID len 32 timeout 1h
Wenn dieser Webserver aus irgendeinem Grund nicht verfügbar ist, sollte es HAProxy natürlich freistehen, Anfragen mit derselben Sitzungs-ID an eine andere aktive Serverinstanz weiterzuleiten. Dies kann durch Hinzufügen der Option „redispatch“ im Abschnitt „defaults“ der HAProxy-Konfigurationsdatei sichergestellt werden.
- Option Redispatch
Testen
Jetzt können wir sowohl ACLs als auch Session Stickiness testen. Wir können die HAProxy-Protokolle auf dem Load-Balancer-Knoten verfolgen:
- tail -f /var/log/haproxy.log
Wir verfolgen auch die Webserver-Zugriffsprotokolle auf jedem der Knoten ‚webserver3‘ und ‚webserver4‘.
1. tail -f /var/log/apache2/access.log
Von zwei verschiedenen Client-Rechnern senden wir Anfragen von einem Browser an die folgende URL:http://
In jeder Anfrage können wir einen anderen Wert für den Abfrageparameter mit dem Namen „fav“ festlegen.
Vom ersten Client senden wir die folgenden aufeinanderfolgenden Anfragen:
- http://
/fun/films.php?fav=avengers - http://
/fun/films.php?fav=jurassicworld
Das Browserfenster auf dem ersten Client zeigt Folgendes an:
Abbildung 5:Eine Clientsitzung
Vom zweiten Client senden wir die folgenden aufeinanderfolgenden Anfragen:
- http://
/fun/films.php?fav=race3 - http://
/fun/films.php?fav=gold
Das Browserfenster im zweiten Client zeigt Folgendes an:
Abbildung 6:Eine weitere Clientsitzung
Aus der in jedem Client-Browser angezeigten Antwort geht hervor, dass die Sitzungen in jedem Fall korrekt aufrechterhalten werden. In Firefox können wir von der Webkonsole aus auch die PHPSESSID-Werte überprüfen.
Wir können die folgenden zwei Beobachtungen aus den HAProxy- und Webserver-Protokollen machen:
- Diese Anfragen mit dem URL-Muster „/fun“ werden nur an das Backend namens „films“ weitergeleitet (ACL-Richtlinien)
- Eine Anfrage von derselben Client-IP-Adresse landet auf demselben Webserver-Knoten (Session Stickiness)
Abbildung 7:HAProxy-Protokolle mit Sticky Sessions
Abbildung 8:Zugriffsprotokolle auf dem Webserver3-Knoten mit dauerhaften Sitzungen
Abbildung 9:Zugriffsprotokolle auf dem Webserver4-Knoten mit dauerhaften Sitzungen
Sicherheit:SSL-Terminierung
Eine letzte, aber entscheidende Konfiguration, die wir gerne übernehmen, bezieht sich auf die Sicherheit. Apache-Webserver können so konfiguriert werden, dass sie HTTPS unterstützen, aber wenn wir HAProxy am Frontend installiert haben, landen Client-Anfragen zuerst beim Load Balancer.
Es wird daher empfohlen, dass wir HAProxy so konfigurieren, dass es HTTPS unterstützt. Dies ist ein vierstufiger Prozess:
- Besorgen Sie sich ein SSL-Zertifikat für unsere Website. Zu Versuchszwecken haben wir mit openssl ein selbstsigniertes Zertifikat namens haproxy.pem erstellt
- Binde das Frontend an einen HTTPS-Port (standardmäßig 443) und weise diesem Frontend das SSL-Zertifikat zu
- Aktivieren Sie HAProxy, um über HTTP gesendete Client-Anfragen an den HTTPS-Port umzuleiten
- Erforderliche Header zur HTTP-Anforderung bei jedem hinzufügen oder festlegen der konfigurierten Backends
Die ersten drei Schritte oben werden auf Frontend-Ebene implementiert. (Wir haben unser Frontend in „alltraffic“ statt „httptraffic“ umbenannt.)
Abbildung 10:Frontend-Konfiguration für SSL
Der obige vierte Schritt wird bei jedem implementiert Backend:
Abbildung 11:Backend-Konfiguration für SSL
Normalerweise helfen die Header X-Forward-Port und X-Forward-Proto der Anwendung, die URL korrekt zu erstellen, wenn sowohl HTTP- als auch HTTPS-Anfragen möglich sind.
Das Beenden von SSL am Load-Balancer-Knoten verursacht einen gewissen Verarbeitungsaufwand an diesem Knoten (im Vergleich zum Weiterleiten der verschlüsselten Anfrage an die Backends). Es gibt einen Parameter, der sich auf den verwendeten zugrunde liegenden Verschlüsselungsalgorithmus bezieht. Ein höherer Wert erhöht den Verarbeitungsaufwand auf dem HAProxy-Knoten. Es kann im Abschnitt „global“ der HAProxy-Konfiguration eingestellt werden:
- tune.ssl.default-dh-param 2048
Also enden die SSL-verschlüsselten Anfragen beim Load-Balancer, der unverschlüsselte HTTP-Anfragen an die Backend-Webserver weiterleitet.
Abbildung 12:SSL-Terminierung
Firewall-Einstellungen
Wir müssen den Port 443 auf dem virtuellen Load Balancer-Knoten (der auf CentOS läuft) öffnen, indem wir den folgenden Befehl ausführen:
- iptables -A INPUT -i eth0 -p tcp –dport 443 -m state –state NEW,ESTABLISHED -j ACCEPT
- systemctl startet iptables neu
Testen
Wir versuchen jetzt, über einen Browser (Firefox) auf unsere PHP-Greeter-Anwendung zuzugreifen, indem wir auf das unsichere HTTP verweisen URL:
http://
Selbst dann fordert uns Firefox auf, eine Sicherheitsausnahme hinzuzufügen, die anzeigt, dass der Client an die sichere HTTPS-URL weitergeleitet wird . Dies wird auch in der Adressleiste des Browsers selbst angezeigt.
Abbildung 13:Zugriff auf die Webanwendung über SSL
Maschinen-Images erstellen und überwachen
Tipp :Es wurde viel Aufwand in die Konfiguration der Virtual Load Balancer-Instanz investiert. Ein Maschinen-Image dieses Knotens kann gespeichert werden, damit später ähnliche Load-Balancer-Instanzen erstellt werden können, die es als Vorlage verwenden. Auf E2E Cloud kann dies erreicht werden, indem zuerst der HAProxy-Knoten heruntergefahren und dann ein Bild dieses Knotens aus dem Dashboard gespeichert wird.
Abbildung 14:Speichern des HAProxy-Maschinenabbilds
Abbildung 15:Maschinen-Image vom HAProxy-Knoten erstellen
Optional könnte auch ein Maschinenabbild von Webserverinstanzen gespeichert werden.
Überwachung mit Zabbix :Der HAProxy-Knoten kann wie jeder andere virtuelle Knoten in der E2E-Cloud mit Zabbix überwacht werden. Wir sollten diese Möglichkeit nutzen.
Abbildung 16:Zustand des Load Balancers überwachen
Schlussfolgerung und nächste Schritte
E2E Cloud bietet Virtual Load Balancer-Knoten zum Einrichten des Lastausgleichs mit HAProxy. In diesen beiden Blogs haben wir uns angesehen, wie eine HAProxy-Installation in E2E Cloud konfiguriert werden kann, um Round-Robin-Load-Balancing für einfache und große Websites mit mehreren Anwendungen mit Session-Stickiness und sicherem Zugriff über HTTPS zu unterstützen.
Wir werden diesen Blog beenden, indem wir einige andere Überlegungen für eine Produktionsbereitstellung zur Kenntnis nehmen:
- Zunächst sollte der Virtual Load Balancer-Knoten (und optional die Webserver-Knoten) mit geeigneten DNS-Einstellungen an eine Domäne gebunden werden
- Entsprechend sollte das SSL-Zertifikat für den sicheren Zugriff auf die HAProxy-Instanz an dieselbe Domain gebunden sein
- Schließlich sollte der Load Balancer nicht zu einem Single Point of Failure werden. Daher kann eine aktiv-passive Bereitstellung von HAProxy empfohlen werden.