Skalierbare Microservices mit Docker und HAProxy

20.06.2016

Ein Ziel von Microservice-Architekturen ist es, möglichst ausfallsicher und skalierbar zu sein. Dazu werden oftmals auf Redundanz und entsprechende Tools für eine möglichst automatische Skalierung gesetzt. Eine Kombination aus Docker und HAProxy vereinfacht die Erreichung dieses Ziels enorm.

Durch den Betrieb von Microservices in einer Docker-Infrastruktur können entsprechende Komponenten und Funktionen dieser Tools genutzt werden, um das Ziel Ausfallsicherheit zu erreichen. Ein Teil des Toolings von Docker ist Docker-Compose. Dieses bietet die Möglichkeit, vorab definierte Microservices einfach zur Laufzeit zu skalieren. Dies ist allerdings nur möglich, so lange die entsprechenden Container nicht an Host-Ports gebunden und damit von außerhalb der Docker-Umgebung erreichbar sind ¹. Ein System, welches über das Internet aufgerufen wird, hat zwangsweise eine Verbindung zu einem bestimmten Port. An dieser Stelle wird der Skalierungsmechanismus von Docker-Compose im Standardumfang also ausgehebelt.

HAProxy

Abhilfe schafft hier das Tool HAProxy. Dabei handelt es sich um einen TCP/HTTP-Loadbalancer. Dieser ermöglicht die automatische Verteilung von Anfragen an mehrere Service-Instanzen. Die Konfiguration von HAProxy erfolgt dabei über eine .cfg-Datei, welche die Namen, IP-Adressen und Ports der zu Verwaltenden Services beinhaltet. Im Normalfall wird diese Datei initial erstellt und ist statisch. Im Zusammenspiel mit Docker ist hier allerdings eine weitaus größere Magie möglich.

Docker kennt die IP-Adressen und Ports der aktuell laufenden Service-Instanzen. Entsprechende Informationen können durch das Abhören von /var/run/docker.sock auch anderen Services zur Verfügung gestellt werden. Kombiniert man nun HAProxy mit Docker in Form eines entsprechenden Images, so wird eine automatische Konfiguration und Rekonfiguration der entsprechenden HAProxy-Instanz möglich. Von HAProxy zu verwaltende Services binden sich nicht direkt an Host-Ports. Vielmehr veröffentlichen (expose) sie ihre öffentlichen Ports innerhalb des Docker-Umgebung. Einzig der HAProxy-Container bindet sich an Host-Ports (ports).

HAProxy & Docker

Um nun automatisch Service-Instanzen verwalten zu können, lauscht ein im HAProxy-Container ausgeführtes Skript auf Docker Events. Registriert dieses Script ein entsprechende Event, wie zum Beispiel den Start der Instanz eines Services, für welche HAProxy das Loadbalancing übernehmen soll, kann dieses Script die Konfiguration von HAProxy automatisch anpassen und die neue Instanz des Services eintragen. Gleiches funktioniert auch beim Herunterfahren oder Ändern der Service-Instanz. Welche Services für HAProxy relevant sind, wird über die Konfiguration von Docker Compose mitgeteilt. Dazu werden dem HAProxy-Service entsprechende Links zu den zu verwaltenden Services hinzugefügt. Nachfolgende Abbildung stellt diesen Aufbau schematisch dar.

Docker HAProxy Architektur
Docker HAProxy Architektur

Ein hervorragendes Beispiel für ein entsprechendes Szenario bietet die docker-compose-demo von vegasbrianc bei GitHub.

In der Docker-Registry eine Vielzahl von Images für HAProxy. In unseren Projekten verwenden wir bisher das Image von Docker Cloud, da es über eine hervorragende Dokumentation verfügt.

Um nun letztendlich die zu Beginn dieses Artikels erwähnte Ausfallsicherheit des Gesamtsystems erreichen zu können, kann neben dem Loadbalancing durch HAProxy die Supervisor-Funktion (restart) von Docker und ein Clustering mittels Docker-Swarm eingesetzt werden. Eine kurzweilige Zusammenfassung zu Docker-Swarm liefert der Blogartikel „Docker Swarm: Container-Orchestration leicht gemacht„.

Zurück zur Übersicht

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*Pflichtfelder

*