Premiers pas avec Docker Swarm

Posted by

Principe

Docker Swarm est un système d’orchestration de conteneur incorporé à Docker Engine. Moins populaire et complet de Kubernetes, il est aussi plus simple à utiliser.

Un cluster Swarm est composé de deux types de noeuds :

  • Les manager nodes qui gèrent la configuration du cluster
  • Les worker nodes qui offrent de la capacité de calcul

Swarm va permettre de déployer des services. Un service est l’état désiré d’un ou plusieurs conteneurs, les ports exposés, le nombre de conteneurs à instancier pour assurer le fonctionnement etc… Le manager node va ensuite se charger de gérer l’orchestration sur les worker afin d’offire le fonctionnement désiré.

Pour la suite, je disposerai de 3 nodes sous Ubuntu 22.04 :

  • swarm0 / 192.168.69.60 : manager node
  • swarm1 / 192.168.69.61 : worker node
  • swarm2 / 192.168.69.62 : worker node

Si docker-ce n’est pas installé, cela se règle rapidement avec :

sudo apt update
sudo apt -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
sudo apt -y remove docker.io
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg |apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt -y install docker-ce
sudo systemctl enable --now docker

Créer le cluster

Docker Swarm est compris par défaut donc il n’y a rien de plus à installer. On peut donc initier le cluster sur le manager avec en advertise address, l’ip du manager :

sudo docker swarm init --advertise-addr 192.168.69.60
Swarm initialized: current node (qeo9wfwnm22pd9mae9hscxfcs) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-13bd0a7lozmekt5ph18igdtngwnqqe9s8lezwcxybqcz05p1gb-0dt1bomyoleflgzy58xbri5e6 192.168.69.60:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Le token est à conserver de manière sécurisée dans un vault ou un keepass par exemple.

On peut maintenant joindre les worker node au manager node avec ce toker et en précisant l’IP du manager :

sudo docker swarm join --token SWMTKN-1-13bd0a7lozmekt5ph18igdtngwnqqe9s8lezwcxybqcz05p1gb-0dt1bomyoleflgzy58xbri5e6 192.168.69.60:2377
[sudo] password for julien:
This node joined a swarm as a worker.

Vérifions nos noeuds :

sudo docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
qeo9wfwnm22pd9mae9hscxfcs *   swarm0     Ready     Active         Leader           23.0.1
aq0jchfcz0c0vedu6gsdteoav     swarm1     Ready     Active                          23.0.1
daspjlhzxpk2xkg9mpbf70s2l     swarm2     Ready     Active                          23.0.1

Lancer un service

Avec Swarm, on ne déploie pas un simple conteneur, il serait instancié bien entendu mais géré comme un conteneur autonome.
On va donc se créer un fichier docker-compose.yml et le déployer sur le cluster. Ici, on va simplement déployer une image nginx avec deux réplicas.

version: "3"
services:
  web:
    image: nginx
    deploy:
      replicas: 2
    ports:
     - "8080:80"
    environment:
     - NGINX_HOST=morot.local
     - NGINX_PORT=80

Et vérifier que le service est bien déployé

julien@swarm0:~$ sudo docker stack deploy --compose-file docker-compose.yml nginx-stack
Creating network nginx-stack_default
Creating service nginx-stack_web

Il est possible de visualiser où nos conteneurs sont lancés :

sudo docker service ps nginx-stack_web
ID             NAME                IMAGE          NODE      DESIRED STATE   CURRENT STATE           ERROR     PORTS
fhgipvoq55wl   nginx-stack_web.1   nginx:latest   swarm1    Running         Running 5 minutes ago
wd2obqai9xoj   nginx-stack_web.2   nginx:latest   swarm0    Running         Running 5 minutes ago

Sur chaque noeud on peut visualiser les conteneurs qui y sont lancés.

 sudo docker ps
[sudo] password for julien:
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
569eeae4351e   nginx:latest   "/docker-entrypoint.…"   6 minutes ago   Up 6 minutes   80/tcp    nginx-stack_web.1.fhgipvoq55wl6qfuals6cxpdg

Après arrêt d’un des deux worker, le conteneur lancé sur swarm1 est lancé sur swarm2 :

julien@swarm0:~$ sudo docker service ps nginx-stack_web
ID             NAME                    IMAGE          NODE      DESIRED STATE   CURRENT STATE            ERROR     PORTS
w0ns4o93q4dp   nginx-stack_web.1       nginx:latest   swarm2    Running         Running 18 seconds ago
fhgipvoq55wl    \_ nginx-stack_web.1   nginx:latest   swarm1    Shutdown        Running 8 minutes ago
wd2obqai9xoj   nginx-stack_web.2       nginx:latest   swarm0    Running         Running 8 minutes ago

Maintenant, faisons en sorte que notre manager ne soit plus un worker node :

julien@swarm0:~$ docker node update --availability drain swarm0
swarm0

Pour assurer le nombre de réplicas, un second conteneur a été démarré sur le worker swarm 2 :

sudo docker service ps nginx-stack_web
ID             NAME                    IMAGE          NODE      DESIRED STATE   CURRENT STATE             ERROR     PORTS
w0ns4o93q4dp   nginx-stack_web.1       nginx:latest   swarm2    Running         Running 5 minutes ago
fhgipvoq55wl    \_ nginx-stack_web.1   nginx:latest   swarm1    Shutdown        Running 13 minutes ago
s8olvpwus904   nginx-stack_web.2       nginx:latest   swarm2    Running         Running 10 seconds ago
wd2obqai9xoj    \_ nginx-stack_web.2   nginx:latest   swarm0    Shutdown        Shutdown 12 seconds ago

Redémarrons le node précédemment arrêté et pour assurer la montée en charge, nous allons indiquer que nous souhaitons 3 réplicas désormais :

docker service scale nginx-stack_web=3
nginx-stack_web scaled to 3
overall progress: 3 out of 3 tasks
1/3: running   [==================================================>]
2/3: running   [==================================================>]
3/3: running   [==================================================>]
verify: Service converged

docker service ls
ID             NAME              MODE         REPLICAS   IMAGE          PORTS
llv38z9l6a0p   nginx-stack_web   replicated   3/3        nginx:latest   *:8080->80/tcp

sudo docker service ps nginx-stack_web
ID             NAME                    IMAGE          NODE      DESIRED STATE   CURRENT STATE                ERROR     PORTS
w0ns4o93q4dp   nginx-stack_web.1       nginx:latest   swarm2    Running         Running 12 minutes ago
fhgipvoq55wl    \_ nginx-stack_web.1   nginx:latest   swarm1    Shutdown        Shutdown 2 minutes ago
s8olvpwus904   nginx-stack_web.2       nginx:latest   swarm2    Running         Running 7 minutes ago
wd2obqai9xoj    \_ nginx-stack_web.2   nginx:latest   swarm0    Shutdown        Shutdown 7 minutes ago
k9g4x9kjsham   nginx-stack_web.3       nginx:latest   swarm1    Running         Running about a minute ago

Faisons le ménage et supprimons notre stack :

sudo docker stack rm nginx-stack
Removing service nginx-stack_web
Removing network nginx-stack_default

Leave a Reply

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *