Orchestrateurs - Swarm
Docker Swarm
Docker swarm est la solution de Docker pour exécuter Docker sur plusieurs hôtes.
La solution n'a jamais résolu les problèmes complexes et d'échelle de la production.
Aujourd'hui le produit est toujours disponible mais n'a plus de visibilité pour l'avenir.
Architecture de Swarm
Docker Swarm est la solution native d'orchestration de conteneurs de Docker
Swarm permet de gérer un cluster de machines Docker comme une seule entité virtuelle.
L'architecture de Swarm est composée d'un control plane et de worker nodes.

Tout est géré via docker qui fournit l'interconnexion réseau, l'élection du service principal dans le control plane, la répartition des conteneurs sur les worker nodes.
Un noeud peut faire partie des deux groupes : être à la fois membre du control plane et héberger des services.
Les requêtes arrivant sur un noeud du cluster sont routées vers le conteneur adapté le plus proche via le docker proxy.

Les rôles des nœuds (manager, worker)
Un cluster Swarm est composé de nœuds managers et workers :
- Manager nodes : Gèrent l'état du cluster, orchestrent les services, maintiennent le consensus
- Worker nodes : Exécutent les tâches (containers) assignées par les managers
# Initialiser un swarm
$ docker swarm init --advertise-addr <MANAGER-IP>
# Rejoindre un swarm en tant que worker
$ docker swarm join --token <WORKER-TOKEN> <MANAGER-IP>:2377
# Lister les nœuds
$ docker node ls
Différences et relations entre Swarm et Kubernetes
Swarm et Kubernetes sont deux orchestrateurs avec des approches différentes :
| Aspect | Docker Swarm | Kubernetes |
|---|---|---|
| Complexité | Simple à déployer | Plus complexe |
| Scaling | Scaling rapide | Scaling avancé |
| Écosystème | Intégré Docker | Vaste écosystème |
| YAML | Syntaxe simple | Syntaxe complexe |
Kompose : Outil pour convertir des docker-compose.yml en ressources Kubernetes
Orchestrateur Swarm sur K8S : Possibilité d'exécuter Swarm dans des pods Kubernetes
Swarm est un composant natif de Docker via swarmkit.
$ docker swarm --help
Usage: docker swarm COMMAND
Manage Swarm
Commands:
ca Display and rotate the root CA
init Initialize a swarm
join Join a swarm as a node and/or manager
join-token Manage join tokens
leave Leave the swarm
unlock Unlock swarm
unlock-key Manage the unlock key
update Update the swarm

La sécurisation de la communication est assurée par une chaine de certificats x509.
Par défaut le premier serveur sur lequel le control plane a été initié va générer une Autorité de Certification racine, mais il est possible d'utiliser une autorité de certification externe.
Pour rejoindre le cluster dans un rôle ou un autre, il faut fournir
Les services
Les services sont la partie opérationnelle de Swarm : ils permettent de répartir des réplicas de conteneurs sur les worker nodes.
$ docker services --help
Usage: docker service COMMAND
Manage services
Commands:
create Create a new service
inspect Display detailed information on one or more services
logs Fetch the logs of a service or task
ls List services
ps List the tasks of one or more services
rm Remove one or more services
rollback Revert changes to a service's configuration
scale Scale one or multiple replicated services
update Update a service

Le moyen le plus pratique de gérer les services est d'utiliser des fichiers de type docker compose.
Certaines parties de la specification Compose sont uniquement destinés aux services
La référence complète de tout ce qu'il est possible de définir est sur :
https://github.com/compose-spec/compose-spec/blob/main/05-services.md
Mise en oeuvre
Se grouper par 2 ou 3 pour créer un cluster à partir de vos VM respectives (il faut utiliser une commande Swarm pour récupérer les instructions nécessaires :
docker swarm initdevrait vous orienter).Si grouper plusieurs des VM n'est pas possible, vous pouvez faire un cluster à un seul noeud, ou bien créer un cluster multi-nodes très simplement avec l'interface du site Play With Docker, il faut s'y connecter avec vos identifiants Docker Hub. Vous pouvez vous connecter à ces VM en SSH.
Vous pouvez faire
docker swarm --helppour obtenir des infos manquantes, ou fairedocker swarm leave --forcepour réinitialiser votre configuration Docker Swarm si besoin.N'hésitez pas à regarder dans les logs avec
systemctl status dockercomment se passe l'élection du nœud leader, à partir du moment où vous avez plus d'un manager.
Créer un service
Afin de visualiser votre installation Swarm, l'application Portainer est très pratique.
On peut aussi utiliser Docker swarm vizualizer : https://github.com/dockersamples/docker-swarm-visualizer
docker run -d -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock dockersamples/visualizer
En ligne de commande
En ligne de commande :
docker service create --name whoami --replicas 5 -p 9999:80 traefik/whoami
Avec la clé deploy:
A l'aide de la propriété deploy: de docker compose, créer un service en 5 exemplaires (replicas) à partir de l'image traefik/whoami accessible sur le port 9999 et connecté au port 80 des 5 replicas.
Correction
services:
whoami:
image: traefik/whoami
ports:
- 9999:80
deploy:
replicas: 5
Accédez à votre service depuis un node et actualisez plusieurs fois la page (Ctrl+Maj+R sinon le cache du navigateur vous embêtera). Les informations affichées changent. Pourquoi ?
- Lancez une commande
service scalepour changer le nombre de replicas de votre service et observez le changement avecdocker service ps hello
Administrer les Docker Secrets

