Knowledge Management : runbooks, postmortems, ADR & docs-as-code
Objectifs pédagogiques
- Comprendre le coût de la connaissance tacite en exploitation
- Organiser la documentation d'une plateforme avec le cadre Diátaxis
- Consigner les décisions d'architecture avec des ADR
- Écrire des runbooks exécutables et les relier aux alertes
- Conduire un postmortem blameless qui produit des actions
- Mener un audit croisé et constituer un dossier de preuves indexé
Pourquoi documenter l'exploitation
Le coût de la connaissance tacite
- À 3 h du matin, l'astreinte n'a ni le temps ni le contexte pour redécouvrir la plateforme
- Le bus factor : combien de départs avant que plus personne ne sache redémarrer le service ?
- Chaque minute passée à chercher une procédure s'ajoute au temps de rétablissement
- Un auditeur ne croit que ce qui est écrit, daté et prouvé
- Une décision non documentée sera rediscutée, puis défaite par quelqu'un qui en ignore les raisons
Docs-as-code
- La documentation vit dans le dépôt, à côté du code qu'elle décrit
- Elle est écrite en Markdown, revue en Merge Request comme le code
- La CI la vérifie : syntaxe, liens morts, orthographe, fraîcheur des dates de revue
- Elle est publiée automatiquement (MkDocs, Backstage TechDocs)
- Un changement d'architecture sans mise à jour de la doc ne passe pas la revue
- Chaque document a un propriétaire et une date de dernière revue
Le cadre Diátaxis
| Type | Orientation | Question du lecteur | Exemple |
| Tutoriel | Apprentissage | « Comment débuter ? » | Monter la plateforme depuis un poste vierge |
| Guide pratique | Tâche | « Comment résoudre ce problème ? » | Runbook « API en OOMKilled » |
| Référence | Information | « Quelle est la valeur exacte ? » | Catalogue des alertes, matrice de conformité |
| Explication | Compréhension | « Pourquoi est-ce ainsi ? » | ADR, architecture, choix de sécurité |
- Mélanger les quatre types produit des documents que personne ne lit jusqu'au bout
docs/
├── README.md # Tutoriel : bootstrap de bout en bout
├── runbooks/ # Guides pratiques : un par alerte
├── reference/ # Catalogue des alertes, SLO, matrice de conformité
├── adr/ # Explications : décisions d'architecture
├── postmortems/ # Explications : incidents et apprentissages
├── audit/ # Rapports d'audit reçus
└── preuves/ # Preuves horodatées et leur index
- Chaque dossier répond à un besoin de lecteur, pas à un découpage technique
Le README d'exploitation
- Vue d'ensemble : ce que fait la plateforme, schéma d'architecture, propriétaires
- Prérequis : outils, versions, accès et comptes nécessaires
- Bootstrap : de zéro à une plateforme fonctionnelle, sans étape implicite
- Opérations courantes : déployer, revenir en arrière, consulter logs et métriques
- Points d'entrée : dashboards, alertes, runbooks, contacts d'escalade
- Test d'acceptation : un nouvel arrivant monte la plateforme seul en suivant le README
Architecture Decision Records
- Document court qui consigne une décision d'architecture significative
- Titre : la décision, formulée comme un choix
- Statut : proposé, accepté, déprécié, remplacé par l'ADR n
- Contexte : les forces en présence, les contraintes, ce qui rend la décision nécessaire
- Décision : ce qui est choisi, formulé à la voix active
- Conséquences : effets positifs, négatifs et neutres, y compris ce que l'on accepte de perdre
Exemple d'ADR
# ADR 0003 : Kyverno comme moteur de politiques d'admission
Statut : accepté (2026-11-03)
## Contexte
Les manifests doivent être validés à l'admission : non-root, limits,
images signées. L'équipe maîtrise YAML mais pas Rego
## Décision
Nous utilisons Kyverno, avec des politiques testées en CI par kyverno apply
## Conséquences
- Politiques lisibles par toute l'équipe, vérification Cosign intégrée
- Moins expressif que Rego pour des règles très complexes
- Kyverno devient un composant critique : deux réplicas et supervision
Cycle de vie des ADR
- Numérotés et immuables : on ne réécrit pas une décision, on la remplace
- Un ADR remplacé pointe vers son successeur, et inversement
- Écrire un ADR quand la décision est coûteuse à défaire ou quand elle sera contestée
- Exemples : moteur de politiques, gestion des secrets, composant désactivé, dérogation à un benchmark
- Les options écartées et leurs raisons comptent autant que la décision retenue
Runbooks
Anatomie d'un runbook
- Symptôme et impact : ce que l'alerte signifie pour les utilisateurs
- Diagnostic : vérifications ordonnées, commandes et requêtes copiables
- Remédiation : actions par cause identifiée, de la moins risquée à la plus risquée
- Retour à la normale : critères mesurables de fin d'incident
- Escalade : qui appeler, quand, avec quelles informations
- Références : dashboards, ADR, postmortems liés
Relier l'alerte au runbook
- alert: SecurePayContainerOOMKilled
expr: |
increase(kube_pod_container_status_restarts_total{namespace="securepay"}[10m]) > 0
and on (namespace, pod, container)
kube_pod_container_status_last_terminated_reason{namespace="securepay", reason="OOMKilled"} == 1
labels:
severity: warning
component: securepay-api
cause: oomkilled
annotations:
summary: "{{ $labels.pod }} redémarre après un dépassement mémoire"
runbook_url: "https://git.example.com/securepay-platform/-/blob/main/docs/runbooks/oomkilled.md"
- L'astreinte passe de la notification à la procédure en un clic
- Une alerte sans runbook est une alerte incomplète
## Diagnostic
1. Confirmer la cause :
kubectl -n securepay describe pod <pod> | grep -A5 "Last State"
2. Comparer la consommation à la limite (Grafana, panneau Mémoire)
3. Vérifier un déploiement récent : argocd app history securepay-api
## Remédiation
- Release récente en cause : revenir à la révision précédente par Git
- Pic de charge légitime : augmenter la limite par MR, preuve à l'appui
- Croissance continue : suspecter une fuite, ouvrir un incident applicatif
## Retour à la normale
Aucun redémarrage depuis 15 min et SLI de disponibilité au-dessus de 99,5 %
Bonnes pratiques
- Exécutable par une personne extérieure à l'équipe : c'est le vrai test
- Commandes copiables, sans étape implicite ni « faire comme d'habitude »
- Jamais de secret dans un runbook : indiquer où et comment l'obtenir
- Rejoué lors des GameDays, corrigé après chaque incident
- Une étape répétée à chaque incident est candidate à l'automatisation
- Le runbook d'aujourd'hui est le script d'auto-remédiation de demain
Postmortems blameless
Quand écrire un postmortem ?
- Impact visible par les utilisateurs au-delà d'un seuil convenu
- Consommation significative de l'error budget en une fois
- Perte ou corruption de données, incident de sécurité
- Intervention manuelle nécessaire pour rétablir le service
- Échec de la détection : l'incident a été signalé par un client
- Les critères sont fixés à l'avance, pas négociés après l'incident
La culture blameless
- On suppose que chacun a agi au mieux avec les informations dont il disposait
- « Erreur humaine » n'est jamais une cause racine : c'est le point de départ de l'analyse
- La vraie question : qu'est-ce qui, dans le système, a rendu l'erreur possible et silencieuse ?
- Désigner un coupable apprend aux équipes à cacher les incidents
- La sécurité psychologique produit des chronologies honnêtes et complètes
Structure d'un postmortem
- Résumé : quoi, quand, combien de temps, quel impact, en quelques lignes
- Impact : utilisateurs touchés, requêtes en erreur, budget consommé
- Chronologie : horodatage UTC de la détection, des décisions et de la résolution
- Cause racine et facteurs contributifs : techniques, organisationnels, outillage
- Ce qui a bien fonctionné, ce qui a mal fonctionné, où nous avons eu de la chance
- Actions : prévenir, détecter, atténuer, chacune avec un responsable et une échéance
Mesurer la chronologie
| Repère | Mesure |
| Début de l'impact → détection | Temps de détection |
| Détection → prise en charge | Temps de réaction |
| Prise en charge → atténuation | Temps d'atténuation |
| Début de l'impact → résolution | Temps de rétablissement |
- Chaque intervalle trop long désigne un type d'action : alerting, astreinte, runbook, automatisation
- Les horodatages viennent des outils (alertes, événements, commits), pas de la mémoire
Les limites des « 5 pourquoi »
- Chaîne linéaire : une seule cause par niveau, alors que les incidents en combinent plusieurs
- S'arrête souvent sur une personne : « parce que l'opérateur a oublié »
- Biais rétrospectif : le chemin paraît évident une fois l'issue connue
- Deux enquêteurs obtiennent deux chaînes différentes
- Préférer une analyse des facteurs contributifs : technique, processus, outillage, contexte
- Chercher plusieurs actions à plusieurs niveaux plutôt qu'une correction unique
Suivre les actions
- Chaque action devient un ticket avec responsable, échéance et priorité
- Le postmortem est revu en équipe avant d'être publié
- Une revue périodique vérifie que les actions sont réellement fermées
- Les postmortems sont partagés largement : un incident évité ailleurs vaut un incident résolu
- Un postmortem sans action fermée n'a servi qu'à écrire un document
Audit croisé & dossier de preuves
Méthodologie d'audit croisé
- Cadrage : périmètre, référentiel (risques, PSSI, grille), durée
- Règles d'engagement : ce qui est autorisé, interdit, et en présence de qui
- Revue documentaire : dépôts gelés, ADR, matrice de conformité, preuves
- Vérifications actives : tentatives de contournement des contrôles, rejeu des audits
- Constats : preuve, sévérité, recommandation
- Restitution puis contre-vérification après remédiation
Règles d'engagement
- Cibles autorisées nommées explicitement : namespace, dépôts, machine
- Actions interdites : destruction de données, de VM ou de dépôt, déni de service
- Équipe auditée présente, chaque action annoncée avant d'être lancée
- Toutes les commandes tracées, avec leur horodatage
- Arrêt immédiat sur demande de l'équipe auditée
- Aucune correction silencieuse : l'auditeur constate, l'audité remédie
Rédiger un constat
### AUD-04 : un pod root est admis dans le namespace securepay
Sévérité : majeure
Contrôle visé : politique d'admission « exécution non-root »
Preuve : 2026-11-07_1012_audit-pod-root.png
kubectl -n securepay run test --image=busybox --overrides='...runAsUser: 0...'
=> pod/test created
Impact : un conteneur compromis s'exécute avec les droits root
Recommandation : passer la politique Kyverno en mode Enforce
Statut : corrigé le 2026-11-07, contre-vérifié (preuve AUD-04-bis)
- Sans preuve reproductible, un constat n'est pas recevable
Le dossier de preuves indexé
- Un dossier
docs/preuves/ et un index docs/preuves/README.md - Nommage :
AAAA-MM-JJ_HHMM_<scenario>.<ext>, en heure UTC - Chaque preuve est reliée à une exigence, un scénario et un résultat
- Captures complètes : horloge, filtres et période visibles
- Empreinte
sha256sum dans l'index pour attester l'intégrité - Une preuve introuvable en trente secondes n'existe pas pour un auditeur
À retenir
- La documentation d'exploitation fait partie de la plateforme, versionnée et revue comme le code
- Diátaxis : tutoriel, guide pratique, référence, explication, sans les mélanger
- Un ADR par décision coûteuse à défaire, immuable et remplaçable
- Une alerte, un runbook, exécutable par quelqu'un d'extérieur à l'équipe
- Postmortems sans reproche, avec des actions suivies jusqu'à leur fermeture
- Audit et certification ne reposent que sur des preuves horodatées et indexées
Pour aller plus loin
- Diátaxis et l'article de Michael Nygard « Documenting Architecture Decisions »
- Site Reliability Engineering (Google), chapitre « Postmortem Culture »
- Les modèles prêts à l'emploi de ce cours