HAProxy-Tutorial: Installation unter Debian/Linux

HAProxy Tutorial – Installation und Konfiguration

In diesem HAProxy Tutorial führe ich dich durch die Installation und Konfiguration von HAProxy unter Debian/Linux und binde zwei Webserver als Backend-Systeme ein.

Wenn du noch nicht so viele Erfahrungen mit Loadbalancern hast und dich für ein paar Grundlagen interessierst, scroll doch mal kurz durch meinen Artikel Loadbalancing mit HAProxy.

In diesem Setup gehe ich dann Stück für Stück durch unterschiedliche Konfigurationen und Loadbalancer Modes durch.

Vorbereitung

Als erstes installiere dir drei neue Server bei deinem Cloud Hosting Provider. In diesem Artikel nutze ich natürlich Cloud Server auf unserer Plattform 🙂 aber du kannst die Installation und Konfiguration auch auf jeden anderen Hosting Provider anwenden.

Bei gridscale kannst du dir interne Layer-2 Netzwerke konfigurieren und deine Cloud Server intern vernetzen. Diese Funktion nutze ich in dieser Anleitung. Sollte dein Cloud Hosting Provider dir keine internen Netzwerke zur Verfügung stellen, arbeite einfach mit den öffentlichen IP-Adressen deiner neuen Server.

Auf meinen Servern habe ich ein frisches Debian 8 installiert. Du kannst aber natürlich auch eine beliebige andere Distribution, zum Beispiel CentOS, verwenden.

Installation HAProxy

Als erstes bereite deinen Cloud Server mit HAProxy vor. Unter Debian nutzt du dafür einfach apt-get um die benötigten Pakete zu installieren. Ich installiere noch ein paar zusätzliche Sachen wie ‚vim‘ oder ‚wget‘, du kannst darauf natürlich auch verzichten.

root@haproxy:~# apt-get -y install wget vim haproxy

Konfiguriere nun noch das interne Netzwerk auf dem HAProxy Server. Dazu einfach die Datei /etc/network/interfaces editieren und folgendes einfügen:

auto eth1
     iface eth1 inet static
     address 10.0.0.1
     netmask 255.255.255.0
     broadcast 10.0.0.255

Anschließend das Netzwerk neustarten und kontrollieren, ob das Interface eth1 konfiguriert ist.

root@haproxy:~# /etc/init.d/networking restart
[ ok ] Restarting networking (via systemctl): networking.service.
root@haproxy:~# ifconfig 
eth0      Link encap:Ethernet  HWaddr 1e:db:db:8b:c1:01  
...

eth1      Link encap:Ethernet  HWaddr 1e:db:db:8b:c1:02  
          inet addr:10.0.0.1  Bcast:10.0.0.255  Mask:255.255.255.0
...

root@haproxy:~#

Jetzt konfiguriere ein paar Bindings auf deinem HAProxy, damit wir pro Binding nachher einen Service mit unterschiedlichen Konfigurationsoptionen versehen können.

Du findest alle Konfigurationsdateien in ‚/etc/haproxy‘. Öffne als erstes die Datei ‚haproxy.cfg‘ und verschaffe dir einen kurzen Überblick.

Du kannst sowohl die global als auch die defaults Sektion erst einmal überspringen. Leg dir am Ende der Datei ein paar Listener an und erstelle die zugehörigen Backend Services.

frontend port_80
 bind *:80
 mode http
 default_backend port_80

frontend port_81
 bind *:81
 mode tcp
 default_backend port_81

backend port_80
 mode http
 balance roundrobin
 option httpchk HEAD / HTTP/1.0
 server web1 10.0.0.2:80 check
 server web2 10.0.0.3:80 check

backend port_81
 mode tcp
 balance roundrobin
 option httpchk HEAD / HTTP/1.0
 server web1 10.0.0.2:80 check
 server web2 10.0.0.3:80 check

Mit der Konfiguration hast du erst einmal einen funktionierenden HAProxy. Jetzt schnell die Webserver noch konfigurieren.

Installation deiner Webserver