Les secrets permettent de gérer les données sensibles de manière sécurisée :
# Créer un secret depuis un fichier
$ echo "mon-mot-de-passe" | docker secret create db_password -
# Créer un secret depuis la ligne de commande
$ docker secret create api_key "ma-clé-secrète"
# Lister les secrets
$ docker secret ls
# Utiliser un secret dans un service
$ docker service create \
--name webapp \
--secret source=db_password,target=/run/secrets/db_password \
nginx:latest
Les secrets sont :
- Chiffrés au repos
- Transmis de manière sécurisée
- Montrés uniquement aux services autorisés
- Stockés dans le Raft log du swarm
Swarm Manager Locking
Protection contre la perte de quorum en cas de panne des managers :
# Vérifier l'état actuel du swarm
$ docker swarm unlock-key
# Régénérer la clé de déverrouillage
$ docker swarm unlock-key --rotate
# Déverrouiller un manager verrouillé
$ docker swarm unlock
Fonctionnement :
- En cas de perte de quorum, les managers se verrouillent automatiquement
- Nécessite une clé de déverrouillage pour reprendre le contrôle
- Protège contre les scenarios "split-brain"
Les déploiements, rollbacks et le monitoring (Prometheus)
Gestion des déploiements et rollbacks :
# Déployer un service avec mise à jour progressive
$ docker service create \
--name web \
--replicas 3 \
--update-delay 10s \
--update-parallelism 1 \
nginx:1.18
# Mettre à jour un service
$ docker service update \
--image nginx:1.19 \
web
# Rollback d'un service
$ docker service update --rollback web
# Surveiller les déploiements
$ docker service ps web
Intégration Prometheus :
version: '3.8'
services:
app:
image: mon-app:latest
ports:
- "8080:8080"
deploy:
replicas: 3
labels:
- "com.docker.prometheus.scrape=true"
- "com.docker.prometheus.port=8080"
- "com.docker.prometheus.path=/metrics"
Les contraintes de placement des conteneurs

Contrôler où les conteneurs sont déployés dans le cluster :
version: '3.8'
services:
database:
image: postgres:13
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
- node.labels.disk == ssd
preferences:
- spread: node.labels.datacenter
cache:
image: redis:6
deploy:
placement:
constraints:
- node.labels.redis == true
Types de contraintes :
node.role == manager|workernode.labels.key == valueengine.labels.key == valuenode.hostname == hostname
Le clustering, le calcul du quorum et l'algorithme de Raft

