Apache Spark Cluster auf Docker Swarm
An dieser Stelle knüpfen wir an das Tutorial “Docker Swarm Cluster erstellen” an. In Teil 1 habe ich dich mit den Docker Swarm Basics vertraut gemacht und dir gezeigt, wie du einen Swarm generierst. Heute dreht sich alles um die Bereitstellung von Services auf einem Swarm. Ich mache dich Fit mit weiteren Swarm Kommandos, erkläre dir was der Docker Hub ist und zeige auf welchen Wegen du einen Services auf Docker Swarm depoyen kannst. Die Anwendung die wir auf dem Swarm deployen ist Apache Spark. Spark ist ein Open-Source Cluster Computing Framework von der Apache Foundation, welches hauptsächlich zur Datenverarbeitung eingesetzt wird.
Spark besteht aus unterschiedlichen Komponenten mit denen verschiedene Use Cases abgedeckt werden:
- Spark Core – für Big Data Analysen
- Spark SQL – Schnelle und skalierbare Datenstruktur-Konsole
- Spark Streaming – für die Verarbeitung von Datenströmen
- MLlib Machine Learning Library – Machine Learning für Spark-Systeme
- Spark GraphX – Berechnungen auf Graphen
In diesem Tutorial werden wir uns jedoch vorwiegend mit dem Infrastruktur Part von Docker Swarm auseinander setzen. Wenn du lernen willst, wie du coole Data Science Aufgaben mit Apache Swarm umsetzt, lohnt sich erstmal ein Blick in die Dokumentation von Spark.
In der nächsten Zeit wird aber auch ein Apache Spark Tutorial bei Tech4Hosting folgen.
Vorteile von Spark auf Docker Swarm
Die Bereitstellung von Apache Spark als Swarm Services und auch von Anwendungen generell bringt einige Vorteile mit sich.
- Das Starten von Services geht schnell
- Die Services sind leicht & beeinträchtigen nicht die Performance deiner Maschine
- Die Services lassen sich flexibel skalieren
- Via docker pull kannst du Images für deine Anwendung laden ohne aufwändige Skripts schreiben zu müssen
- Du kannst ein Overlay Network generieren und so die Vorteile der Docker Network Features nutzen
Ziel des Tutorials
Ziel des Tutorials ist es Spark im standalone Modus auf Docker Swarm zu deployen.
Die Cluster Architektur die wir für diesen Zweck einsetzen werden besteht aus 3 Cloud-Servern: Einem Master und 2 Workern. Ich habe mir das Setup in kurzer Zeit und mit wenig Aufwand in meinem Tech4Hosting Panel zusammengestellt. Überzeuge dich einfach selbst von unseren Features und der simplicity und baue dir deine eigene Cloud-Umgebung bei Tech4Hosting: Sign up? Hier entlang!.
Der replica Faktor setzt sich somit aus 1 für den Master und 2 für die Worker zusammen. Die Worker Nodes sind dafür da die Spark Jobs auszuführen.
In echten Setups läuft Spark häufig auf Mesos, YARN oder Hadoop. Wir werden Spark aber der Einfachheit halber im standalone Mode einsetzen, dies erfordert keine zusätzlichen Vorkehrungen und ist am einfachsten umzusetzem. Spark verteilt die Resourcen im standalone Cluster Mode nach Cores und Memory. Damit unsere Anwendung nicht vollständig auf den verfügbaren Speicher innerhalb des Clusters zurückgreifen wird, ist es notwendig, dass wir die Ressourcen der Worker in unserer Konfiguration limitieren. In diesem Tutorial werden wir auf ein Apache Spark Image aus dem Docker Hub zurückgreifen.
Was ist der Docker Hub?
An dieser Stelle werde ich dir noch ein paar Fact’s zum Docker Hub mit auf den Weg geben.
Wenn du mit Docker Containern und Services arbeitest, dann wirst du um den Docker Hub nicht herumkommen. Innerhalb des Docker Hubs findest du eine Auswahl an öffentlichen Images die Nutzer oder offizielle Herausgeber anderen Nutzern zur Verfügung stellen. Daneben gibt es einen nicht öffentlichen Bereich, in dem du deine eigenen Docker Images verwalten kannst.
Der Docker Hub ist also ein erster Anlaufpunkt, wenn du Container oder Services deployen willst. Oft findest du hier schon fertige und erprobte Images für bekannte Anwendungen. Der grad der Dokumentation zu den einzelnen Images kann dabei natürlich schwanken. Wenn du kein fertiges Image findest welches deinen Anforderungen entspricht, so kannst du auch dein eigenes erstellen. Zum deployen, musst du es in den Docker Hub uploaden und kannst anschließend entscheiden ob du es public machen willst. Hierfür ist eine Registrierung im Docker Hub notwendig.
Für unser Tutorial greifen wir auf ein bestehendes Image das ein Nutzer für andere bereitgestellt hat zurück. Du findest das Image im Docker Hub unter:
https://hub.docker.com/r/birgerk/apache-spark/
Schau dir unter dem Link am besten einmal an, wie so ein Dockerfile aufgebaut ist.
Vorbereitungen
Auf allen Servern die deinem Swarm Cluster angehören sollen, benötigst du Docker. Nachdem du Docker auf deinen Cloud Servern installiert hast, musst du deinen Swarm initialisieren und die Worker Nodes hinzufügen.
In diesen Tutorials erfährst du alles zur Installation von Docker:
Docker auf Ubuntu 16.04 LTS – ein einfaches Kochrezept
Docker auf Windows installieren
Und wie du einen Swarm mit Docker initialisiert wird dir hier gezeigt:
Docker Swarm Cluster erstellen
Wenn du mit den Vorbereitungen durch bist und dein Setup inklusive Swarm Cluster steht, dann können wir loslegen.
Swarm Setup
Das Apache Spark Docker Image welches, wir verwenden werden habe ich dir bereits weiter oben gezeigt. Also können wir damit beginnen uns das Image für unser Cluster zu ziehen. Die Spark Version, die wir mit dem Image erhalten ist Spark v2.2.1.
Ausgangspunkt für das weitere Vorgehen ist ein Setup, das in Etwa so aussehen sollte:
Docker Image pullen
Wechsel auf deinen Master Host und führe folgenden Befehl aus:
docker pull birgerk/apache-spark
Den Befehl zum pullen eines Docker Images findest du immer auf der jeweiligen Seite unter “Docker Pull Command”.
Overlay Network erstellen
Im nächsten Schritt erstellst du ein Overlay Network für das Cluster, damit die Hosts direkt miteinander auf Layer 2 Ebene kommunizieren können.
docker network create --driver overlay spark
Labels setzen
Anschließend versiehst du deine Nodes mit Labels, so hast du später die Möglichkeit zu filtern. Dem Master Node gibts du das Label sparkmaster und deinen Worker Nodes das Label sparkworker.
Die Syntax dafür:
docker node update --label-add type=sparkmaster [HOSTNAME von deinem Master]
docker node update --label-add type=sparkworker [HOSTNAME von deinem Worker1]
docker node update --label-add type=sparkworker [HOSTNAME von deinem Worker2]
Das setzen von Labels ist eine gute Angewohnheit und sorgt für besondere Deutlichkeit bei deinem Swarm. Mit den zwei verschiedenen Tags bist du in der Lage, die nachfolgenden constraints (Beschränkungen) auf dem Swarm zu definieren.
So hast du die Möglichkeit zwischen den constraints type == sparkworker (ist gleich) und type != sparkmaster (ist nicht gleich) bei der Definition von Services auf dem Swarm:
--constrain “node.labels.type==sparkworker”
und
--constraint “node.labels.type!=sparkmaster”
Spark auf Docker Swarm deployen
Jetzt kannst du damit beginnen, die Spark Services auf Docker Swarm zu erstellen.
Der Befehl mit dem ein Service initiiert wird lautet:
docker service create
Beginne als erstes mit dem Master Host:
docker service create
--hostname master
--container-label sparkmaster
--network spark
--constraint node.labels.type==sparkmaster
--publish 8080:8080
--publish 7077:7077
--publish 6066:6066
--publish 50070:50070
--replicas 1
--limit-memory 1g
--name spark-master
birgerk/apache-spark
Wenn du das ganze zum ersten Mal machst, werden bei dir jetzt wohl ein paar Fragezeichen aufleuchten oder vielleicht kannst du vieles auch schon erahnen. Deswegen gehen wir jede Zeile noch einmal durch.
Mit der ersten Option wird der Hostname des Containers gesetzt und mit der zweiten das Container Label. Mit der dritten Option hängst du dein zuvor erstelltes Overlay-Network an. Bei Option 4 wird auf die Node Labels zurückgegriffen, constraint sorgt dafür, dass der Service nur auf Nodes deployed wird die mit dem Label type sparkmaster übereinstimmen. Anschließend werden noch ein paar Ports published damit Spark richtig laufen kann (Spark Web UI, Spark Master Port, Spark REST Server). Danach folgt noch der Replika Faktor von 1 für den Master und eine Beschränkung von 1 GB für das Heap Size von Spark (Menge an Memory Ressourcen die Spark zur Verfügung stehen). Nach den Optionen wird noch der Name des Images definiert.
Dann deployest du den Spark Service für die Worker Nodes:
docker service create
--constraint node.labels.type==sparkworker
--network spark
--publish 8081:8081
--replicas 2
--limit-memory 512m
--env "SPARK_ROLE=slave"
--env "SPARK_MASTER=10.0.0.60"
--name spark-worker
birgerk/apache-spark
Wie du siehst, weicht das Kommando hier etwas von dem vorherigen Befehl ab. Mit Port 8081 exposed du den Port für das Spark Worker Web UI. Der Replika ist 2 und das Memory wird auf 512MB festgelegt.
Wichtig sind an dieser Stelle die beiden Optionen mit den environment Variablen. Bei den meisten brauchbaren Docker Images im Docker Hub findest du ergänzende Angaben für die Konfiguration. Bei dem Image das wir in diesem Tutorial verwenden, ist angegeben das die default Role von dem Image Master ist. Desweiteren wird ausgeführt das die environment Variable Spark_Role bei Slaves – also Workern – auf Slave gesetzt werden muss.
Die zweite Variable ist wichtig damit die Spark Hosts untereinander Kommunizieren können. An dieser Stelle stehen musst du die IP-Adresse angeben die in deinem Master Web UI unter REST URL spezifiziert ist.
Für mehr Infos zu allen create Optionen lohnt sich ein Blick auf die Help-Page:
docker service create --help
Der fertige Swarm
Soweit so gut. Wenn alles geklappt hat, kannst du dir nun auf deinem Master Node mit
docker service ls
eine Liste deiner Services ausgeben lassen.
Und auch in deinem Spark Master User-Interface sind jetzt die Worker-Nodes zu sehen.
Fazit
In diesem Tutorial haben wir eine echte Anwendung auf Docker Swarm deployed. Du konntest Praxis dabei sammeln, wie man ein Cluster startet, ein Overlay-Network für das Cluster erstellt und wie du deinen Service richtig definierst. Bis zu einem Production fertigen Spark Cluster sind es zwar noch ein paar Schritte z.B. fehlt das Storage-Setup, aber der Anfang ist geschafft!
Wenn du Lust auf mehr in Sachen Container-Management, Kubernetes, Docker und Co. hast, dann wirf ein Bilck in folgende Artikel:
- Docker Swarm vs. Kubernetes: Beide Container-Management-Tools im Vergleich
- Best-practice Kubernetes Cluster mit kubeadm
Bis bald!