Lab 12.2 : Mises à jour, secrets et panne d'un nœud¶
| Durée | 90 min |
| Niveau | Autonome |
| Prérequis | Lab 12.1 : Déployer une stack (cluster de trois nœuds, fichiers compose.yaml et default.conf), cours du chapitre 12 |
| Acquis visés | AA8 |
Objectifs
- Mettre à jour un service par lots, sans interruption, puis revenir en arrière
- Déclencher une mise à jour qui échoue et observer le retour arrière automatique
- Utiliser un secret Swarm et le remplacer sans modifier l'application
- Simuler la panne d'un nœud et observer la reprise
- Constater la limite d'un volume local à un nœud
Contexte et schéma¶
Vous exploitez maintenant la stack du Lab 12.1 comme en production : nouvelle version de l'application, mot de passe à renouveler, puis panne d'une machine. Ce lab est autonome : seuls les objectifs et les critères de réussite sont donnés. Appuyez-vous sur le cours (sections 4, 6 et 7) et sur vos labs précédents. Toutes les commandes docker s'exécutent sur swarm-manager, sauf indication contraire.
flowchart LR
subgraph S["Stack tp"]
P["proxy<br/>2 répliques, workers"] --> A["app<br/>3 répliques"]
L["lecteur<br/>secret jeton"]
M["memo<br/>volume donnees, worker"]
end
| Service | Rôle dans ce lab |
|---|---|
proxy et app |
Mêmes services qu'au Lab 12.1, cibles des mises à jour |
lecteur |
Petit conteneur alpine:3.20 qui lit un secret |
memo |
Petit conteneur alpine:3.20 qui écrit un fichier dans un volume |
Ne stoppez jamais le manager
Le cluster n'a qu'un seul manager : sans lui, plus aucune commande Swarm n'est possible (chapitre 11). La panne simulée à l'étape 8 vise uniquement un worker.
Étapes¶
Étape 1 : Remettre la stack en place avec une politique de mise à jour¶
- Objectif : repartir d'un état connu, avec une stack dont la mise à jour est réglée.
- Consignes :
- Vérifiez le cluster (
docker node ls) et l'existence de la configproxy_conf(recréez-la depuisdefault.confsi elle a été supprimée). - Dans
compose.yaml, mettezappà 3 répliques, conservez la contrainte de placement du proxy sur les workers, et ajoutez àappune sectionupdate_config: un seul conteneur remplacé à la fois, 10 secondes entre deux lots, nouveau conteneur démarré avant l'arrêt de l'ancien, retour arrière automatique en cas d'échec. - Déployez la stack sous le nom
tp.
- Vérifiez le cluster (
Point de contrôle
-
docker stack services tpaffichetp_proxy(2/2) ettp_app(3/3) -
docker service inspect --pretty tp_appaffiche la politique de mise à jour voulue - Les réponses de l'application viennent de l'image
1.0
Étape 2 : Préparer la version 2.0 de l'application¶
- Objectif : disposer d'une seconde version, distinguable de la première.
- Consignes :
- Reprenez le code de l'application
qui-repond(Lab 11.2) et modifiez le texte de la réponse, de façon à ce qu'on reconnaisse la version (par exemple en y ajoutantv2). - Construisez l'image
<utilisateur>/qui-repond:2.0et publiez-la sur Docker Hub. - Ne modifiez pas la balise
1.0, qui reste disponible.
- Reprenez le code de l'application
Point de contrôle
- Les balises
1.0et2.0existent toutes deux sur Docker Hub - Un conteneur lancé depuis
2.0répond avec le nouveau texte
Étape 3 : Mettre à jour sans interruption¶
- Objectif : passer de la version 1.0 à la version 2.0 sans refuser une seule requête.
- Consignes :
- Dans un second terminal, lancez une boucle de requêtes vers un nœud, espacées d'une seconde, pendant environ une minute :
for i in $(seq 1 60); do curl -s -o /dev/null -w "%{http_code} " http://<adresse-d-un-noeud>:8080; sleep 1; done
- Pendant ce temps, passez `app` en version `2.0` **en modifiant le fichier** puis en relançant `docker stack deploy`.
- Suivez le remplacement avec `docker service ps tp_app` (répétez la commande pendant la mise à jour).
- Une fois la mise à jour terminée, envoyez quelques requêtes pour vérifier que seule la version 2.0 répond.
Point de contrôle
- La boucle n'affiche que des codes
200 - Pendant la mise à jour,
docker service ps tp_appmontre des tâches1.0arrêtées et des tâches2.0démarrées, remplacées une par une - Après la mise à jour, toutes les réponses viennent de la version 2.0
- Vous savez expliquer le rôle de
order: start-firstdans ce résultat
Étape 4 : Revenir en arrière¶
- Objectif : annuler une mise à jour réussie mais indésirable.
- Consignes :
- Revenez à la version précédente avec la commande dédiée de Swarm, sans toucher au fichier.
- Vérifiez la version qui répond et l'état de la mise à jour (
docker service inspect --pretty tp_app). - Notez ce que contient maintenant le fichier
compose.yamlet ce qui se passerait si vous relanciezdocker stack deploysans le modifier. Vérifiez votre hypothèse. - Remettez ensuite le fichier et le service en cohérence.
Point de contrôle
- Après le retour arrière, la version
1.0répond de nouveau - Vous avez constaté l'écart entre le fichier et le service, et son effet sur un nouveau déploiement
- Le fichier et le service décrivent à nouveau la même version
Étape 5 : Provoquer une mise à jour qui échoue¶
- Objectif : observer le retour arrière automatique.
- Consignes :
- Mettez à jour
appvers une image qui n'existe pas (une balise inexistante de votre dépôt), avecdocker service update --image. - Observez
docker service ps tp_appetdocker service inspect --pretty tp_apppendant quelques dizaines de secondes. - Pendant ce temps, vérifiez avec quelques requêtes que l'application continue de répondre.
- Mettez à jour
Point de contrôle
- Les nouvelles tâches échouent (image introuvable) et la mise à jour est annulée sans intervention
- L'état de la mise à jour (
UpdateStatus) mentionne un retour arrière - Le service est de nouveau à
3/3avec la version précédente et n'a pas cessé de répondre - Vous savez expliquer quel paramètre du fichier a déclenché ce comportement
Étape 6 : Utiliser un secret¶
- Objectif : fournir une valeur sensible à un service sans la mettre dans le fichier.
- Consignes :
- Créez un secret
jetonà partir de la valeur de votre choix, lue sur l'entrée standard (jamais dans le fichier ni dans la ligne de commande d'un service). - Ajoutez au fichier le service
lecteur: imagealpine:3.20, une seule réplique, commandesleep 3600, avec le secretjeton(déclaréexternal: true). - Déployez, puis lisez la valeur depuis le conteneur du service (repérez le nœud avec
docker service ps tp_lecteur, puisdocker execsur ce nœud). - Vérifiez ce que montrent
docker secret inspect jetonetdocker service inspect tp_lecteur: retrouvez-vous la valeur ?
- Créez un secret
Point de contrôle
- Le fichier
/run/secrets/jetondu conteneur contient la valeur choisie - Ni
docker secret inspectnidocker service inspectn'affichent la valeur - Le fichier
compose.yamlne contient pas la valeur
Étape 7 : Remplacer le secret¶
- Objectif : changer la valeur sans modifier l'application ni le chemin du fichier.
- Consignes :
- Essayez de supprimer le secret
jetonpendant qu'il est utilisé : notez le message. - Créez un secret
jeton_v2avec une nouvelle valeur. - Mettez à jour le service
tp_lecteurpour retirerjetonet ajouterjeton_v2, de façon que le conteneur lise toujours/run/secrets/jeton. Consultez l'aide dedocker service updatepour les options de secrets (--secret-rm,--secret-add, et le champtarget). - Vérifiez la nouvelle valeur dans le conteneur, puis supprimez l'ancien secret.
- Modifiez enfin le fichier pour qu'il décrive cet état.
- Essayez de supprimer le secret
Point de contrôle
- La suppression d'un secret utilisé est refusée
- Le conteneur lit la nouvelle valeur dans
/run/secrets/jeton - L'ancien secret est supprimé,
docker secret lsn'affiche plus quejeton_v2 - Le fichier de stack est cohérent avec le service
Ce que montre cette étape
Un secret est immuable : on le remplace par un nouvel objet, et le service est recréé pour le recevoir. Le choix d'un target fixe évite de modifier l'application.
Étape 8 : Simuler la panne d'un worker¶
- Objectif : observer la reprise des tâches et la limite des volumes locaux.
- Consignes :
- Ajoutez au fichier le service
memo: imagealpine:3.20, une réplique, limité aux workers, avec un volume nommédonneesmonté sur/data, et la commande suivante (qui n'écrit la date dans le fichier qu'à la première exécution puis l'affiche) :
- Ajoutez au fichier le service
- Déployez, repérez le worker qui héberge la tâche et lisez la note avec `docker service logs tp_memo`. **Relevez la date.**
- Sur **ce worker** (pas sur le manager), arrêtez Docker :
- Depuis le manager, observez pendant une à deux minutes `docker node ls`, `docker service ps tp_memo` et `docker stack services tp`.
- Lisez de nouveau les journaux de `tp_memo` et comparez la date avec celle relevée.
- Vérifiez que l'application répond toujours par les nœuds restants.
Point de contrôle
- Le nœud arrêté passe à l'état
Down - Les tâches qui s'y trouvaient (
memo, et celles deproxyouappéventuellement) sont recréées sur les nœuds restants - La note affiche une autre date : le fichier a été recréé, car le volume est resté sur le nœud arrêté
- L'application continue de répondre
Étape 9 : Rétablir le nœud¶
- Objectif : observer le retour du nœud et le devenir des tâches et des données.
- Consignes :
- Redémarrez Docker sur le worker arrêté :
sudo systemctl start docker. - Observez
docker node lspuisdocker service ps tp_memoetdocker stack ps tp. - Sur le worker rétabli, listez les volumes (
docker volume ls) et lisez le fichier du volumetp_donneesavec un conteneur temporairealpine:3.20(voir le Lab 5.1). - Observez si Swarm redéplace les tâches vers ce nœud de lui-même.
- Redémarrez Docker sur le worker arrêté :
Point de contrôle
- Le nœud repasse à l'état
Ready - Les tâches déplacées pendant la panne ne reviennent pas d'elles-mêmes sur ce nœud
- L'ancien volume
tp_donneesexiste toujours sur ce nœud, avec la première date - Vous savez expliquer pourquoi la tâche
memoa perdu ses données à l'étape 8
Étape 10 : Dresser le bilan¶
- Objectif : classer les pannes et les remèdes rencontrés.
- Consignes : complétez le tableau à partir de ce que vous avez observé.
| Situation | Réaction de Swarm | Ce qu'il reste à faire à l'exploitant |
|---|---|---|
| Mise à jour réussie | ||
| Mise à jour échouée | ||
| Secret à changer | ||
| Nœud arrêté | ||
| Service avec données locales |
Point de contrôle
- Chaque ligne est complétée avec vos propres observations
Questions de réflexion¶
Pourquoi le retour arrière manuel a-t-il créé un écart entre le fichier et le service ?
docker service rollback modifie le service, pas le fichier. Le fichier reste la référence de l'état désiré : au prochain docker stack deploy, Swarm rétablit la version qu'il décrit. Après un retour arrière, il faut corriger le fichier.
Pourquoi l'application n'a-t-elle pas été interrompue pendant la mise à jour de l'étape 3 ?
Swarm remplace les tâches une par une et, avec start-first, démarre la nouvelle avant d'arrêter l'ancienne : le service ne descend jamais sous sa capacité, et le proxy joint toujours des tâches disponibles.
Quelle différence entre un secret et une variable d'environnement ?
Le secret est chiffré dans le cluster, transmis aux seuls nœuds concernés et monté en mémoire dans un fichier ; une variable d'environnement apparaît dans la configuration du service et dans les inspections.
Pourquoi les tâches ne reviennent-elles pas d'elles-mêmes sur le nœud rétabli ?
Swarm ne déplace pas des tâches qui fonctionnent déjà ailleurs : un redéploiement forcé du service serait nécessaire pour les répartir de nouveau.
Que faudrait-il pour que le service memo conserve ses données malgré la panne du nœud ?
Soit le fixer à un nœud précis (en acceptant que ce nœud soit un point de défaillance), soit utiliser un stockage partagé entre les nœuds ou un service de données hors du cluster (section 5.1 du cours).
Dépannage¶
| Symptôme | Pistes |
|---|---|
secret not found au déploiement |
Le secret n'a pas été créé avant docker stack deploy, ou son nom diffère dans le fichier |
secret ... is in use by the following service |
Retirez-le d'abord du service (--secret-rm) |
docker secret create reste en attente |
Avec -, la commande lit l'entrée standard : fournissez la valeur avec printf '...' \| |
| La mise à jour reste bloquée ou en pause | docker service inspect --pretty tp_app : lisez UpdateStatus ; corrigez la cause puis relancez, ou utilisez docker service rollback |
| Aucun retour arrière automatique | Vérifiez que failure_action: rollback figure bien dans le fichier déployé |
tp_app toujours en 1.0 après le déploiement |
La balise du fichier n'a pas changé, ou l'image 2.0 n'est pas publiée |
Le nœud n'apparaît pas Down |
Patientez quelques dizaines de secondes ; vérifiez que Docker est bien arrêté (systemctl status docker sur le worker) |
docker.socket relance Docker |
Arrêtez bien les deux unités : docker et docker.socket |
memo n'est pas recréée |
Vérifiez que la contrainte autorise l'autre worker et que celui-ci est Ready |
| Fichier de stack refusé | Validez la syntaxe avec docker compose -f compose.yaml config |
Nettoyage et reprise¶
Les volumes tp_donnees restent sur les nœuds où ils ont été créés : sur chaque nœud concerné, supprimez-les avec docker volume rm tp_donnees une fois les tâches arrêtées. Si l'ancien secret jeton existe encore, supprimez-le aussi. Conservez le cluster : le mini-projet de la partie y sera déployé. Vous pouvez supprimer les images 2.0 et les balises de test de Docker Hub si vous le souhaitez.
Retour au chapitre¶
Chapitre 12 : Swarm : stacks et exploitation · Retour à l'index de la partie 3