Alle nachfolgenden Befehle führe einfach auf beiden Webservern aus, damit die Installationen gleich sind. Zunächst installiere dir ein paar Pakete. Es dürften alle möglichen Abhängigkeiten aufgelöst werden, am Ende steht dir dann ein Webserver mit PHP5 zur Verfügung. PHP5 möchte ich später dafür nutzen, um auf dem Webserver ein paar Daten auszugeben.

$ apt-get -y install vim wget libapache2-mod-php5

Nun editiere noch die Datei ‚/etc/network/interfaces‘ auf deinen Servern und fahre das Netzwerk Interface eth1 mit einer internen IP hoch. Für web1 habe ich 10.0.0.2 und für web2 habe ich 10.0.0.3 genommen. Die Konfigurationsdatei und das Kommando zum Neustarten der Netzwerkinterfaces kannst du von deinem HAProxy Server abgucken.

Bist du bereit zu starten?

Oder hast du noch Fragen? Erstelle dir jetzt dein kostenloses Konto oder lass dich in einem persönlichen Gespräch beraten.

Übersicht deiner aktuellen Installation

Wenn alles funktioniert hat, dann sollte deine Installation nun wie folgt aussehen.

Ob dein HAProxy funktioniert kannst du ganz einfach testen. Rufe in deinem Webbrowser einfach die IP-Adresse deines HAProxy Servers auf. Du solltest eine Standard-Webseite vom Apache2 erhalten.

Wenn das klappt, versuche das selbe mit Port 81. Auch hier sollte jetzt der Webserver seine Standardseite präsentieren.

Lass uns einen kurzen Blick auf die Konfiguration werfen, warum das so ist. Zunächst haben wir auf Port 80 einen Listener erstellt. Alle Anfragen die HAProxy auf Port 80 entgegen nimmt, werden auf die Backend-Server weitergeleitet, die unter der Gruppe „port_80“ zusammengefasst sind. Port 80 verfügt über ein sogenanntes Layer-7 Loadbalancing (zu erkennen an dem mode http). Für Port 80 ist noch keine Sticky Session konfiguriert, sprich deine Anfragen werden zwischen den Webservern verteilt.

Für Port 81 (Layer-4 Loadbalancing) verhält sich es ähnlich. Der Port 81 ist ohne eine Sticky Session konfiguriert. Das heißt, deine Anfragen werden auch über Port 81 zwischen web1 und web2 verteilt.

Gut, dann teste mal noch ein wenig mehr. Lege auf deinen Webservern im Verzeichnis ‚/var/www/html‘ eine Text-Datei an. Nenne sie einfach test.txt und schreibe jeweils den Hostnamen hinein. Also auf web1 „web1“ und auf web2 „web2“.

Nun rufe über deine öffentliche IP-Adresse und Port 80 die Datei test.txt mehrmals in kurzen Abständen hintereinander auf. Du solltest dabei immer zwischen web1 und web2 wechseln.

Ändere den Port auf 81 und frage erneut in kurzen Abständigen die test.txt an. Was siehst Du?

Verlängere den Intervall der Anfragen solange, bis du wieder zwischen den einzelnen Webservern wechselst. Obwohl als Balancing Mode roundrobin konfiguriert ist, bleibst du für ca. fünf Sekunden auf einem der Webserver kleben. Erst, wenn mehr als fünf Sekunden zwischen zwei Anfragen liegen, wird deine TCP-Session neu verteilt und landet evtl. auf einem anderen Webserver. Das liegt daran, dass die TCP-Session nicht sofort geschlossen wird und du so Gelegenheit hast, noch einen weiteren Request in die bereits geöffnete TCP-Session zu senden.

PHP zum Auslesen der Webserverinfos

Damit ich an ein paar der Header auf dem Webserver komme, habe ich PHP direkt mitinstalliert. Leg doch mal eine neue Datei nach ‚/var/www/html/‘ mit Namen „info.php“. Schreib in die Datei rein:

<?php print_r($_SERVER); ?>

Wenn du jetzt die info.php über Port 80 oder 81 aufrufst, siehst du ein paar mehr Informationen über deinen Webserver und über den Verbindungsaufbau.
Wenn du dir die Ausgabe genau ansiehst, dann wirst du feststellen, dass an keiner Stelle deine IP-Adresse auftaucht. Stattdessen ist in beiden Fällen die interne IP-Adresse des HAProxy zu erkennen.

