Les versions actuelles de Docker incluent nativement le mode Swarm afin de gérer un ensemble de Docker engine. De ce fait, à partir du moment où vous avez installé Docker sur plusieurs machines ( physiques ou virtuelles ), vous pouvez regrouper ces différentes installations dans un Swarm afin de les faire travailler ensemble et distribuer vos micro-services sur l'ensemble de votre installation : Qui parle d'orchestration ? 😀
Nous allons au cours de cet article, monter notre premier cluster et ainsi commencer à voir quelques concepts sur Docker Swarm.
Ce tutoriel n'est pas ici pour vous fournir une installation "production ready". Il s'agit de comprendre le fonctionnement afin de vous donnez toutes les clés pour réussir votre propre installation.
Nous pourrons d'ailleurs voir ensemble, par la suite, comment améliorer cette installation à travers plusieurs articles.
Préambule
Avant tout, je pense qu'il est nécessaire de se poser la question que beaucoup de monde n'ose plus aborder :
Est-il toujours intéressant de passer sur Docker Swarm en 2020 ? Surtout après le rachat de la partie entreprise de Docker par Mirantis ?
Ne tournons pas autour du pot, pour le moment l'avenir de Docker Swarm reste très flou. Après avoir annoncé dans un premier temps que Swarm ne serait plus maintenu après 2021, l'entreprise Mirantis s'est rétractée. Elle affirme même maintenant que de nouvelles fonctionnalités seront disponibles prochainement :
Ces ajouts seront-ils disponibles dans la version Docker CE ?!
En attendant, Docker Swarm est fonctionnel et reste un outil fort intéressant surtout pour ceux qui ne souhaitent pas passer sur Kubernetes ou au moins pas immédiatement.
Et j'ajouterais qu'il reste simple à mettre en œuvre et à comprendre donc si vous débutez avec un orchestrateur : c'est un point de départ intéressant.
Enfin, et surtout, vous êtes plusieurs à m'avoir demandé un tutoriel sur ce sujet afin d'en comprendre les grandes lignes : Let's go !
Pré-requis
Afin de réaliser ce tutoriel, vous allez avoir besoin d'au moins trois serveurs ou machines virtuelles avec Docker d'installé. Il est possible de lancer un Swarm avec uniquement 2 machines, voire même une seule, mais cela limiterait fortement l'intérêt des tests que nous allons effectuer tout au long de notre série sur ce sujet.
De mon côté je vais utiliser le Public Cloud d'OVH afin de me créer trois instance :
En ligne de commande, ça me donne :
$ openstack server create --image "Ubuntu 20.04" --flavor "s1-4" --key-name "MyKey" --net "Ext-Net" --user-data=docker.yaml my-manager
$ openstack server create --image "Ubuntu 20.04" --flavor "s1-4" --key-name "MyKey" --net "Ext-Net" --user-data=docker.yaml my-worker1
$ openstack server create --image "Ubuntu 20.04" --flavor "s1-4" --key-name "MyKey" --net "Ext-Net" --user-data=docker.yaml my-worker2
Et voici mon fichier cloud-init ( docker.yaml
) afin d'installer automatiquement Docker sur mes instances :
#cloud-config
package_update: true
packages:
- apt-transport-https
- ca-certificates
- curl
- gnupg-agent
- software-properties-common
runcmd:
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
- add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- apt-get update -y
- apt-get install -y docker-ce docker-ce-cli containerd.io
- systemctl start docker
- systemctl enable docker
final_message: "The system is finally up, after $UPTIME seconds"
Nous voila prêts !
Docker Swarm
Comme Swarm n'est qu'un mode de Docker, son gros avantage est que vous n'avez rien de plus à installer !
Nous allons donc pouvoir initialiser notre premier cluster immédiatement.
Sur ma machine manager, je vais lancer la commande suivante :
$ sudo docker swarm init
Swarm initialized: current node (vseamtq4qgpmvu0m50gaee3co) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1jyx1grn9l5ru7oh2hxlquioccoasrxcstqwr9c511gwzah98y-ac0ulnp1e1sey7ntyumidqtu0 X.X.X.X:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Que se passe-t-il lorsque j'exécute cette commande ?
Comme vous pouvez le constater, la sortie standard vous renvoie la commande qui va vous permettre, plus tard, de rejoindre votre cluster depuis une autre machine :
docker swarm join --token SWMTKN-1-1jyx1grn9l5ru7oh2hxlquioccoasrxcstqwr9c511gwzah98y-ac0ulnp1e1sey7ntyumidqtu0 X.X.X.X:2377
Avec cette sortie nous pouvons voir également deux choses.
- Docker écoute maintenant sur le port 2377 qui est le port par défaut pour les communications liées à la gestion de votre cluster.
🚩 Il serait préférable d'utiliser un réseau privé afin de réaliser ces échanges entre les différents nodes du cluster, pour des raisons de sécurité bien évidemment. Dans un souci de simplification, je n'ai pas abordé ce point aujourd'hui 🚩
- Je viens de créer un node manager. Il existe deux types de nodes dans Docker Swarm :
Les managers : Ce sont les nodes gestionnaires de votre cluster. Ils distribuent les tâches aux nodes workers et ils effectuent également les fonctions d'orchestration et de gestion.
Vous pouvez avoir plusieurs nodes managers, par contre un seul de ces nœuds est élu leader du cluster.
Les workers : Les petites mains de votre cluster. Ils vont exécuter les tâches confiées par les managers. Un agent s'exécute sur chaque nœud et rend compte des tâches qui lui sont affectées. Il informe ainsi les nodes managers de l'état des tâches affectées.
Un nœud manager peut également être worker et ainsi exécuter des tâches. Sauf si vous lui demandez explicitement d'être uniquement manager.
Pour être précis, et même si rien ne le montre à ce moment là, d'autres ports viennent également de s'ouvrir :
- TCP and UDP port 7946 for communication among nodes
- UDP port 4789 for overlay network traffic
Ajoutons maintenant nos deux nodes workers à notre cluster :
$ sudo docker swarm join --token SWMTKN-1-1jyx1grn9l5ru7oh2hxlquioccoasrxcstqwr9c511gwzah98y-ac0ulnp1e1sey7ntyumidqtu0 X.X.X.X:2377
This node joined a swarm as a worker.
Je peux vérifier l'état de mon cluster avec la commande :
$ sudo docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
vseamtq4qgpmvu0m50gaee3co * s1-4-gra7-1 Ready Active Leader 19.03.11
tfbcyrplop3yvdmt6hjzc4tic s1-4-gra7-2 Ready Active 19.03.11
s2yftcngo6j2278y82yhohinn s1-4-gra7-3 Ready Active 19.03.11
C'est aussi simple que cela... !
Nous allons créer un premier container afin de pouvoir visualiser notre cluster. Pour cela je vais utiliser l'image dockersamples/visualizer
. Mais comment créer ce container dans Swarm ?
Services
Est-ce que je peux lancer simplement cette image dans mon cluster avec la commande docker run
?
Vous pouvez effectivement lancer une image de cette façon. Il sera alors considéré comme un container standalone dans votre Cluster. Swarm ne s'occupera pas de lui.
Mais alors, comment créer des containers gérés par Swarm ?
Les services
!
Si vous utilisez docker-compose
, ce mot vous dira peut-être quelque chose ? C'est normal ...
En réalité Swarm utilise la même syntaxe que la commande docker-compose
pour déployer des services. Créons par exemple un fichier docker-compose.yaml
pour notre image :
version: "3"
services:
viz:
image: dockersamples/visualizer
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
ports:
- "8080:8080"
Il s'agit donc de la même syntaxe qu'avec docker-compose
. Mais je vais lancer ce service dans mon cluster avec la commande docker stack deploy
:
$ sudo docker stack deploy --compose-file docker-compose.yaml myfirststack
Creating network myfirststack_default
Creating service myfirststack_viz
Une stack
, n'est rien d'autre qu'un ou plusieurs services ( donc des containers ) qui vont fournir une application.
Pour vérifier que votre service fonctionne :
docker service ls
Enfin rendez-vous sur http://ADRESSE_IP_MANAGER:8080
:
Et si on essayait sur l'adresse de l'un de nos workers http://ADDRESSE_IP_WORKER1:8080
:
Et oui, c'est la même chose ! Dans Swarm, lorsque l'on publie un port, celui-ci est accessible sur tous les nœuds. Peu importe sur quel node tourne mon application !
Enfin vous pouvez arrêter votre stack avec :
$ sudo docker stack rm myfirststack
Removing service myfirststack_viz
Removing network myfirststack_default
Nous avons vu aujourd'hui comment créer notre premier cluster avec Docker Swarm et même déployer notre première application. Au cours du prochain article, nous allons pouvoir aller plus loin en créant une stack classique d'application web avec un frontend et un backend et donc plusieurs services.
Cela nous permettra de voir plus en détails les mécanismes de réseaux mis en œuvre dans Swarm ( overlay network, ingress ) et de découvrir quelques options des fichiers compose
spécifiques à Swarm.
En tout cas n'hésitez pas à m'apporter des remarques ou des commentaires sur Twitter, ou ici 👇