93 lines
4.3 KiB
Markdown
93 lines
4.3 KiB
Markdown
# Runbook — Self-healing des VM (bloc A, semaine 6)
|
|
|
|
## Principe
|
|
|
|
Chaque minute, le scheduler Laravel (compte `www-data`, déjà en place depuis
|
|
l'étape 10) exécute `php artisan labs:surveiller-vm`, implémenté par
|
|
`App\Services\Labs\SurveillanceVm`.
|
|
|
|
Pour chaque VM (stock chaud et sessions d'élèves actives), il demande au
|
|
service **correcteur** (sur l'hyperviseur) une **sonde de santé** :
|
|
état libvirt du domaine (`virsh domstate`) et `guest-ping` de l'agent invité
|
|
QEMU. Rien n'est exécuté dans la VM — c'est une requête distincte de la
|
|
correction d'un lab (`{instance, sante: true}` plutôt que
|
|
`{instance, lab, verification}`), refusée si elle porte les deux à la fois.
|
|
|
|
- **VM du stock muette 2 sondes de suite** (`stock:echecs` compteur Redis
|
|
`sante:muette:{instance}`) : sa stack est retirée du stock chaud et
|
|
supprimée. `labs:remplir-stock` la remplace à la prochaine minute. Aucun
|
|
élève ne reçoit jamais une VM défaillante.
|
|
- **VM d'élève muette 3 sondes de suite** : redémarrage forcé par Nova
|
|
(`reboot --hard`, ou démarrage si elle est éteinte), au plus **2 fois par
|
|
heure**. Au-delà, la VM est marquée **irréparable** : le prof la voit dans
|
|
la salle d'attente (« ne répond plus malgré deux redémarrages automatiques.
|
|
L'équipe technique est prévenue. »), et doit relancer le lab de cet élève
|
|
à la main.
|
|
|
|
## Garde-fous
|
|
|
|
- **Délai de grâce** de 3 minutes après la création d'une VM : elle démarre
|
|
encore, on ne la sonde pas (correspond au p95 de démarrage mesuré à
|
|
l'étape 13, 75 s, avec large marge).
|
|
- **Correcteur injoignable** : aucune action (on ne devine jamais l'état
|
|
d'une VM qu'on n'a pas pu sonder).
|
|
- **Panne générale** : si *toutes* les VM sondées sont muettes à la fois
|
|
(seuil : au moins 3 VM), c'est probablement l'hyperviseur qui est en
|
|
cause, pas les VM une par une — aucune relance n'est tentée (une rafale de
|
|
redémarrages ne répare pas un hôte en panne, et l'alourdirait). Couvert
|
|
par les alertes existantes (`DisqueSature`, `MemoireSaturee`,
|
|
`ServiceOpenStackArrete`), pas par ce mécanisme.
|
|
|
|
## Métriques (Prometheus, collecteur textfile)
|
|
|
|
Fichier `/var/lib/node_exporter/textfile/sante_vm.prom` (écrit par
|
|
`www-data`, lu par `node_exporter`) :
|
|
|
|
| Métrique | Sens |
|
|
|---|---|
|
|
| `syllabus_vm_surveillance_timestamp` | dernier passage |
|
|
| `syllabus_vm_sondees` / `syllabus_vm_muettes` | VM sondées / muettes à ce passage |
|
|
| `syllabus_vm_irreparables` | VM d'élèves toujours muettes après les relances |
|
|
| `syllabus_vm_panne_generale` | 1 si aucune action n'a été tentée (panne générale ou correcteur injoignable) |
|
|
| `syllabus_vm_reparations_total{type=...}` | compteur cumulé : `relance_session`, `retrait_stock`, `abandon` |
|
|
|
|
Alertes à ajouter avant le pilote (pas encore faites, voir `docs/dette.md`) :
|
|
`syllabus_vm_panne_generale == 1` pendant plus de 5 min, et
|
|
`syllabus_vm_irreparables > 0`.
|
|
|
|
## Lancer une vérification manuellement
|
|
|
|
```
|
|
ssh paillasse
|
|
cd /var/www/portail
|
|
sudo -u www-data HOME=/tmp php8.3 artisan labs:surveiller-vm
|
|
cat /var/lib/node_exporter/textfile/sante_vm.prom
|
|
```
|
|
|
|
## Provoquer une panne pour tester (ne jamais sur une vraie classe)
|
|
|
|
```
|
|
# 1. Prendre une VM réelle (une session de test, ou du stock) et la geler
|
|
# comme un noyau planté (le CPU virtuel s'arrête, l'agent ne répond plus) :
|
|
ssh paillasse "sudo docker exec nova_libvirt virsh suspend <uuid-instance>"
|
|
|
|
# 2. Observer (plusieurs minutes, ou plusieurs appels manuels) :
|
|
ssh paillasse "cd /var/www/portail && sudo -u www-data HOME=/tmp php8.3 artisan labs:surveiller-vm"
|
|
|
|
# 3. Vérifier le retour à l'état normal :
|
|
ssh paillasse "sudo docker exec nova_libvirt virsh domstate <uuid-instance>" # running
|
|
```
|
|
|
|
Compte-rendu du premier test réel : `docs/postmortems/2026-10-12-vm-figee-self-healing.md`.
|
|
|
|
## Limites connues
|
|
|
|
- Ne couvre pas la panne du serveur lui-même (un seul serveur, pas de sonde
|
|
extérieure — dette connue, `docs/dette.md`).
|
|
- Ne couvre pas un service Kolla arrêté ni un conteneur maison arrêté : ce
|
|
sont déjà `Restart=always`/`unless-stopped` côté systemd et Docker (voir
|
|
relevé du 2026-10-12 dans le journal), pas ce mécanisme.
|
|
- Une stack du stock chaud orpheline (ni muette, ni référencée) est déjà
|
|
traitée par `StockChaud::menage()` (étape 11) ; `SurveillanceVm` s'occupe
|
|
seulement des VM qui *répondent mal*, pas de celles qui n'existent plus
|
|
en Redis.
|