Architecture de consensus distribué :
# Recommandations pour la configuration des managers
# Nombre impair de managers recommandé
# 3 managers : tolère la perte d'1 manager
# 5 managers : tolère la perte de 2 managers
# 7 managers : tolère la perte de 3 managers
# Ajouter un manager
$ docker swarm join-token manager
# Calcul du quorum : (n/2) + 1
# Ex: 3 managers → quorum = 2
# Ex: 5 managers → quorum = 3
Algorithme Raft :
- Élection de leader
- Réplication des logs
- Tolérance aux pannes
- Cohérence forte
Une base de données distribuée (Postgres HA)
Déploiement de PostgreSQL haute disponibilité avec Swarm :
version: '3.8'
services:
postgres-primary:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: admin
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
volumes:
- postgres_data:/var/lib/postgresql/data
deploy:
replicas: 1
placement:
constraints:
- node.labels.db == primary
restart_policy:
condition: on-failure
postgres-replica:
image: postgres:13
command: >
sh -c "
until pg_basebackup -h postgres-primary -D /var/lib/postgresql/data -U replicator -vP -W;
do sleep 2; done &&
echo 'host replication replicator 0.0.0.0/0 md5' >> /var/lib/postgresql/data/pg_hba.conf &&
cp /var/lib/postgresql/data/postgresql.conf /var/lib/postgresql/data/postgresql.conf.bak &&
echo 'hot_standby = on' >> /var/lib/postgresql/data/postgresql.conf &&
chown -R postgres:postgres /var/lib/postgresql/data &&
su postgres -c 'pg_ctl -D /var/lib/postgresql/data start' &&
tail -f /var/lib/postgresql/data/logfile
"
environment:
POSTGRES_USER: replicator
POSTGRES_PASSWORD_FILE: /run/secrets/replica_password
secrets:
- replica_password
volumes:
- postgres_replica:/var/lib/postgresql/data
deploy:
replicas: 2
placement:
constraints:
- node.labels.db == replica
secrets:
db_password:
external: true
replica_password:
external: true
volumes:
postgres_data:
postgres_replica:
La stack example-voting-app
Cloner l'application
example-voting-appici : https://github.com/dockersamples/example-voting-appLire le schéma d'architecture de l'app
example-voting-appsur Github.Lire attentivement le fichier
docker-stack.yml. Ce sont des fichiers Docker Compose classiques avec différentes options liées à un déploiement via Swarm. Quelles options semblent spécifiques à Docker Swarm ? Ces options permettent de configurer des fonctionnalités d'orchestration.
Avec
docker swarm init, transformer son installation Docker en une installation Docker compatible avec Swarm. Lisez attentivement le message qui vous est renvoyé.Déployer la stack du fichier
docker-stack.yml:docker stack deploy --compose-file docker-stack.yml votedocker stack lsindique 6 services pour la stackvote. Observer également l'output dedocker stack ps voteet dedocker stack services vote. Qu'est-ce qu'un service dans la terminologie de Swarm ?Accéder aux différents front-ends de la stack grâce aux informations contenues dans les commandes précédentes. Sur le front-end lié au vote, actualiser plusieurs fois la page. Que signifie la ligne
Processed by container ID […]? Pourquoi varie-t-elle ?Scaler la stack en ajoutant des replicas du front-end lié au vote avec l'aide de
docker service --help. Accédez à ce front-end et vérifier que cela a bien fonctionné en actualisant plusieurs fois.
puis spécifier quelques options d'orchestration exclusives à Docker Swarm : que fait
mode: global? N'oubliez pas de redéployer votre Compose file.Avec Portainer ou avec docker-swarm-visualizer, explorer le cluster ainsi créé.
Opérer sur le cluster
Trouver la commande pour déchoir et promouvoir l'un de vos nœuds de
manageràworkeret vice-versa.Puis sortir un nœud du cluster (
drain) :docker node update --availability drain <node-name>
Installons Portainer
Portainer est une interface web de base pour gérer un cluster docker.
docker service create \
--name portainer \
--publish 9000:9000 \
--constraint 'node.role == manager' \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
portainer/portainer \
-H unix:///var/run/docker.sock
- Listez les services
- Inspectez le service portainer avec l'option --pretty
- Ouvrez la page avec
firefox http://$(docker-machine ip <machine_manager>):9000-->
Facultatif : déployer une nouvelle image pour un service de example-voting-app
Tenter :
- de rebuild les différentes images à partir de leur Dockerfile,
- puis d'éditer votre fichier Docker Compose (
docker-stack.yml) pour qu'il se base sur l'image que vous venez de reconstruire. - et de déployer ces images, potentiellement en faisant varier les options de
update_config:. Un message de warning devrait apparaître, pourquoi ?
Facultatif : Gérer les données sensibles dans Swarm avec les secrets Docker
créer un secret avec :
echo "This is a secret" | docker secret create my_secret_datapermettre l'accès au secret via :
docker service create --name monservice --secret my_secret_data redis:alpinelire le contenu secret dans :
/var/run/my_secret_data
Facultatif : cluster Postgres haute dispo et Swarm
Objectif : Déployer un cluster postgres répliqué avec Swarm
Indice : https://www.crunchydata.com/blog/an-easy-recipe-for-creating-a-postgresql-cluster-with-docker-swarm
Conclusion
Docker swarm est une solution "out of the box" pour monter un cluster Docker.
C'est simple et facile à mettre en place.
Mais cet outil est mal adaptée pour une plateforme mutualisée sur le long terme.
Elle ne permet pas d'obtenir immédiatement une compartimentation logique, des gestions d'utilisateurs, des comportements avancés tels que les permettent Kubernetes.