Aller au contenu
Conteneurs & Orchestration medium

Orchestrez vos conteneurs avec Docker Swarm

44 min de lecture

logo docker-swarm

Docker Swarm est le mode d'orchestration natif de Docker. En une seule commande (docker swarm init), vous transformez votre Docker Engine en un cluster capable de distribuer des conteneurs sur plusieurs machines, d'assurer la haute disponibilité et de gérer automatiquement les pannes. Contrairement à Kubernetes qui nécessite une installation séparée, Swarm est intégré à Docker et utilise les mêmes fichiers docker-compose.yml que vous connaissez déjà.

  • Architecture Swarm : comprendre les nœuds managers et workers, l'algorithme Raft
  • Services et tâches : déployer des applications avec état désiré et réplication
  • Réseaux overlay : faire communiquer vos conteneurs à travers plusieurs hôtes
  • Secrets et configs : gérer vos données sensibles de manière sécurisée
  • Déploiement avancé : rolling updates, contraintes de placement, healthchecks
  • Haute disponibilité : quorum, tolérance aux pannes, bonnes pratiques production

Avant de commencer, assurez-vous d'avoir :

Docker Swarm est un outil d'orchestration de conteneurs intégré nativement à Docker. Il permet de regrouper plusieurs machines Docker (appelées nœuds) en un cluster unique, géré comme une seule entité.

Le choix se joue rarement sur les fonctionnalités : il se joue sur le coût d'entrée. Swarm réutilise le vocabulaire Docker que vous maîtrisez déjà (image, volume, réseau, docker-compose.yml), là où Kubernetes impose un modèle d'objets complet à apprendre avant le premier déploiement. Le tableau ci-dessous résume les écarts qui pèsent le plus dans une décision d'équipe.

CritèreDocker SwarmKubernetes
InstallationIntégré à DockerInstallation séparée complexe
Courbe d'apprentissageDouce (commandes Docker)Raide (nouveaux concepts)
Fichiers de configdocker-compose.ymlManifests YAML spécifiques
Cas d'usagePetits/moyens clustersGrands clusters, multi-cloud
FonctionnalitésEssentiellesTrès complètes

La question est légitime tant l'écosystème pousse vers Kubernetes. La réponse est oui : Mirantis, qui maintient Swarm depuis le rachat de Docker Enterprise, en garantit le support jusqu'en 2030, et le projet SwarmKit reste activement développé. Swarm n'est pas un projet mort, mais une brique stabilisée : peu de nouveautés, une maintenance assurée et un vrai créneau pour les petites équipes, le homelab et l'edge, là où la complexité de Kubernetes ne se justifie pas.

Le point de vigilance de 2026 vient de Docker Engine v29, qui introduit des ruptures touchant Swarm en priorité : les plugins de volume V1 (NFS/iSCSI hérités) sont rejetés, et dans un cluster mixte mélangeant v29 et versions antérieures, le trafic overlay chiffré peut s'arrêter silencieusement. La règle est de migrer tous les nœuds en une seule fois. Si vous pilotez Swarm via Portainer, mettez-le à jour vers une version LTS récente avant de basculer en v29.

Un cluster Swarm est composé de deux types de nœuds avec des rôles distincts. Cette séparation détermine tout le reste : qui stocke l'état du cluster, qui accepte vos commandes, qui exécute réellement les conteneurs. Un même serveur peut cumuler les deux rôles, ce qui explique qu'un cluster de test à un seul nœud fonctionne parfaitement. Le schéma ci-dessous montre comment une demande de déploiement descend des managers vers les workers.

Architecture d'un cluster Docker Swarm avec managers, workers et répartition des tâches

Pour fonctionner, un cluster Swarm a besoin d'au moins un nœud manager. Ce manager assure trois fonctions : il décide où placer les conteneurs, maintient l'état du cluster et expose l'API pour recevoir vos commandes. Les nœuds workers sont les exécutants : ils reçoivent les instructions du manager et font tourner les conteneurs.

Concrètement, quand vous tapez docker service create, votre commande arrive sur un manager qui décide sur quel(s) nœud(s) lancer les conteneurs, puis envoie les ordres aux workers concernés.

TypeRôleResponsabilités
ManagerDécide et coordonneOrchestration, planification, API, stockage de l'état (Raft)
WorkerExécute les tâchesExécution des conteneurs

