Paillasse/docs/runbooks/self-healing.md
2026-10-12 21:12:43 +02:00

4.3 KiB

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.