HAProxy und X-Forwarded-For Header

Lass uns als erstes den Header so verändern, dass du auf dem Webserver auch die IP-Adresse des anfragenden Clienten erkennen kannst. Hier hat sich ein Standard etabliert, der sogenannte X-Forwarded-For Header. Dieser sollte immer dann gesetzt werden, wenn aus irgendeinem Grund die Client-IP versteckt wird. Andernfalls hast du auf dem Webserver keine Möglichkeit festzustellen, welche Client-IP eine bestimmte Anfrage veranlasst hat.

Füge in dein port_80 Backend unterhalb von ‚mode http‘ folgendes hinzu:

http-request set-header X-Forwarded-For %[src]

Jetzt rufe erneut deine info.php über den Port 80 auf. Du solltest nun den Header ‚HTTP_X_FORWARDED_FOR‘ mit deiner öffentlichen IP erkennen können. Das Ganze hat einen kleinen Haken: Sollte sich zwischen dir und deinem HAProxy ein weiterer Proxy befinden, der bereits den X-Forwarded-For Header gesetzt hat (du terminierst also gar nicht mit deiner öffentlichen IP auf dem HAProxy), dann überschreibst du jetzt den bestehenden Header mit der falschen, nämlich der des Proxy-Servers, IP-Adresse. Aber später mehr dazu.

Du solltest jetzt einen wesentlichen Unterschied zwischen Layer-4 und Layer-7 Loadbalancing erkennen können. Es ist nicht möglich, in einem Layer-4 Loadbalancer eine Manipulation in dem höheren Protokoll vorzunehmen. Vielleicht jetzt noch kein großer Nachteil. Sobald du jedoch umfangreichere Manipulationen oder logische Entscheidungen treffen willst, kann Layer-4 dir die Arbeit nicht mehr abnehmen.

Beispiel Layer-7 Loadbalancer und URIs

Lass uns kurz einen neuen Frontend- und einen neuen Backend-Service definieren, um noch weitere Tests machen zu können. Füge einfach an das Ende der haproxy.cfg folgendes ein und starte den Dienst neu:

frontend port_82
 bind *:82
 mode http
 acl my_rule path_beg /i_exist
 use_backend alternative_82 if my_rule
 default_backend port_82

backend port_82
 mode http
 balance leastconn
 http-request set-header X-Forwarded-For %[src]
 option httpchk HEAD / HTTP/1.0
 server web1 10.0.0.2:80 check
 server web2 10.0.0.3:80 check

backend alternative_82
 mode http
 balance leastconn
 http-request set-header X-Forwarded-For %[src]
 option httpchk HEAD / HTTP/1.0
 server web1 10.0.0.2:80 check


Leg nun auf deinem web1 das Verzeichnis ‚/var/www/html/i_exist‘ an und lege dort eine Text-Datei „test.txt“ mit irgendeinem Inhalt ab. Lege dieses Verzeichnis nicht auf web2 an, denn durch die HAProxy-Konfiguration ist ja gewährleistet, dass immer nur web1 die Anfragen für dieses Verzeichnis bekommt.

Zusammenfassung

Also was hast du jetzt konfiguriert:

  • Drei neue Cloud Server (vermutlich mit Debian 8) die intern untereinander vernetzt sind.
  • Auf einen Cloud Server hast du einen HAProxy installiert, auf den anderen einen Apache2 mit PHP5
  • Du hast im HAProxy erfolgreich einen Layer-4 Loadbalancer erstellt (Port 81)
  • Du hast im HAProxy erfolgreich einen Layer-7 Loadbalancer erstellt (Port 80) und zugleich Header manipuliert
  • Und du hast im HAProxy eine bestimmte URI abgefangen und auf einen separaten Backend-Server umgeleitet

Das ist schon ganz gut. Was jetzt fehlt sind die Sticky Sessions (dazu später mehr), ein paar advanced Konfigurationen und natürlich noch SSL.