Dans Swarm, vous ne déployez pas des conteneurs directement, mais des services :

  • Service : Définition déclarative avec un état désiré (image, réplicas, ports, ressources). Swarm s'assure que l'état réel correspond toujours à cet état désiré.
  • Tâche (Task) : Instance d'un service = 1 conteneur. Si vous demandez 3 réplicas, Swarm crée 3 tâches.

Exemple : Un service web avec 3 réplicas crée 3 tâches (web.1, web.2, web.3), chacune étant un conteneur nginx.

Relation entre Service, Tasks et Conteneurs dans Docker Swarm

Docker Swarm utilise l'algorithme de consensus Raft pour synchroniser l'état du cluster entre les managers. Un algorithme de consensus garantit que plusieurs machines se mettent d'accord sur une même version de la vérité, même si certaines tombent en panne ou répondent en retard. C'est ce qui permet à Swarm de survivre à la perte d'un manager sans perdre la liste de vos services.

  1. Un leader est élu parmi les managers
  2. Toutes les modifications passent par le leader
  3. Le leader réplique les changements aux followers
  4. Les décisions nécessitent un quorum (majorité)

Le quorum est le nombre minimum de managers qui doivent être disponibles pour que le cluster puisse prendre des décisions. C'est une notion fondamentale pour comprendre la haute disponibilité de Swarm.

Prenons un exemple concret : avec 3 managers, le quorum est de 2. Si un manager tombe en panne, les 2 restants peuvent continuer à fonctionner. Mais si 2 managers tombent, le dernier ne peut plus rien décider seul et le cluster devient indisponible pour les opérations d'écriture (création de services, scaling...).

Le calcul est simple : quorum = (N/2) + 1 où N est le nombre de managers.

ManagersQuorumPannes tolérées
110
220 ⚠️
321
532
743

Notez que 2 managers ne tolèrent aucune panne (quorum = 2, donc les 2 doivent être up). C'est pourquoi Docker recommande 3 managers minimum en production pour avoir une vraie tolérance aux pannes.

L'activation du swarm mode ne demande aucune installation : le binaire est déjà présent dans votre Docker Engine. Une seule commande bascule le moteur en mode cluster, génère l'autorité de certification interne et fait du nœud courant le premier manager. L'opération est réversible avec docker swarm leave --force, qui détruit l'état du cluster local.

  1. Initialiser le cluster

    Transformez votre Docker Engine en nœud manager :

    Fenêtre de terminal
    docker swarm init

    Résultat attendu :

    Swarm initialized: current node (abc123) is now a manager.
    To add a worker to this swarm, run:
    docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377
    To add a manager to this swarm, run 'docker swarm join-token manager'
  2. Vérifier l'état du cluster

    Fenêtre de terminal
    docker node ls

    Sortie :

    ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
    abc123 * server1 Ready Active Leader 24.0.7
    • * indique le nœud courant
    • Leader indique le manager actif pour Raft
    • Active signifie que le nœud accepte des tâches

Pour ajouter des nœuds au cluster, récupérez d'abord les tokens :

Fenêtre de terminal
# Token pour ajouter un worker
docker swarm join-token worker
# Token pour ajouter un manager
docker swarm join-token manager

Puis sur la nouvelle machine :

Fenêtre de terminal
docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377

Si vos nœuds sont sur des machines différentes (ce qui est le cas en production), ils doivent pouvoir communiquer entre eux. Swarm utilise trois ports distincts, chacun avec un rôle précis :

  • Le port 2377 est le plus important : c'est par là que les managers communiquent entre eux (algorithme Raft) et que vous envoyez vos commandes docker. C'est l'API de gestion du cluster.
  • Le port 7946 sert aux échanges d'informations entre tous les nœuds (managers et workers). C'est le protocole "gossip" qui permet aux nœuds de se découvrir et de partager leur état.
  • Le port 4789 transporte le trafic réseau entre vos conteneurs sur différents hôtes. C'est la technologie VXLAN qui crée un réseau virtuel au-dessus de votre réseau physique.
PortProtocoleUsage
2377TCPCommunication de gestion (API Swarm, Raft)
7946TCP + UDPCommunication entre nœuds (gossip)
4789UDPTrafic overlay (VXLAN)

Si vous utilisez un firewall comme ufw ou firewalld, pensez à ouvrir ces ports entre vos nœuds avant de créer votre cluster.

