Pour découvrir le swarm (la nuée ou l'essaim) de docker, on va partir de notre poste Fedora, avec une installation de libvirt fonctionnelle.

Installation
On va créer deux nouvelles machines virtuelles que l'on nommera worker1 et worker2: 2 vCPUs et 4Go de RAM.
Sur l'hôte servant de manager, on initialise le swarm (aka le poste Fedora), en précisant l'adresse IP sur la patte libvirt
docker swarm init --advertise-addr 192.168.122.1
Swarm initialized: current node (2kdz664ro2rpjh5pn1743gsez) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join
--token SWMTKN-1-5od9m6ccyazf6uqnopqv6f1p2xqu4saiul7yvbqvjkw5ryczyz-8mjxk1qv26isjnzzyzpf02w5e
192.168.122.1:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Sur les deux hôtes servant de workers: worker1 et worker2
-
On installe la version la plus récente de docker
yum install docker docker-latest -
On lance le daemon docker
systemctl start docker -
On se joint au swarm en précisant le token fourni à l'initialisation du swarm sur le manager.
docker swarm join --token SWMTKN-1-54yhh9qjmwcsxb4jhp7p6a0isc4in0vykqu3ir4y06aq6xtpbb-8mspc4bbxh32nx8obni897fvn 192.168.122.1:2377 This node joined a swarm as a worker.
Le swarm est en place, il ne reste plus qu'à l'utiliser.
Visualiseur
Pour faciliter la vision des choses, on va mettre en place un visualiseur, qui sera encore un conteneur docker.
docker run -it -d
-p 5000:8080
-v /var/run/docker.sock:/var/run/docker.sock
--name swarm_visualizer
dockersamples/visualizer
On accède maintenant au visualizer en allant sur l'url http://192.168.122.1:5000/

Gestion des services
Docker swarm gère des services qui seront associés en interne à un ou plusieurs conteneurs. Dans cette exemple (phpmyadmin), on va le découper en deux services:
- la base de données
- le serveur web avec le module php
On aurait pu découper en trois, en n'installant pas le module php avec le serveur web et utiliser un service php-fpm, mais cela aurait complexifié inutilement l'exemple.
Afin que nos conteneurs puisse se parler entre eux, on va créer un réseau dédié (overlay)
docker network create --driver overlay --subnet 172.255.0.0/24 swarmnet
On démarre le conteneur embarquant la base de données. Quelques remarques sur la commande à lancer:
- On fixe la contrainte d'exécution sur le manager, car le conteneur a un volume attaché et docker n'a pas de solution de synchonisation des volumes en natif. En effet si le conteneur s'exécutait sur une autre hôte (worker), il aurait un nouveau volume vierge et on oublie la persistance des données. Toutefois, on pourrait fixer la contrainte d'exécution sur un worker particulier avec
--constraint node.hostname=worker1afin de toujours se servir du même volume de données. - On monte le volume docker s'appelant pma-db-data en lieu et place du répertoire de travail mariadb.
- On fixe le nom de la base de données, les identifiants utilisateur et le mot de passe du superutilisateur (root) via des variables d'environnement.
- On précise que le conteneur est accessible via son nom d'hôte (accès par rotation DNS) et comme on n'a qu'un seul conteneur base de données, on est sûr de tomber toujours sur le même). Sans ce paramètre (accès par vip) il aurait fallut brancher le port 3306 sur l'hôte exécutant docker (le poste Fedora) et de connecter le conteneur web à l'adresse IP de l'hôte.
- Évidemment, on le branche sur notre réseau dédié
docker service create --name pma-db
--constraint node.role==manager
--mount type=volume,src=pma-db-data,dst=/var/lib/mysql
-e DB_NAME=pmadb
-e DB_USER=pma
-e DB_PASS=pmapasswd
-e DB_ROOT_PASS=rootpasswd
--endpoint-mode dnsrr
--network swarmnet
docker.io/didier13150/mariadb
On démarre maintenant le second conteneur qui contient le serveur web (avec le module php) et phpmyadmin sur un des workers
- On fixe la contrainte d'exécution sur un worker
- On lui communique le nom d'hôte, le nom de la base de données, ainsi que les identifiants utilisateur via des variables d'environnement.
- On connecte le port 80 du conteneur sur le port 8080 du manager, même si le(s) conteneur(s) s'exécute(nt) sur le(s) worker(s)
- On le branche également sur notre réseau dédié (pour la résolution du nom d'hôte pma-db)
docker service create --name pma-web
--constraint node.role==worker
-e DB_NAME=pmadb
-e DB_USER=pma
-e DB_PASS=pmapasswd
-e DB_HOST=pma-db
-p 8080:80
--network swarmnet
docker.io/didier13150/phpmyadmin
On accède maintenant à phpmyadmin en allant sur l'url http://192.168.122.1:8080/

Rien de bien compliqué jusqu'à présent.
Mais imaginons qu'un seul serveur web ne puisse tenir la charge et qu'il faudrait le cloner (même plusieurs fois) pour absorber la charge, disons 4 instances de ce serveur web serait pas mal. La magie de swarm, c'est que c'est faisable à chaud, quasiment instantanément et en une seule petite commande:
docker service scale pma-web=4

Et encore plus fort, imaginons que le pic de charge est passé et que les clones ne servent plus à rien, et bien on peut les supprimer:
docker service scale pma-web=1
Pour arrêter les services, on les supprime
docker service rm pma-web
docker service rm pma-db
On arrête aussi notre réseau
docker network rm swarmnet
Gestion des nœuds
Étudions maintenant la gestion des nœuds au sein de notre essaim
-
Lister les nœuds du swarm
docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 2kdz664ro2rpjh5pn1743gsez * manager1 Ready Active Leader 0xj7x2kxmjuvyqj19ekdubs99 worker1 Ready Active 7xqkaxxbzi4260b6drujhis1q worker2 Ready Active -
Supprimer un nœud
docker node rm 7xqkaxxbzi4260b6drujhis1q