4.1 KiB
Post-mortem — Panne provoquée : VM figée, réparation automatique
Date : 2026-10-12. Gravité : aucune (panne provoquée volontairement, sur le serveur réel, pour valider le self-healing du bloc A, semaine 6). Impact réel : nul — une seule VM de test, aucun élève.
Scénario
Une VM d'élève (3 machines du lab 08, prises du stock chaud et attribuées à
une session de test) est gelée avec virsh suspend, qui simule un noyau
planté ou un blocage matériel : le processeur virtuel s'arrête, l'agent
invité ne répond plus, mais la VM reste en mémoire (état libvirt paused).
Déroulé observé
| Heure (locale) | Événement |
|---|---|
| 21:08:00 | VM pc-a mise en pause (virsh suspend) ; routeur et pc-b intactes |
| 21:08–21:10 | Sondes automatiques (labs:surveiller-vm, chaque minute) : pc-a muette, routeur/pc-b répondent |
| ≈ 21:10 | 3 sondes ratées de suite atteintes : Nova reçoit l'ordre de redémarrage forcé (reboot --hard) sur pc-a ; routeur et pc-b jamais touchées |
| + quelques secondes | pc-a repasse de paused à running ; la sonde suivante la trouve de nouveau vivante |
| — | lab_session_machines.sante = relancee, horodatée ; les deux autres machines restent null |
Aucune intervention humaine entre la mise en pause et la réparation.
Preuve
# Avant : pc-a « running »
# Panne : virsh suspend → domstate « paused »
3 VM sondées, 1 muettes ; élèves : 1 VM relancée(s), 0 irréparable(s)
# Après : domstate « running »
3 VM sondées, 0 muettes ; élèves : 0 VM relancée(s), 0 irréparable(s)
sante = "relancee", sante_a = 2026-10-12 19:08:11
Ce qui a bien fonctionné
- La sonde (correcteur) distingue bien une VM gelée (
paused) d'une VM éteinte (shut off) et d'une VM saine : seulepc-aa été touchée, les deux autres machines de la même session n'ont jamais reçu d'action. - Le redémarrage forcé a suffi : pas besoin de reconstruire la stack Heat ni de perdre le travail de l'élève sur les deux autres machines.
- Le compteur de relances par heure a empêché une boucle : si la VM était restée muette, elle serait passée « irréparable » après 2 tentatives, pas redémarrée indéfiniment.
Ce qui a été découvert pendant le test (pas un défaut, une leçon)
Le scheduler Laravel tourne chaque minute en continu, y compris pendant
qu'on teste à la main : les appels manuels de labs:surveiller-vm se sont
mélangés avec les passages automatiques du cron. Le seuil de 3 sondes
ratées a donc été atteint plus vite qu'en comptant seulement les commandes
tapées à la main. À refaire : pour un test reproductible au chronomètre,
désactiver temporairement le cron du scheduler (ou observer uniquement les
métriques, sans lancer la commande soi-même) — noté pour le prochain test
(montée en charge, panne générale).
Un piège trouvé avant ce test, pendant le déploiement : le correcteur
n'avait pas encore été recompilé avec la sonde quand le nouveau code
Laravel a commencé à l'appeler (cron déjà actif après ansible-playbook portail.yml, avant ansible-playbook correcteur.yml). Les VM sont
apparues « muettes » quelques minutes à tort (erreur requete_invalide de
l'ancien binaire, pas une vraie panne). Correction pour la suite :
toujours déployer correcteur.yml avant portail.yml quand les deux
changent ensemble (le contraire de l'ordre suivi cette fois).
Comprendre
Un self-healing qui ne distingue pas « cette VM précise est malade » de « tout l'hôte est en panne » ferait plus de mal que de bien : redémarrer en boucle 20 VM parce que l'hyperviseur lui-même est surchargé n'aiderait en rien, et ajouterait de la charge au pire moment. La règle « toutes muettes à la fois → aucune action » (vérifiée mais non provoquée pendant ce test, seulement en test Pest) existe pour cette raison. L'autre leçon, plus générale, rejoint celle de l'étape 7 : un service qui tourne en tâche de fond (ici le scheduler, chaque minute) continue de tourner pendant qu'on observe à la main — il faut en tenir compte en testant, pas le découvrir après coup.