80 lines
4.1 KiB
Markdown
80 lines
4.1 KiB
Markdown
|
|
# 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 : seule `pc-a` a é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.
|