Le service est l'unité de travail de Swarm : vous ne lancez plus un conteneur, vous déclarez combien d'instances doivent tourner et sur quelle image. Swarm compare en permanence cet état désiré à l'état réel et corrige l'écart, qu'un conteneur ait planté ou qu'un nœud entier soit tombé. Les commandes de cette section (create, ls, scale, ps) forment le socle du travail quotidien sur un cluster.

La commande docker service create crée un service avec l'état désiré :

Fenêtre de terminal
docker service create \
--name web \
--replicas 3 \
-p 80:80 \
nginx

Cette commande :

  • Crée un service nommé web
  • Lance 3 conteneurs nginx (réplicas)
  • Publie le port 80 sur tous les nœuds

Vérification :

Fenêtre de terminal
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
abc123 web replicated 3/3 nginx:latest *:80->80/tcp

Swarm propose deux modes de déploiement qui répondent à des besoins différents.

Le mode replicated (par défaut) est celui que vous utiliserez le plus souvent : vous demandez un nombre précis de conteneurs, et Swarm les répartit intelligemment sur les nœuds disponibles. Par exemple, "je veux 5 instances de mon API", Swarm décide sur quels serveurs les placer.

Le mode global est plus spécifique : il lance exactement une instance par nœud du cluster. C'est idéal pour les agents de monitoring comme Prometheus Node Exporter, les collecteurs de logs comme Fluentd, ou tout service qui doit tourner sur chaque machine. Quand un nouveau nœud rejoint le cluster, il reçoit automatiquement sa propre instance.

ModeDescriptionCas d'usage
replicated (défaut)Nombre fixe de réplicasApplications web, APIs
global1 tâche par nœudMonitoring, log collectors
Fenêtre de terminal
# Service global (1 instance par nœud)
docker service create --name node_exporter --mode global prom/node-exporter

Avec le mode global, pas besoin de spécifier --replicas : le nombre de conteneurs correspond toujours au nombre de nœuds dans le cluster.

Deux syntaxes équivalentes pour scaler :

Fenêtre de terminal
# Syntaxe courte (plusieurs services possibles)
docker service scale web=5 api=3
# Syntaxe longue (combinable avec d'autres options)
docker service update --replicas 5 web

Vérifier le scaling :

Fenêtre de terminal
docker service ps web
ID NAME IMAGE NODE STATE CURRENT STATE
abc1 web.1 nginx server1 Running Running 5 minutes ago
abc2 web.2 nginx server2 Running Running 2 minutes ago
abc3 web.3 nginx server1 Running Running 2 minutes ago
abc4 web.4 nginx server3 Running Running 30 seconds ago
abc5 web.5 nginx server2 Running Running 30 seconds ago

Docker Swarm utilise le même format de fichier déclaratif que Docker Compose. Vous pouvez réutiliser vos fichiers docker-compose.yml avec quelques adaptations.

Bien que les fichiers soient au même format YAML, certaines directives fonctionnent différemment selon que vous utilisez docker compose up (environnement local) ou docker stack deploy (Swarm).

La différence principale concerne le build : en local, Compose peut construire vos images à la volée depuis un Dockerfile. En Swarm, c'est impossible car les workers n'ont pas accès à votre code source, vous devez utiliser des images déjà construites et poussées dans un registry.

De même, depends_on qui garantit l'ordre de démarrage en local n'a pas de sens dans un cluster distribué où les conteneurs peuvent être sur des machines différentes. Swarm ignore cette directive.

En contrepartie, Swarm ajoute la section deploy qui permet de configurer le nombre de réplicas, les contraintes de placement sur certains nœuds, et les stratégies de mise à jour progressive.

FonctionnalitéDocker ComposeDocker Swarm
build✅ Supporté❌ Ignoré (images pré-buildées)
depends_on✅ Supporté❌ Ignoré
deploy❌ Ignoré✅ Configuration Swarm
deploy.replicas-Nombre de réplicas
deploy.placement-Contraintes de placement
deploy.update_config-Stratégie de rolling update

Cette stack à trois services rassemble tout ce qui précède : un frontal nginx répliqué, une API contrainte aux workers et une base PostgreSQL isolée sur un réseau backend. Notez le secret db_password déclaré external: true, ce qui signifie qu'il doit exister avant le déploiement.

stack.yml
services:
web:
image: nginx:1.31.3-alpine
ports:
- "80:80"
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
max_attempts: 3
networks:
- frontend
api:
image: mon-api:latest
deploy:
replicas: 2
placement:
constraints:
- node.role == worker
secrets:
- db_password
networks:
- frontend
- backend
db:
image: postgres:15
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
volumes:
- db_data:/var/lib/postgresql/data
secrets:
- db_password
networks:
- backend
networks:
frontend:
backend:
volumes:
db_data:
secrets:
db_password:
external: true

