Die hybride Cloud mit Docker Swarm und Ansible (2/2)

Seite 4: Portainer visualisiert den Schwarm

Inhaltsverzeichnis

Natürlich ist der Schwarm nun vollständig initialisiert. Mit dem Docker Swarm CLI steht die gesamte Bandbreite an Interaktionsmöglichkeiten zur Verfügung. Beispielsweise zeigt der Befehl docker service ls alle laufenden Docker Swarm Services und das Kommando docker service ps [ServiceName] die Interna eines solchen Services. Trotzdem kann es sicherlich nicht schaden, eine grafische Aufbereitung in Form einer Managementoberfläche zur Verfügung zu haben.

Docker stellt zwar selbst mit dem Projekt Swarm Visualizer eine Visualisierungsoberfläche zur Verfügung, allerdings steht mit dem Tool Portainer eine weitaus umfangreichere und ausgereiftere Alternative zur Verfügung, die ebenfalls vollständig als Open-Source-Software vorliegt. Im Internet finden sich dazu viele Gegenüberstellungen. Und da Portainer zusätzlich hybride Cluster aus Windows- und Linux-Nodes vollständig unterstützt, steht der Nutzung im vorliegenden Szenario nichts im Wege.

Dazu enthält das Beispielprojekt eine komplette Portainer-Konfiguration. Das im Haupt-Playbook inkludierte run-portainer.yml enthält alle dafür notwendigen Anweisungen:

- name: Create directory for later volume mount into Portainer service on Linux Manager node if it doesn´t exist
file:
path: /mnt/portainer
state: directory
mode: 0755
when: inventory_hostname in groups['linux']
sudo: yes

- name: Run Portainer Docker and Docker Swarm Visualizer on Linux Manager node as Swarm service
shell: "docker service create --name portainer --publish 9000:9000 --constraint 'node.role == manager' --constraint
ignore_errors: yes
when: inventory_hostname == "masterlinux01"

Nach der Erstellung eines Mount-Punkts für die später zu persistierenden Portainer-Meta-Daten, deployt man Portainer als Docker Swarm Service. Die beiden Constraints --constraint 'node.role == manager' sowie -- constraint 'node.labels.os==linux' sorgen dafür, dass Docker Swarm Portainer nur auf Linux-Manager-Nodes laufen lässt. Im aktuellen Beispiel damit also genau auf einer Maschine. Die Anweisung [i]--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock gibt Portainer direkten Zugriff auf die laufende Docker-Instanz des Linux-Manager-Nodes. Dadurch ist Portainer in der Lage, alle möglichen Management-Aufgaben innerhalb eines Docker Swarm auszuführen. Weitere Konfigurationsmöglichkeiten verrät die Portainer-Dokumentation.

Ein Aufruf der Portainer-Weboberfläche von einem der Windows-Nodes kann schnell frustrieren. Denn der installierte Internet-Explorer ist nicht in der Lage, die auf einer neueren Angular-Version basierende Oberfläche von Portainer vernünftig darzustellen. Per Ansible ist ein aktueller Browser aber schnell installiert. Dann lässt sich Portainer einfach per http://172.16.2.10:9000 aufrufen.

Doch im vorliegenden Beispielprojekt ist das gar nicht nötig. Denn die Konfigurationsanweisung masterlinux.vm.network "forwarded_port", guest: 9000, host: 49000, host_ip: "127.0.0.1", id: "portainer" im Vagrantfile des Vagrant-Multi-Machine-Clusters bindet den Port 49000 des Host-Systems an den Port 9000 des Linux-Manager-Nodes. Und auf dem Port ist der Portainer-Docker Swarm Service deployt. Es genügt ein Aufruf der Adresse http://localhost:49000/ im Browser des Vagrant-Hosts, um Portainer zu öffnen.

Portainer visualisiert den Docker Swarm

Wie im Abschnitt "HTTP-basierte Docker-Registries erlauben" erwähnt, gelingt das Bereitstellen der Docker-Images für das Applikations-Deployment auf jeden Cluster-Node am einfachsten mit einer lokalen Docker Registry. Obwohl eine Docker Registry nicht direkt zum Initialisieren eines Docker Swarm notwendig ist, ist sie für einen vollständig nutzbaren Schwarm doch unverzichtbar. Die Initialisierung einer Registry ist in der Docker-Dokumentation beschrieben. Allerdings hat sie noch einige Pull-Requests (docker.github.io/pull/4465, docker.github.io/pull/4641 und docker.github.io/pull/4644) nötig. Das Beispielprojekt setzt die Docker Registry wieder mit Ansible auf. Dazu kommt das inkludierte Playbook run-swarm-registry.yml zum Einsatz:

- name: Specify to run Docker Registry on Linux Manager node
shell: "docker node update --label-add registry=true masterlinux01"
ignore_errors: yes
when: inventory_hostname == "masterlinux01"

- name: Create directory for later volume mount into the Docker Registry service on Linux Manager node if it doesn´t
file:
path: /mnt/registry
state: directory
mode: 0755
when: inventory_hostname in groups['linux']
sudo: yes

- name: Run Docker Registry on Linux Manager node as Swarm service
shell: "docker service create --name swarm-registry --constraint 'node.labels.registry==true' --mount type=bind,src
ignore_errors: yes
when: inventory_hostname == "masterlinux01"

Passend für Linux ist das Docker-Image für eine Docker Registry standardmäßig über den hub.docker.com bereitgestellt. Um die Registry auf dem Linux-Manager-Node auszuführen, versieht man ihn zuerst mit dem shell-Modul und dem Kommando docker node update mit dem Label registry=true. Danach erfolgt - wie schon bei der Portainer- Konfiguration - die Erstellung eines Mount-Punkts, der später von der Registry als persistente Ablagemöglichkeit für Docker-Images Verwendung findet.

Im letzten Schritt im Playbook weist Docker Swarm an, die Registry als Service auf dem Linux-Manager-Node zu starten und sie auf dem Port 5000 bereitzustellen. Nach der Ausführung des Ansible-Playbooks sollte der Docker Swarm einen Service mit dem Namen swarm-registry ausführen. Am einfachsten ist die Überprüfung über die Portainer-Oberfläche möglich.

Die beiden bisher deployten Docker Swarm Services

Im Haupt-Playbook initialize-docker-swarm.yml folgt nur noch ein letzter Schritt. Der letzte task inkludiert das Playbook display-swarm-status.yml, das nicht viel mehr zu tun hat, als den aktuellen Status des Schwarms am Ende der Ausführung des Ansible-Skripts auf der Kommandozeile auszugeben.

Der letzte Output des Ansible-Skripts gibt am Ende Aufschluss über den aktuellen Status des Schwarms