La section deploy offre de nombreuses options, regroupées en trois familles : le dimensionnement (replicas), les quotas de ressources (resources) et le comportement en cas de changement ou d'échec (update_config, restart_policy). Ce bloc est ignoré par docker compose up, il ne sert que sous docker stack deploy.

deploy:
# Nombre de conteneurs
replicas: 3
# Limites de ressources
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
# Stratégie de mise à jour
update_config:
parallelism: 2 # Conteneurs mis à jour simultanément
delay: 10s # Pause entre les lots
failure_action: rollback # rollback|pause|continue
order: start-first # start-first|stop-first
# Politique de redémarrage
restart_policy:
condition: on-failure
max_attempts: 3
window: 120s

Une stack est un groupe de services déployés et gérés ensemble à partir d'un seul fichier YAML. Elle joue pour Swarm le rôle que docker compose up joue sur une machine isolée : une commande, un fichier, un ensemble cohérent de services, réseaux et secrets. Toutes les ressources créées portent le nom de la stack en préfixe, ce qui rend la suppression complète triviale.

Le drapeau -c désigne le fichier de composition et le dernier argument donne le nom de la stack, qui servira de préfixe à toutes les ressources créées.

Fenêtre de terminal
docker stack deploy -c stack.yml ma_stack

Sortie :

Creating network ma_stack_frontend
Creating network ma_stack_backend
Creating secret ma_stack_db_password
Creating service ma_stack_web
Creating service ma_stack_api
Creating service ma_stack_db

Les services sont automatiquement préfixés par le nom de la stack (ma_stack_).

Ces quatre commandes suffisent au suivi courant ; retenez que docker stack rm supprime les services, les réseaux et les secrets de la stack, mais jamais les volumes, qui restent sur les nœuds.

Fenêtre de terminal
# Lister les stacks
docker stack ls
# Services d'une stack
docker stack services ma_stack
# Tâches d'une stack
docker stack ps ma_stack
# Supprimer une stack
docker stack rm ma_stack

Pour appliquer des modifications, relancez simplement docker stack deploy :

Fenêtre de terminal
docker stack deploy -c stack.yml ma_stack

Swarm détecte les changements et applique un rolling update automatiquement.

Les réseaux overlay permettent aux conteneurs de communiquer à travers plusieurs hôtes comme s'ils étaient sur le même réseau local. Un overlay est un réseau virtuel construit par-dessus votre réseau physique : Swarm encapsule le trafic des conteneurs dans des paquets UDP qui circulent normalement entre vos serveurs. Le résultat est qu'un conteneur peut joindre un autre conteneur par son nom de service, quel que soit le nœud qui l'héberge, sans que vous ayez à toucher au routage de votre infrastructure.

Trois mécanismes se mettent en place sans intervention de votre part dès l'initialisation du cluster.

  1. Swarm crée automatiquement le réseau ingress pour le routing mesh
  2. Chaque stack obtient un réseau par défaut
  3. Les réseaux overlay utilisent VXLAN pour l'encapsulation

Le sous-réseau est facultatif : sans --subnet, Swarm en choisit un dans sa plage par défaut, au risque d'entrer en conflit avec votre plan d'adressage existant.

Fenêtre de terminal
docker network create \
--driver overlay \
--subnet 10.0.1.0/24 \
mon_reseau

Le routing mesh est un load balancer intégré à Swarm. Quand vous publiez un port (-p 80:80) :

  1. Tous les nœuds écoutent sur ce port
  2. Le trafic est automatiquement redirigé vers un conteneur du service
  3. C'est transparent pour le client

Exemple : Avec 3 nœuds et un service web sur le nœud 2, vous pouvez accéder au service depuis n'importe quel nœud (1, 2 ou 3).

Fonctionnement du routing mesh : accès au service depuis n'importe quel nœud du cluster

Swarm offre deux façons de publier les ports de vos services, avec des comportements très différents.

Le mode ingress (par défaut) active le routing mesh : le port est ouvert sur tous les nœuds du cluster, même ceux qui n'exécutent pas de conteneur pour ce service. C'est pratique car vous pouvez pointer votre load balancer externe vers n'importe quel nœud, et Swarm redirigera le trafic vers un conteneur actif.

Le mode host bind le port uniquement sur les nœuds où le conteneur tourne réellement. C'est utile dans deux cas : quand vous avez besoin de connaître l'IP réelle du client (le routing mesh fait du NAT qui masque l'IP source), ou pour des performances maximales en évitant la couche de routage supplémentaire.

ModeDescriptionCas d'usage
ingress (défaut)Port publié sur tous les nœuds via routing meshApplications web standard
hostPort bindé uniquement sur les nœuds où la tâche tourneBypass du mesh, IP client réelle
ports:
- target: 80
published: 80
mode: host # ou ingress (défaut)

Attention avec le mode host : si vous avez 3 réplicas mais seulement 2 nœuds, le 3ème conteneur ne pourra pas démarrer (conflit de port).

Pour un service qui ne doit pas être exposé (ex: base de données) :

  1. Ne publiez pas de port
  2. Les autres services y accèdent via le DNS Swarm
services:
db:
image: postgres:15@sha256:74e110c41804365e3915fcc09d5e7a1eff50161aaa94d5da0e58e0cd75ae509c
# Pas de section "ports"
networks:
- backend
api:
image: mon-api
environment:
DATABASE_URL: postgres://db:5432/app # DNS interne
networks:
- backend

Le nom du service (db) devient un hostname résolvable par tous les services sur le même réseau.

Les secrets Docker Swarm stockent des données sensibles (mots de passe, clés d'API, certificats) sans jamais les écrire sur le disque des workers. Ils remplacent les variables d'environnement, qui apparaissent en clair dans docker inspect et dans les journaux. Quatre propriétés distinguent un secret Swarm d'un simple fichier de configuration.

  • Chiffrés au repos dans le store Raft des managers
  • Chiffrés en transit via TLS mutuel entre les nœuds
  • Accessibles uniquement aux services Swarm autorisés (pas aux conteneurs standalone)
  • Montés en tmpfs (mémoire) dans /run/secrets/

Un secret est immuable : pour changer sa valeur, il faut en créer un nouveau puis mettre à jour les services qui l'utilisent. Le tiret final indique à Docker de lire la valeur sur l'entrée standard, ce qui évite de laisser traîner un fichier en clair.

Fenêtre de terminal
# Depuis un fichier
docker secret create db_password password.txt
# Depuis stdin (plus sûr)
echo "mon_mot_de_passe" | docker secret create db_password -
# Ou avec un fichier
printf "mon_mot_de_passe" | docker secret create db_password -

Le drapeau --secret accorde au service l'accès à un secret déjà créé ; un service qui ne le déclare pas ne peut pas le lire, même s'il tourne sur le même nœud.

Fenêtre de terminal
docker service create \
--name api \
--secret db_password \
mon-api

Dans le conteneur, le secret est disponible dans /run/secrets/db_password.

La forme longue (source, target, mode) sert quand l'application attend le fichier à un emplacement précis ou exige des permissions restreintes. La clé external: true suppose le secret déjà créé à la main, tandis que file: le fait créer par Swarm au moment du déploiement.

services:
api:
image: mon-api
secrets:
- db_password
- source: api_key
target: /app/config/api.key
mode: 0400
secrets:
db_password:
external: true # Secret déjà créé
api_key:
file: ./secrets/api.key # Créé au déploiement

Un cluster vit : des machines partent en maintenance, d'autres rejoignent le groupe, un worker devient manager. Toutes ces opérations passent par la commande docker node, exécutable uniquement depuis un manager. Les trois gestes à connaître sont l'inspection, le changement de disponibilité avant une intervention, et le changement de rôle.

docker node ls donne la vue d'ensemble ; --pretty reformate la sortie JSON de inspect en texte lisible, avec les labels et les ressources du nœud.

Fenêtre de terminal
# Lister les nœuds
docker node ls
# Détails d'un nœud
docker node inspect server1 --pretty

Chaque nœud Swarm possède un état de disponibilité qui contrôle s'il peut recevoir des tâches. Comprendre ces trois états est essentiel pour gérer correctement la maintenance de votre cluster.

L'état active est le fonctionnement normal : le nœud accepte de nouvelles tâches et celles qu'il exécute continuent de tourner.

L'état pause est utile pour une maintenance légère : le nœud garde ses tâches existantes mais le scheduler ne lui en assignera plus de nouvelles. C'est pratique si vous voulez empêcher temporairement un nœud de recevoir du travail sans perturber ce qui tourne déjà.

L'état drain est le plus radical : Swarm évacue toutes les tâches du nœud vers d'autres nœuds disponibles. Utilisez-le avant un reboot, une mise à jour système, ou toute opération qui nécessite d'arrêter le nœud.

ÉtatDescriptionUsage
activeAccepte de nouvelles tâchesFonctionnement normal
pausePas de nouvelles tâches, tâches existantes continuentMaintenance légère
drainÉvacue toutes les tâches vers d'autres nœudsMaintenance lourde

La séquence ci-dessous évite toute coupure de service : le passage en drain déclenche la replanification des tâches avant que vous ne touchiez à la machine. Sur un manager, pensez à vérifier que le quorum reste atteint pendant l'opération.

  1. Mettre le nœud en drain

    Fenêtre de terminal
    docker node update --availability drain server1

    Swarm replanifie automatiquement les tâches sur d'autres nœuds.

  2. Effectuer la maintenance (reboot, mise à jour Docker, etc.)

  3. Réactiver le nœud

    Fenêtre de terminal
    docker node update --availability active server1

Le rôle d'un nœud se change à chaud, sans arrêter les conteneurs qu'il héberge : un worker promu rejoint le groupe Raft et reçoit une copie de l'état du cluster.

Fenêtre de terminal
# Promouvoir un worker en manager
docker node promote server2
# Rétrograder un manager en worker
docker node demote server3

Docker Swarm permet des rolling updates contrôlés : au lieu de tout arrêter puis tout relancer, il remplace les tâches par petits lots et observe le résultat entre chaque lot. Si le taux d'échec dépasse le seuil que vous avez fixé, il stoppe la manœuvre ou revient à la version précédente. Cette mécanique se pilote indifféremment depuis le fichier de stack ou depuis la ligne de commande.

Les cinq paramètres qui suivent se lisent ensemble : parallelism fixe la taille du lot, delay et monitor le temps d'observation, max_failure_ratio le seuil de déclenchement de failure_action.

deploy:
update_config:
parallelism: 2 # Tâches mises à jour en parallèle
delay: 10s # Pause entre les lots
failure_action: rollback # En cas d'échec
monitor: 30s # Temps de surveillance après update
max_failure_ratio: 0.1 # Ratio d'échecs toléré
order: start-first # Démarrer avant d'arrêter

Les mêmes réglages existent en options de docker service update ; changer l'image dans la même commande déclenche immédiatement la mise à jour progressive.

Fenêtre de terminal
docker service update \
--update-parallelism 2 \
--update-delay 10s \
--update-failure-action rollback \
--image nginx:1.25 \
web

Avec failure_action: rollback, Swarm annule automatiquement si trop de tâches échouent.

Rollback manuel :

Fenêtre de terminal
docker service rollback web

Pour qu'un cluster Swarm soit vraiment résilient en production, quelques règles simples font toute la différence.

La première concerne le nombre de managers : toujours impair (3 ou 5) pour optimiser le quorum. Trois managers tolèrent une panne, cinq en tolèrent deux. Docker ne fixe pas de limite, mais plus vous ajoutez de managers, plus les écritures Raft sont lentes.

Ensuite, répartissez vos managers géographiquement : sur différents racks, différentes zones de disponibilité, voire différents datacenters. Si tous vos managers sont sur le même rack et qu'il prend feu, vous perdez tout.

Côté services, les healthchecks sont indispensables : sans eux, Swarm ne sait pas si votre application fonctionne vraiment. Un conteneur peut tourner mais être planté, le healthcheck permet de le détecter et de le remplacer automatiquement.

Enfin, configurez toujours vos rolling updates avec rollback automatique. Si une nouvelle version de votre application plante, Swarm reviendra automatiquement à la version précédente au lieu de casser tout votre service.

En résumé :

  1. Toujours un nombre impair de managers (3 ou 5 recommandés)
  2. Distribuer les managers sur différentes zones/racks
  3. Limiter le nombre de managers si les performances d'écriture comptent
  4. Utiliser des healthchecks pour détecter les services défaillants
  5. Configurer des rolling updates avec rollback automatique
  6. Monitorer le leader Raft (docker node ls)
  7. Rotater les tokens périodiquement (ex: tous les 6 mois)

Les contraintes contrôlent les tâches peuvent s'exécuter. Par défaut, Swarm place les conteneurs sur le nœud le moins chargé, sans se soucier du matériel ni de la localisation. Dès que vos machines ne sont plus interchangeables (disques SSD sur certaines, données réglementées cantonnées à une zone, licence liée à un serveur), il faut lui dire explicitement quels nœuds sont éligibles.

Les contraintes utilisent des attributs des nœuds pour filtrer où vos conteneurs peuvent s'exécuter. Vous pouvez utiliser des attributs intégrés (rôle, hostname, ID) ou créer vos propres labels.

Les labels personnalisés sont particulièrement puissants : vous pouvez par exemple labelliser vos nœuds par zone géographique (zone=europe), par type de stockage (storage=ssd), ou par environnement (env=production). Ensuite, vous contraignez vos services à ne tourner que sur les nœuds correspondants.

La syntaxe utilise les opérateurs == (égal) et != (différent). Vous pouvez combiner plusieurs contraintes, elles doivent toutes être satisfaites pour qu'un nœud soit éligible.

ContrainteDescriptionExemple
node.roleRôle du nœudnode.role == worker
node.hostnameNom d'hôtenode.hostname == server1
node.idID du nœudnode.id == abc123
node.labels.*Labels personnalisésnode.labels.zone == europe
engine.labels.*Labels Docker Engineengine.labels.storage == ssd

Cette contrainte réserve les managers à l'orchestration : aucune tâche du service ne sera planifiée sur eux, même si le cluster manque de capacité.

deploy:
placement:
constraints:
- node.role == worker

Les labels de nœud se posent depuis un manager et sont stockés dans l'état Raft, donc conservés après un redémarrage de la machine.

Fenêtre de terminal
# Ajouter un label au nœud
docker node update --label-add zone=europe server1
# Contraindre le service
docker service create \
--name api \
--constraint 'node.labels.zone == europe' \
mon-api

Les préférences répartissent les tâches sans bloquer si impossible :

deploy:
placement:
preferences:
- spread: node.labels.zone

Sans quota, un conteneur qui fuit peut consommer toute la mémoire d'un nœud et faire tomber les services voisins. Swarm distingue deux notions souvent confondues : la réservation, qui sert au calcul de placement, et la limite, qui est appliquée par le noyau via les cgroups. Déclarer les deux est la seule façon d'obtenir à la fois un placement pertinent et un cloisonnement réel.

Les valeurs CPU s'expriment en fraction de cœur ('0.5' vaut un demi-cœur) et doivent être quotées, la mémoire en unités M ou G.

deploy:
resources:
limits:
cpus: '0.5' # 50% d'un CPU max
memory: 256M # 256 Mo max
reservations:
cpus: '0.25' # Garantit 25% d'un CPU
memory: 128M # Garantit 128 Mo

Via CLI :

Fenêtre de terminal
docker service create \
--name api \
--limit-cpu 0.5 \
--limit-memory 256M \
--reserve-cpu 0.25 \
--reserve-memory 128M \
mon-api

Les healthchecks permettent à Swarm de vérifier la santé réelle des conteneurs. Sans eux, le seul critère disponible est « le processus principal tourne encore », ce qui laisse passer une application bloquée sur une base de données injoignable ou un serveur qui répond 500 à chaque requête. Un healthcheck est une commande exécutée à intervalle régulier dans le conteneur : son code de retour décide de l'état healthy ou unhealthy. Il se déclare à trois endroits, du plus durable au plus ponctuel.

Défini dans le Dockerfile, le test suit l'image partout où elle est déployée, sans dépendre de la configuration du service.

HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
CMD curl -f http://localhost/health || exit 1

Les options --health-* surchargent le test embarqué dans l'image, ce qui dépanne quand vous ne pouvez pas reconstruire cette dernière.

Fenêtre de terminal
docker service create \
--name web \
--health-cmd "curl -f http://localhost/health || exit 1" \
--health-interval 30s \
--health-timeout 10s \
--health-retries 3 \
nginx

Le paramètre start_period est celui qui manque le plus souvent : il laisse à l'application le temps de démarrer avant que les échecs ne soient comptabilisés, ce qui évite une boucle de redémarrages sur un service lent à s'initialiser.

services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s

Une tâche n'est considérée running que si le healthcheck passe. Les tâches unhealthy sont automatiquement remplacées.

Docker Swarm utilise TLS pour sécuriser les communications. Les certificats doivent être renouvelés régulièrement.

La rotation se fait sans interruption de service, mais elle sollicite tous les nœuds : évitez de la lancer pendant un déploiement.

Fenêtre de terminal
docker swarm ca --rotate

Cette commande :

  1. Régénère le certificat CA
  2. Met à jour les certificats de tous les nœuds
  3. Les nœuds se reconnectent automatiquement

La durée de validité par défaut des certificats de nœud est de 90 jours, et le renouvellement est automatique. Elle s'exprime en heures, d'où la valeur 2160h.

Fenêtre de terminal
# Certificats valides 90 jours
docker swarm update --cert-expiry 2160h
# Vérifier la configuration
docker swarm inspect --pretty

Sur Swarm, l'erreur est rarement là où on la cherche : docker ps sur un worker ne montre rien d'utile si la tâche n'a jamais été planifiée. Le réflexe est de partir du service, de descendre vers ses tâches, puis seulement ensuite vers les logs du conteneur. La colonne ERROR de docker service ps porte presque toujours la réponse.

Le drapeau --no-trunc est indispensable : sans lui, le message d'erreur est coupé à quelques dizaines de caractères et devient illisible.

Fenêtre de terminal
# État des nœuds
docker node ls
# Services et leur état
docker service ls
# Tâches d'un service (avec historique)
docker service ps web --no-trunc
# Logs d'un service
docker service logs -f web
# Logs avec timestamp
docker service logs --since 10m --timestamps web
# Détails d'un service
docker service inspect web --pretty

Voici les problèmes que vous rencontrerez le plus souvent avec Swarm, et comment les résoudre.

Quand un service affiche 0/3 réplicas, c'est généralement que l'image n'est pas accessible. Vérifiez d'abord le nom et le tag (nginx:latest vs nginx:1.25), puis assurez-vous que vos workers peuvent accéder au registry (authentification avec docker login si nécessaire).

Une tâche en Pending signifie que Swarm ne trouve pas de nœud capable de l'exécuter. La cause la plus fréquente : vous avez défini des réservations de ressources (--reserve-memory 4G) mais aucun nœud n'a autant de mémoire disponible. Réduisez les réservations ou ajoutez des nœuds plus puissants.

L'état Rejected indique qu'une contrainte de placement n'est pas satisfaite. Par exemple, vous demandez node.labels.zone == europe mais aucun nœud n'a ce label. Utilisez docker node inspect pour voir les labels existants.

Si vous avez perdu le quorum (majorité des managers down), votre cluster ne peut plus accepter de modifications. Essayez d'abord de remettre des managers en ligne. En dernier recours, utilisez --force-new-cluster sur un manager survivant.

SymptômeCause probableSolution
Service 0/3 réplicasImage non trouvéeVérifier le nom/tag de l'image, login registry
Tâche en PendingRessources insuffisantesRéduire réservations ou ajouter des nœuds
Tâche en RejectedContrainte non satisfaiteVérifier --constraint, ajouter labels
Réseau non trouvéRéseau pas encore crééLe réseau se crée au 1er service, attendre
Perte du quorumMajorité des managers downForcer un nouveau cluster si irrécupérable

Si vous avez perdu le quorum et ne pouvez pas récupérer les managers :

Fenêtre de terminal
# Sur un manager survivant
docker swarm init --force-new-cluster

Docker Swarm est une solution d'orchestration qui brille par sa simplicité. Si vous savez utiliser Docker et Docker Compose, vous savez déjà utiliser Swarm à 80%.

Les concepts clés à retenir :

  1. Docker Swarm est natif : intégré à Docker, utilise les mêmes fichiers Compose
  2. Managers vs Workers : les managers orchestrent, les workers exécutent
  3. Raft assure la cohérence : toujours un nombre impair de managers (3 ou 5)
  4. Services = état désiré : Swarm maintient automatiquement le nombre de réplicas
  5. Overlay = communication multi-hôtes : les conteneurs communiquent comme sur un même réseau
  6. Routing mesh : tout nœud peut recevoir le trafic pour n'importe quel service
  7. Secrets chiffrés : jamais en clair, uniquement en mémoire dans le conteneur
  8. Rolling updates : déploiements progressifs avec rollback automatique

Swarm n'est pas aussi riche en fonctionnalités que Kubernetes, mais pour beaucoup de cas d'usage, sa simplicité est un avantage considérable. Commencez par Swarm pour comprendre les concepts d'orchestration, vous pourrez toujours migrer vers Kubernetes plus tard si vos besoins évoluent.

Dix questions tirées de la banque Swarm pour vérifier que les notions de quorum, de service et de routing mesh sont acquises. La note de passage est fixée à 70 %.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

10 questions
15 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn