freedzhost.cloud

DevOps module 4 : observabilité, incidents, sécurité, et le projet final

Niveau IntermédiaireTemps estimé 17 hÀ lire avant DevOps module 3 : infrastructure en code, Kubernetes et secretsUn mot inconnu ? Lexique

Dix-sept séances sur ce qui se passe après le déploiement : voir à l'intérieur d'un système en marche, décider ce que « ça marche » veut dire, gérer le jour où ça casse et en tirer les leçons, et sécuriser la chaîne qui le construit. Les six derniers jours rassemblent tout dans un projet final que vous pouvez montrer.

La pile de supervision tourne en local avec Docker Compose ; les noms d'images et les ports viennent de la documentation de chaque projet, vérifiez-les là avant de commencer. Si vous avez manqué des jours, c'est ce module que vous raccourcissez : gardez les jours 43, 44, 49, 50, 51, 52 et le projet final.

Jour 43 · 15/12 — Observabilité : métriques, journaux, traces

Objectif : dire à quoi répond chaque signal, et choisir quoi surveiller avec les signaux d'or.

Théorie 1/2 : supervision et observabilité

La supervision guette des problèmes prévus (le disque est plein) ; l'observabilité, c'est pouvoir poser de nouvelles questions à un système en marche à partir de ce qu'il émet, y compris sur des problèmes que personne n'avait prévus. Trois sortes de signaux : les métriques (des nombres dans le temps, peu coûteux : requêtes par seconde), les journaux (des événements horodatés, détaillés : cette requête a échoué avec cette erreur), les traces (le trajet d'une requête à travers les services, avec le temps passé dans chacun).

« Quel service a ralenti cette requête précise ? » Quel signal répond le mieux ?

  1. Les métriques
  2. Les journaux
  3. Les traces
Réponse

Une trace montre le temps passé à chaque étape d'une requête.

« Combien d'erreurs par seconde sur la semaine passée ? » Quel signal ?

  1. Les métriques
  2. Les traces
Réponse

Un compteur dans le temps : les métriques.

Théorie 2/2 : signaux d'or, USE, RED

Le livre SRE de Google nomme quatre signaux d'or pour un service exposé aux utilisateurs : la latence, le trafic, les erreurs, la saturation. Pour les ressources (CPU, disque, réseau), la méthode USE de Brendan Gregg : utilisation, saturation, erreurs. Pour les services à requêtes, la méthode RED de Tom Wilkie : débit (rate), erreurs, durée.

Latence, trafic, erreurs et… quel quatrième signal d'or ?

Réponse

La saturation : à quel point le service est plein.

RED veut dire…

  1. Requests, Errors, Disk
  2. Rate, Errors, Duration
Réponse

Rate, Errors, Duration : débit, erreurs, durée.

Pratique (30 min)

  1. Lisez le chapitre Monitoring Distributed Systems du livre SRE (en anglais), la partie sur les quatre signaux d'or.
  2. Pour hello-ops, écrivez dans votre carnet ce que serait chaque signal d'or, concrètement (quel nombre, d'où).
  3. Écrivez trois questions auxquelles vous aimeriez répondre sur votre appli en production, et quel signal répond à chacune.

Avec votre IA : « Pour une petite API HTTP avec un cache Redis, propose les métriques RED et USE que je devrais collecter, dans un tableau avec nom de la métrique, type (compteur, jauge, histogramme) et question à laquelle elle répond. Puis interroge-moi avec trois cas "quel signal regarderais-tu". »

Synthèse (10 min)

Trois lignes : supervision ou observabilité, les trois signaux, les signaux d'or. Puis récitez RED et USE sans notes.

Jour 44 · 16/12 — Prometheus 1 : collecte et PromQL

Objectif : lancer Prometheus, collecter les métriques d'une machine et écrire vos premières requêtes.

Théorie 1/2 : le modèle par collecte

Prometheus est né chez SoundCloud en 2012, a rejoint la CNCF en 2016 et en a été le deuxième projet diplômé (2018) ; la version 3.0 est sortie en novembre 2024. Il tire les données : toutes les quelques secondes, il collecte (scrape) un point HTTP (/metrics) sur chaque cible et range les échantillons en séries temporelles, nommées et étiquetées : http_requests_total{path="/", code="200"}. Des exporteurs exposent les métriques de ce qui ne le fait pas : node_exporter pour une machine Linux (port 9100).

# prometheus.yml
global:
  scrape_interval: 15s
scrape_configs:
  - job_name: node
    static_configs:
      - targets: ["node-exporter:9100"]

L'appli envoie-t-elle ses métriques à Prometheus ?

  1. Oui, elle les pousse
  2. Non, Prometheus vient les collecter chez l'appli
Réponse

Modèle par collecte : Prometheus lit /metrics.

Théorie 2/2 : PromQL

Un compteur ne fait que monter (requêtes servies) ; une jauge monte et descend (mémoire utilisée) ; un histogramme compte des valeurs par tranches (durées de requêtes). Un compteur se regarde par son taux :

up                                             # 1 si la cible a répondu à la dernière collecte
rate(node_cpu_seconds_total{mode!="idle"}[5m]) # CPU utilisé par seconde
sum by (code) (rate(http_requests_total[5m]))  # requêtes par seconde, par code
histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

Quelle fonction transforme un compteur en taux par seconde ?

Réponse

rate(), sur une plage comme [5m].

La mémoire utilisée est…

  1. une jauge
  2. un compteur
Réponse

Elle monte et descend : une jauge.

Pratique (30 min)

  1. Dans un nouveau dossier monitoring/, écrivez un compose.yaml à deux services : prometheus (image prom/prometheus, port 9090, votre prometheus.yml monté en lecture seule sur /etc/prometheus/prometheus.yml) et node-exporter (image prom/node-exporter). Vérifiez les étiquettes sur les pages des projets.
  2. docker compose up -d ; ouvrez http://127.0.0.1:9090, Status → Targets : les deux sont up.
  3. Lancez dans la page de requêtes : up, puis le taux de CPU, puis node_memory_MemAvailable_bytes, en mode graphique.
  4. Créez de la charge (yes > /dev/null & pendant une minute, puis kill %1) et regardez la courbe du CPU.

Avec votre IA : « Apprends-moi PromQL avec les métriques de node_exporter : donne-moi cinq questions de difficulté croissante ("mémoire disponible en pourcentage", "CPU par mode"…). J'écris la requête, tu la vérifies et tu expliques l'erreur s'il y en a une. Ne donne pas la réponse avant que j'essaie. »

Le faire faire par un agent : un agent peut écrire du PromQL à partir d'une question en langage courant. Vous lancez encore chaque requête dans l'interface de Prometheus et vérifiez une valeur à la main (par exemple la mémoire face à free -b) : une requête qui tourne n'est pas une requête juste.

Synthèse (10 min)

Trois lignes : collecte et scrape, compteur / jauge / histogramme, rate(). Puis réécrivez la configuration de collecte sans notes.

Jour 45 · 17/12 — Prometheus 2 : instrumenter l'appli, règles d'alerte

Objectif : faire exposer à hello-ops ses propres métriques et déclencher une alerte quand elle tombe.

Théorie 1/2 : instrumenter

La bibliothèque cliente Python crée des métriques et les produit dans le format texte que lit Prometheus. Les valeurs de labels doivent rester peu nombreuses (chemin, code) : un label qui contient un identifiant d'utilisateur ou une URL complète crée une série par valeur et surcharge Prometheus (forte cardinalité).

from prometheus_client import CONTENT_TYPE_LATEST, Counter, generate_latest

REQUESTS = Counter("http_requests_total", "HTTP requests", ["path", "code"])

# dans do_GET, avant le routage :
if self.path == "/metrics":
    data = generate_latest()
    self.send_response(200)
    self.send_header("Content-Type", CONTENT_TYPE_LATEST)
    self.end_headers()
    self.wfile.write(data)
    return
# après le routage :
REQUESTS.labels(path=self.path if code != 404 else "other", code=str(code)).inc()

Pourquoi ne pas prendre l'URL demandée complète comme label ?

  1. Elle est trop longue à taper
  2. Chaque URL distincte crée une nouvelle série : cardinalité sans limite
Réponse

C'est pourquoi les chemins inconnus sont regroupés sous « other ».

Théorie 2/2 : règles d'alerte et Alertmanager

Prometheus évalue des règles d'alerte ; une règle qui reste vraie pendant sa durée for: se déclenche, et Alertmanager regroupe, met en sourdine et achemine les alertes vers un courriel, une messagerie ou un système d'astreinte.

groups:
  - name: hello-ops
    rules:
      - alert: HelloOpsDown
        expr: up{job="hello-ops"} == 0
        for: 1m
        labels:
          severity: page
        annotations:
          summary: "hello-ops is not answering scrapes"

Que fait for: 1m ?

  1. La condition doit tenir une minute avant que l'alerte se déclenche
  2. L'alerte se répète chaque minute
Réponse

Il filtre les incidents d'une seconde.

Quel composant achemine et met en sourdine les alertes que déclenche Prometheus ?

Réponse

Alertmanager.

Pratique (30 min)

  1. Ajoutez prometheus-client à un requirements.txt, le code ci-dessus à app.py, et installez les dépendances dans l'étape finale du Dockerfile. Reconstruisez ; curl http://127.0.0.1:8080/metrics.
  2. Ajoutez hello-ops au projet compose de supervision (même réseau) et un job de collecte hello-ops qui vise app:8080.
  3. Écrivez la règle dans rules.yml, montez-la, référencez-la avec rule_files. Arrêtez l'appli : après une minute, l'alerte est « firing » dans la page Alerts de Prometheus.
  4. Ajoutez à test_app.py un test qui vérifie que le compteur augmente après une requête (avec REQUESTS.labels(...)._value.get() ou le get_sample_value du registre).

Avec votre IA : « Relis mon code de métriques pour la cardinalité et le nommage, selon les bonnes pratiques de nommage de Prometheus : [collez le code]. Liste les problèmes avec la ligne exacte, et dis-moi quelle page de prometheus.io lire pour vérifier chaque point. »

Le faire faire par un agent : un agent peut ajouter un histogramme de durée au gestionnaire. Consigne : « Ajoute un Histogram http_request_duration_seconds étiqueté par chemin ; garde des labels bornés ; ajoute un test ; lance pytest. » Vous vérifiez encore /metrics à la main et que les valeurs de labels ne peuvent pas grossir avec ce qu'envoie l'utilisateur.

Synthèse (10 min)

Trois lignes : instrumenter, la cardinalité, règle plus Alertmanager. Puis réécrivez la règle d'alerte de mémoire.

Jour 46 · 18/12 — Grafana : les tableaux de bord

Objectif : construire un tableau de bord des signaux d'or de hello-ops, et le garder en code.

Théorie 1/2 : sources de données et panneaux

Grafana (Torkel Ödegaard, 2014) dessine des tableaux de bord à partir de sources de données : Prometheus pour les métriques, Loki pour les journaux, Jaeger ou Tempo pour les traces. Un panneau est une requête plus une visualisation ; des variables font servir un même tableau à chaque instance. Un bon tableau répond d'un coup d'œil à une question : le service va-t-il bien, et sinon, où ça coince.

Grafana stocke-t-il les métriques ?

  1. Oui
  2. Non, il interroge des sources de données comme Prometheus
Réponse

Grafana affiche ; Prometheus stocke.

Théorie 2/2 : les tableaux de bord en code

Un tableau assemblé à la souris est un animal de compagnie. Grafana sait provisionner sources de données et tableaux à partir de fichiers au démarrage (YAML pour les fournisseurs, JSON pour les tableaux) : ils vivent dans Git, sont relus, et survivent à un conteneur reconstruit.

Pourquoi provisionner les tableaux à partir de fichiers ?

  1. Versionnés, relus, reconstruits à l'identique
  2. Les fichiers rendent Grafana plus rapide
Réponse

Même raison que pour toute infrastructure en code.

Quel panneau montre le mieux la part de réponses 5xx ?

  1. Un tableau de chaque requête
  2. Un camembert des chemins
  3. Une série temporelle de sum(rate(http_requests_total{code=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
Réponse

Un ratio d'erreurs dans le temps.

Pratique (30 min)

  1. Ajoutez grafana (image grafana/grafana, port 3000) à la pile de supervision, avec un fichier de provisionnement qui déclare Prometheus à http://prometheus:9090.
  2. Construisez un tableau à quatre panneaux : requêtes par seconde, ratio d'erreurs, latence p95 (si vous avez ajouté l'histogramme), et up.
  3. Créez du trafic avec une boucle de curl, dont quelques-uns sur /nothing pour des 404 ; regardez les panneaux.
  4. Exportez le tableau en JSON, rangez-le dans monitoring/dashboards/, provisionnez-le, recréez le conteneur : il est toujours là.

Avec votre IA : « Voici les métriques qu'expose mon appli : [collez /metrics]. Propose un tableau de bord à quatre panneaux des signaux d'or : pour chaque panneau, la requête PromQL, le type de visualisation et le seuil qui doit le faire passer au rouge. Je le construirai moi-même. »

Le faire faire par un agent : les agents savent générer le JSON d'un tableau de bord. Vous le chargez encore, vérifiez que chaque panneau affiche des données conformes à une requête que vous lancez vous-même dans Prometheus, et retirez les panneaux que personne ne regarderait.

Synthèse (10 min)

Trois lignes : sources de données et panneaux, une question par tableau, les tableaux en code. Puis réécrivez la requête du ratio d'erreurs de mémoire.

Jour 47 · 19/12 — Journaux : structurés, collectés, cherchés

Objectif : faire écrire à l'appli une ligne JSON par requête, collecter les journaux, et les chercher à côté des métriques.

Théorie 1/2 : des journaux structurés sur la sortie standard

L'application en douze facteurs (facteur XI) traite les journaux comme un flux d'événements écrit sur la sortie standard ; la plateforme (journald, Docker, Kubernetes) les collecte. Une ligne de journal structurée se lit par une machine, avec des noms de champs stables, si bien qu'on filtre sur des champs au lieu de deviner avec grep :

{"ts": "2026-12-19T10:42:07Z", "level": "info", "path": "/health", "code": 200, "ms": 1.8}

Ne journalisez jamais en clair des secrets, des jetons ou des données personnelles : les journaux sont copiés à beaucoup d'endroits et gardés longtemps.

Où une appli conteneurisée doit-elle écrire ses journaux ?

  1. Dans un fichier dans le conteneur
  2. Sur stdout et stderr, collectés par la plateforme
Réponse

Les fichiers dans un conteneur disparaissent avec lui et se collectent mal.

Théorie 2/2 : Loki et son collecteur

Loki (Grafana Labs, 2018) stocke les journaux indexés seulement par quelques labels (job, conteneur), ce qui le garde bon marché ; on l'interroge en LogQL : {container="hello-ops"} | json | code >= 500. Les journaux sont expédiés par un collecteur : Promtail l'a fait pendant des années, mais il est arrivé en fin de vie le 2 mars 2026 ; Grafana oriente désormais vers Grafana Alloy, et d'autres collecteurs (Fluent Bit, l'OpenTelemetry Collector) savent aussi envoyer à Loki.

Quel collecteur a remplacé Promtail dans les recommandations de Grafana ?

  1. Grafana Alloy
  2. Grafana Agent
Réponse

Alloy. Grafana Agent est lui-même arrivé en fin de vie en novembre 2025.

Pourquoi Loki n'indexe-t-il que les labels, pas le texte des journaux ?

  1. Il ne sait pas lire le texte
  2. Pour garder stockage et indexation bon marché ; le texte est filtré au moment de la requête
Réponse

Peu de labels, petit index ; les filtres tournent sur les flux sélectionnés.

Pratique (30 min)

  1. Surchargez log_message (ou log_request) dans le gestionnaire pour écrire une ligne JSON par requête avec json.dumps, sur stderr. Reconstruisez ; docker compose logs app montre des lignes JSON.
  2. Ajoutez Loki et un collecteur à la pile de supervision en suivant le démarrage rapide de Loki de Grafana (il fournit un exemple Compose avec Alloy) ; pointez-le vers les journaux de vos conteneurs.
  3. Dans Grafana, ajoutez Loki comme source de données ; dans Explore, trouvez toutes les lignes 404 des 15 dernières minutes en LogQL.
  4. Sans la pile : docker compose logs app | grep '"code": 404' | wc -l, et comparez les comptes.

Avec votre IA : « Voici dix de mes lignes de journal JSON : [collez]. Apprends-moi LogQL dessus : donne-moi quatre questions (erreurs par chemin, requêtes les plus lentes…), j'écris la requête, tu la vérifies. Dis-moi quels noms de champs tu renommerais et pourquoi. »

Le faire faire par un agent : un agent peut chercher dans les journaux sur une période et résumer. Demandez-lui la requête LogQL ou la commande exacte qu'il a lancée. Vous la relancez encore et regardez quelques lignes brutes : les résumés cachent la ligne bizarre qui compte.

Synthèse (10 min)

Trois lignes : journaux sur stdout, champs structurés, labels de Loki et son collecteur. Puis réécrivez la requête LogQL de mémoire.

Jour 48 · 20/12 — Traces : OpenTelemetry et Jaeger

Objectif : émettre une trace depuis l'appli et la lire dans Jaeger.

Théorie 1/2 : spans et contexte

Une trace est l'arbre des spans d'une requête ; un span est une opération avec un début, une durée, des attributs et un parent. D'un service à l'autre, le contexte (identifiant de trace, identifiant de span) voyage dans les en-têtes HTTP (l'en-tête W3C traceparent), si bien que chaque service rattache ses spans à la même trace. L'article Dapper de Google (2010) a décrit l'idée ; OpenTelemetry, né en 2019 de la fusion d'OpenTracing et d'OpenCensus et hébergé par la CNCF, est aujourd'hui l'API, le SDK et le protocole (OTLP) de référence pour traces, métriques et journaux.

Quel en-tête HTTP du W3C transporte le contexte de trace entre services ?

Réponse

traceparent.

Qu'a fusionné OpenTelemetry en 2019 ?

  1. OpenTracing et OpenCensus
  2. Prometheus et Grafana
Réponse

OpenTracing et OpenCensus.

Théorie 2/2 : instrumenter à la main

from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("hello-ops")

# dans do_GET :
with tracer.start_as_current_span("GET " + self.path) as span:
    code, body = route(self.path)
    span.set_attribute("http.response.status_code", code)

L'exporteur lit son adresse dans OTEL_EXPORTER_OTLP_ENDPOINT et le nom du service dans OTEL_SERVICE_NAME : la configuration reste hors du code.

Quelle variable d'environnement nomme le service dans OpenTelemetry ?

Réponse

OTEL_SERVICE_NAME.

Pratique (30 min)

  1. Ajoutez opentelemetry-sdk et opentelemetry-exporter-otlp-proto-http à requirements.txt, et le code ci-dessus à app.py.
  2. Ajoutez Jaeger à la pile de supervision en suivant sa page de prise en main (image tout-en-un : interface sur 16686, OTLP sur HTTP sur 4318). Posez OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318 et OTEL_SERVICE_NAME=hello-ops sur l'appli.
  3. Envoyez quelques requêtes ; ouvrez l'interface de Jaeger, choisissez hello-ops, ouvrez une trace, lisez son span et son attribut.
  4. Ajoutez un span enfant autour d'une fausse étape lente (time.sleep(0.2) sur / seulement) et retrouvez-le dans la trace. Retirez-le ensuite.

Avec votre IA : « Explique, avec mon code ci-dessous, ce qui se passe entre l'arrivée d'une requête et l'apparition de son span dans Jaeger : SDK, processeur, exporteur, OTLP, collecteur. Une ligne par étape. Puis dis-moi ce qu'il faudrait ajouter pour qu'un second service rejoigne la même trace : [collez le code]. »

Le faire faire par un agent : un agent peut ajouter des spans autour de chaque fonction qui mérite d'être chronométrée. Vous lisez encore une trace et vérifiez que les spans s'emboîtent comme le code, et qu'aucun attribut ne porte une donnée personnelle ou un secret.

Synthèse (10 min)

Trois lignes : trace et span, propagation du contexte, ce qu'est OpenTelemetry. Puis réécrivez les quatre lignes de mise en place de mémoire.

Jour 49 · 21/12 — SLI, SLO, budgets d'erreur, des alertes qui comptent

Objectif : définir un SLO pour hello-ops, calculer son budget d'erreur, et alerter sur les symptômes, pas sur les causes.

Théorie 1/2 : SLI, SLO, SLA

Un SLI (indicateur de niveau de service) mesure ce que ressentent les utilisateurs : la part de requêtes servies avec succès en moins de 300 ms. Un SLO (objectif) est la cible de cet indicateur sur une fenêtre : 99,5 % sur 30 jours. Un SLA (accord) est un contrat avec des conséquences s'il n'est pas tenu, fixé plus large que le SLO. 100 % est la mauvaise cible : les utilisateurs ne distinguent pas 99,99 % de 100 %, et elle interdirait tout changement.

« 99,9 % des requêtes réussissent sur 30 jours », c'est…

  1. un SLI
  2. un SLO
  3. un SLA
Réponse

Une cible sur une fenêtre : un SLO. La part de requêtes réussies est le SLI.

Théorie 2/2 : le budget d'erreur

Le budget d'erreur est ce que le SLO permet de rater : 100 % − SLO. À 99,9 % sur 30 jours (43 200 minutes), c'est 0,1 %, environ 43 minutes de panne totale. Tant qu'il reste du budget, l'équipe livre ; quand il est épuisé, le travail de fiabilité passe en premier. Les alertes doivent réveiller sur des symptômes que ressentent les utilisateurs (le budget brûle trop vite), pas sur chaque cause (CPU à 80 %), sinon plus personne ne les lit.

Budget d'erreur d'un SLO à 99,9 % sur 30 jours, en minutes entières de panne totale ?

Réponse

0,1 % × 43 200 = 43,2, environ 43 minutes.

Quelle alerte doit réveiller quelqu'un la nuit ?

  1. Le taux d'erreur brûle le budget du mois en quelques heures
  2. CPU au-dessus de 80 % pendant cinq minutes
Réponse

Réveiller sur les symptômes visibles des utilisateurs ; les causes vont sur les tableaux de bord.

Le budget d'erreur du mois est épuisé le 12. Que dit d'habitude la politique ?

  1. Livrer plus vite pour compenser
  2. Passer le SLO à 90 %
  3. Suspendre les mises en production risquées et travailler la fiabilité
Réponse

Le budget arbitre entre fonctionnalités et fiabilité.

Pratique (30 min)

  1. Écrivez le SLI de hello-ops en ratio PromQL : requêtes réussies (non 5xx) sur toutes les requêtes, sur 30 jours.
  2. Choisissez un SLO, calculez le budget en minutes et en requêtes ratées pour votre trafic, écrivez les deux dans votre carnet.
  3. Écrivez une règle d'alerte sur le ratio d'erreurs sur 1 heure au-dessus de 14,4 fois le taux du budget (l'exemple de brûlure rapide du SRE workbook), et lisez le chapitre Alerting on SLOs pour comprendre ce chiffre.
  4. Supprimez ou rétrogradez toute alerte à vous qui réveille sur une cause.

Avec votre IA : « Mon service reçoit environ 50 000 requêtes par jour. Vérifie mes chiffres pour un SLO mensuel de 99,5 % : budget en requêtes ratées et en minutes de panne totale ; et explique en mots simples ce que veut dire un taux de brûlure de 14,4 sur une heure. Montre le calcul pour que je le refasse. »

Le faire faire par un agent : des outils de SLO (par exemple Sloth ou Pyrra) et les agents savent générer les règles de brûlure à plusieurs fenêtres. Vous recalculez encore un seuil à la main et testez la règle en injectant des erreurs.

Synthèse (10 min)

Trois lignes : SLI / SLO / SLA, le budget d'erreur, symptômes ou causes. Puis recalculez le budget à 99,9 % sans notes.

Jour 50 · 22/12 — Gérer un incident, et prompter pendant

Objectif : mener un incident avec des rôles clairs et une chronologie, et se servir d'une IA pendant sans perdre la main.

Théorie 1/3 : les rôles et les premières minutes

La pratique de l'incident emprunte à l'Incident Command System des pompiers américains (années 1970). Des rôles, même à deux : le responsable d'incident (incident commander) coordonne et décide, il ne tape pas de commandes ; les opérations enquêtent et agissent ; la communication tient informés utilisateurs et parties prenantes. Le premier but est d'atténuer (arrêter les dégâts : revenir en arrière, basculer, éteindre un drapeau), pas de trouver la cause profonde. Tenez une chronologie horodatée de ce qui a été vu et fait ; elle nourrira le postmortem.

Les erreurs ont commencé juste après un déploiement. Premier geste ?

  1. Trouver le bogue dans le code
  2. Revenir en arrière, puis enquêter
Réponse

Atténuer d'abord ; comprendre attendra que les utilisateurs aillent bien.

Le rôle du responsable d'incident est de…

  1. coordonner, décider et garder la vue d'ensemble
  2. réparer lui-même le problème
Réponse

Les mains loin du clavier, les yeux sur l'ensemble.

Théorie 2/3 : les runbooks

Un runbook est la procédure écrite d'une situation connue : symptôme, vérifications, actions, comment vérifier, qui appeler. Chaque alerte renvoie à son runbook. Sous la pression, personne ne se souvient ; tout le monde sait suivre des étapes.

Comment s'appelle la procédure écrite pas à pas, liée depuis une alerte ?

Réponse

Un runbook (ou playbook).

Théorie 3/3 : prompter pendant un incident

Un prompt faible : « mon site est en panne, je fais quoi ? ». Ce qui ne va pas : pas de système, pas de symptôme, pas de données, et il invite le modèle à proposer des commandes risquées que vous serez tenté de coller sous la pression.

Le prompt retravaillé :

Rôle : tu assistes un ingénieur d'astreinte ; tu proposes, je décide et j'agis.
Contexte : hello-ops sur Kubernetes (kind), révision 7 du Deployment
déployée à 10:02 ; l'alerte SLO s'est déclenchée à 10:09.
Tâche : classe les trois causes les plus probables et la vérification
en lecture seule qui confirme ou écarte chacune.
Contraintes : commandes en lecture seule uniquement (get, describe,
logs) ; pas de delete, pas d'apply, pas de redémarrage ; dis
"inconnu" plutôt que deviner.
Entrées : kubectl get pods ; kubectl describe d'un Pod en échec ;
les 30 dernières lignes de journal : [coller].
Sortie : une liste numérotée : cause, indice dans mes entrées, vérification.
Vérification : je lance chaque vérification moi-même et je colle le résultat.

Pourquoi « commandes en lecture seule uniquement » dans un prompt d'incident ?

  1. Pour économiser des jetons
  2. Les commandes de lecture sont plus rapides
  3. Sous la pression, vous pourriez coller une suggestion destructrice ; une vérification en lecture ne peut pas aggraver la situation
Réponse

Le modèle propose ; les actions restent une décision humaine.

Corrigez ce prompt : « Les logs disent erreur, répare. » Le meilleur ajout ?

  1. « Vite »
  2. Les lignes de journal exactes, ce qui a changé et quand, et le format de sortie attendu
Réponse

Les entrées et le format ; sans eux, il ne peut que deviner.

Pratique (30 min)

  1. Écrivez le runbook de l'alerte HelloOpsDown : symptôme, vérifications (kubectl get pods, describe, logs, rollout history), actions (rollout undo), vérification (/health, le panneau du SLI), escalade.
  2. Exercice : déployez l'image cassée v3 du jour 39 pendant qu'une boucle de curl tourne. Jouez responsable et opérateur : ouvrez un fichier de chronologie, notez chaque heure et chaque action, atténuez avec le runbook.
  3. Clôturez l'incident quand le SLI revient ; gardez la chronologie pour demain.

Avec votre IA : utilisez le prompt retravaillé ci-dessus pendant l'exercice, avec vos vraies sorties collées. Notez dans la chronologie ce qu'il a suggéré, ce que vous avez vérifié, et s'il avait raison.

Le faire faire par un agent : un agent peut être secrétaire et enquêteur pendant un incident : tenir la chronologie à partir du fil de discussion, lancer des vérifications en lecture et résumer. Donnez-lui des accès en lecture seule. C'est vous qui décidez et lancez chaque action qui modifie la production.

Synthèse (10 min)

Trois lignes : les trois rôles, atténuer d'abord, ce que contient un runbook ; et les contraintes du prompt d'incident. Puis réécrivez correctement le prompt faible de mémoire.

Jour 51 · 23/12 — Les postmortems sans reproche

Objectif : écrire le postmortem de l'exercice d'hier, sans reproche et avec des actions qui seront faites.

Théorie 1/2 : pourquoi sans reproche

En mai 2012, John Allspaw, qui dirigeait alors l'exploitation d'Etsy, publie « Blameless PostMortems and a Just Culture » : si l'on punit les gens pour leurs erreurs, ils les cachent, et l'organisation cesse d'apprendre. Une revue sans reproche demande ce que les gens savaient, attendaient et faisaient à chaque instant, et pourquoi cela avait du sens pour eux ; la personne la plus proche de la panne devient l'experte de sa prévention. Le livre SRE de Google consacre un chapitre à la culture du postmortem.

« Bob a lancé la mauvaise commande » comme cause profonde, c'est…

  1. une bonne conclusion de postmortem
  2. le point de départ de l'analyse : pourquoi la mauvaise commande était-elle facile à lancer et difficile à rattraper ?
Réponse

« L'erreur humaine » est un point de départ, pas une cause.

Théorie 2/2 : le document

Un postmortem contient : un résumé ; l'impact (qui, combien de temps, combien de budget) ; la chronologie ; comment l'incident a été détecté et atténué ; les facteurs contributifs (rarement une seule cause profonde ; les « cinq pourquoi » aident mais suivent souvent une seule piste) ; ce qui a bien et mal marché ; des actions avec un responsable et une date. L'article du site Quand mon agent IA a ouvert une porte au mauvais endroit est un vrai rapport d'incident écrit ainsi.

Une action sans responsable ni date…

  1. n'est en général jamais faite
  2. convient très bien
Réponse

Un responsable et une date, sinon c'est un souhait.

Quelle partie dit combien de temps les utilisateurs ont été touchés ?

  1. Les actions
  2. La chronologie seule
  3. L'impact
Réponse

L'impact : qui, combien de temps, combien.

Pratique (30 min)

  1. Écrivez postmortems/2026-12-22-broken-health-check.md à partir de la chronologie d'hier : résumé, impact (minutes, requêtes ratées, budget consommé), chronologie, détection, atténuation, facteurs contributifs, ce qui a bien marché, actions.
  2. Trouvez au moins un facteur contributif dans le système, pas dans la personne (par exemple : rien dans la CI ne testait /health dans l'image construite).
  3. Transformez une action en vrai changement dès maintenant (une étape de CI qui lance l'image et interroge /health), et liez le commit dans le postmortem.

Avec votre IA : « Relis mon postmortem en animateur formé aux revues sans reproche : [collez-le]. Signale chaque phrase qui accuse une personne, chaque action sans responsable ni date, et tout facteur contributif que j'aurais manqué vu la chronologie. Cite les phrases. »

Le faire faire par un agent : un agent peut rédiger le postmortem à partir du fil de l'incident et de la chronologie. Les facteurs contributifs et les actions restent à vous : l'agent n'était pas là et ne sait pas quelle correction l'équipe fera vraiment.

Synthèse (10 min)

Trois lignes : pourquoi sans reproche, les parties d'un postmortem, les actions. Puis listez les parties de mémoire.

Jour 52 · 24/12 — Sécurité dans la chaîne 1 : décaler à gauche

Objectif : ajouter à la chaîne l'analyse du code, des dépendances, des secrets et des images, et savoir ce que trouve chacune.

Théorie 1/2 : le DevSecOps et les familles de scanners

Le DevSecOps met la sécurité dans la même chaîne que le reste, le plus tôt possible (« décaler à gauche », shift left) : une faille trouvée dans une pull request coûte des minutes, en production elle coûte un incident. Familles de vérifications :

  • SAST (analyse statique de votre code) : Semgrep, CodeQL, Bandit pour Python ;
  • SCA (vulnérabilités connues de vos dépendances) : pip-audit, OSV-Scanner ;
  • recherche de secrets : Gitleaks (jour 41) ;
  • analyse d'images et de configuration : Trivy, Grype ; et les erreurs de configuration de l'IaC ;
  • DAST (attaquer l'appli en marche) : ZAP.

Le Top 10 de l'OWASP liste les familles de risques les plus courantes des applications web.

Une dépendance que vous utilisez a une CVE publiée. Quel type d'outil la trouve ?

  1. SAST
  2. SCA
  3. DAST
Réponse

L'analyse de composition logicielle : les vulnérabilités connues des dépendances.

Quelle famille analyse votre propre code source sans l'exécuter ?

  1. SAST
  2. DAST
Réponse

Les tests statiques de sécurité applicative.

Théorie 2/2 : constats, seuils et bruit

Un scanner qui échoue sur chaque constat mineur est désactivé en une semaine. Faites échouer la construction sur les constats élevés et critiques qui ont un correctif, signalez le reste, et consignez les risques acceptés avec une raison et une date d'expiration. Et souvenez-vous de mars 2026 : le scanner est lui-même une dépendance (les étiquettes de l'action Trivy ont été détournées) ; épinglez-le comme toute autre action.

Meilleure politique pour un nouveau scanner d'images ?

  1. Échouer sur chaque constat dès le premier jour
  2. Ne jamais échouer, seulement signaler
  3. Échouer sur les constats élevés et critiques corrigeables, signaler le reste, documenter les exceptions
Réponse

Du signal plutôt que du bruit, sinon la vérification est retirée.

Pratique (30 min)

  1. En local, lancez chaque outil une fois sur hello-ops en suivant son README : pip-audit -r requirements.txt, Bandit sur app.py, Gitleaks sur l'historique, Trivy (installé depuis sa documentation officielle, en vérifiant que la version n'est pas l'une des versions compromises listées dans l'avis) sur l'image : trivy image hello-ops:dev.
  2. Lisez chaque constat : réel, faux positif, ou accepté ? Notez votre décision.
  3. Ajoutez les deux moins coûteux (pip-audit et Gitleaks) à la CI dans un job security, avec la politique de seuil ci-dessus.

Avec votre IA : « Voici un rapport Trivy de mon image : [collez le tableau]. Pour chaque constat élevé ou critique, dis-moi si une version corrigée existe, s'il est dans l'image de base ou dans mes dépendances, et le plus petit changement qui le corrige. Ne devine pas les détails des CVE : dis "voir l'avis" quand tu n'es pas sûr. »

Le faire faire par un agent : un agent peut trier la sortie des scanners et ouvrir les pull requests de mise à jour. Vous vérifiez encore que les tests de chaque mise à jour passent, lisez le journal des changements de toute montée de version majeure, et ne le laissez jamais ajouter une exception sans raison écrite.

Synthèse (10 min)

Trois lignes : décaler à gauche, SAST / SCA / secrets / images / DAST, la politique de seuil. Puis nommez l'outil de chaque famille sans notes.

Jour 53 · 25/12 — Sécurité dans la chaîne 2 : la chaîne d'approvisionnement

Objectif : produire une SBOM de l'image, comprendre signature et provenance, et durcir la chaîne elle-même.

Théorie 1/2 : les attaques sur la chaîne

La chaîne d'approvisionnement logicielle, c'est tout ce qui se trouve entre un commit et ce qui tourne : dépendances, outils de construction, actions de CI, registres. Les attaquants visent là parce qu'une compromission atteint des milliers d'utilisateurs. SolarWinds (révélé en décembre 2020) : un système de construction compromis pour livrer une mise à jour piégée. La porte dérobée de xz utils (CVE-2024-3094, découverte en mars 2024 par Andres Freund) : une identité de mainteneur construite pendant des années pour glisser du code malveillant dans une bibliothèque de compression utilisée par SSH sur beaucoup de distributions. Les incidents tj-actions (2025) et Trivy (2026) ont détourné des actions de CI.

Qu'est-ce qui rendait la porte dérobée de xz utils si dangereuse ?

  1. Elle était dans un outil peu utilisé
  2. Elle se trouvait dans une bibliothèque très répandue, atteignable via SSH sur beaucoup de systèmes, insérée par un mainteneur d'apparence fiable
Réponse

La confiance dans une petite dépendance omniprésente.

Théorie 2/2 : SBOM, signature, provenance, SLSA

  • Une SBOM (nomenclature logicielle, software bill of materials) liste chaque composant d'un artefact, dans un format normalisé (SPDX ou CycloneDX) ; Syft en produit une à partir d'une image.
  • Signature : cosign, de Sigstore, signe des images, aussi « sans clé » avec l'identité de la CI, si bien qu'un cluster peut refuser les images non signées.
  • Provenance : une déclaration signée de comment, où et à partir de quel commit un artefact a été construit. SLSA (Supply-chain Levels for Software Artifacts) définit des niveaux de ces garanties.
  • La chaîne elle-même : actions épinglées par empreinte, droits de jeton minimaux, aucun secret pour les pull requests venant de forks, branches protégées avec revue obligatoire.

Quel est le sigle de quatre lettres de la liste de tous les composants d'un artefact ?

Réponse

SBOM, la nomenclature logicielle.

Que prouve la signature d'une image ?

  1. Qui l'a produite, et qu'elle n'a pas été modifiée depuis
  2. Qu'elle n'a aucune vulnérabilité
Réponse

L'origine et l'intégrité, pas l'innocuité.

Pratique (30 min)

  1. Produisez une SBOM : syft hello-ops:dev -o cyclonedx-json > sbom.json (Syft installé depuis son README) ; comptez les paquets ; trouvez-y la version de Python.
  2. Scannez la SBOM au lieu de l'image (Trivy et Grype acceptent les SBOM) et comparez avec hier.
  3. Auditez vos workflows avec la liste ci-dessus : chaque action épinglée, droits minimaux, une règle de protection sur main qui exige la CI et une revue.
  4. Lisez le démarrage rapide de cosign ; notez comment marche la signature sans clé en CI.

Avec votre IA : « Évalue ma chaîne par rapport aux niveaux de construction SLSA : voici mes fichiers de workflow et mes réglages de protection de branche : [collez]. Dis-moi quel niveau j'atteins plausiblement, quelle exigence me manque pour le suivant, et donne le lien de la section de slsa.dev pour chacune afin que je vérifie. »

Le faire faire par un agent : un agent peut ajouter la production de SBOM et la signature au job d'image. Vous vérifiez encore la signature vous-même avec cosign verify et que la SBOM est attachée à l'image que vous déployez, pas à une autre construction.

Synthèse (10 min)

Trois lignes : ce qu'est la chaîne d'approvisionnement, trois vraies attaques, SBOM / signature / provenance. Puis racontez l'histoire de xz en deux phrases.

Jour 54 · 26/12 — Projet final 1 : conception et décisions

Objectif : choisir l'application et la cible du projet final, dessiner sa chaîne, et consigner vos décisions.

Théorie 1/2 : le cahier des charges

Le projet final mène une petite application du commit à la production par une chaîne documentée. L'application peut être hello-ops un peu grandie (un second point d'accès, un compteur dans Redis) ou une petite appli à vous : ce qui compte, c'est la chaîne, pas les fonctionnalités. Deux cibles, toutes deux sur votre machine :

  • A (recommandée) : GitOps sur kind. La CI teste, scanne et envoie l'image, puis met à jour l'étiquette d'image dans la surcouche de production du dépôt ; Argo CD, dans le cluster, récupère et déploie. Aucun accès à votre machine ne la quitte jamais.
  • B : une VM. Ansible déploie la pile Compose sur une deuxième VM, lancé par un runner auto-hébergé sur un miroir privé du dépôt (jour 19).

Pourquoi la cible A n'a-t-elle besoin d'aucun accès à votre machine dans la CI ?

  1. L'agent dans le cluster récupère depuis Git ; rien ne pousse dans le cluster
  2. Parce que kind n'a aucune sécurité
Réponse

Déploiement par récupération : le cluster va chercher, la CI n'entre jamais.

Théorie 2/2 : les registres de décisions d'architecture

Un ADR (architecture decision record, Michael Nygard, 2011) est un court fichier par décision importante : contexte, décision, conséquences. Des mois plus tard, il répond à « mais pourquoi avons-nous fait ça ? ». Rangez-les dans docs/adr/0001-….md.

Quelles sont les trois parties d'un ADR selon Nygard ?

  1. Problème, code, tests
  2. Contexte, décision, conséquences
Réponse

Contexte, décision, conséquences (plus un titre et un statut).

Quelle décision mérite un ADR ?

  1. Renommer une variable
  2. Corriger une faute de frappe
  3. Choisir le GitOps avec Argo CD plutôt que pousser avec kubectl
Réponse

Importante, difficile à défaire, utile à expliquer.

Pratique (30 min)

  1. Créez le dépôt final (par exemple hello-ops-prod, ou faites grandir hello-ops), avec les dossiers app/, k8s/ (ou ansible/), monitoring/, docs/adr/, postmortems/.
  2. Dessinez la chaîne (en texte ou en schéma) : push → analyse → tests → scan → construction → envoi de l'image → mise à jour de l'étiquette → déploiement → vérification. Pour chaque étape : l'outil, ce qui la fait échouer, ce qu'elle protège.
  3. Écrivez l'ADR 0001 (la cible, A ou B) et l'ADR 0002 (le schéma d'étiquettes).
  4. Ajoutez un README.md avec le but du projet et le schéma ; commitez.

Avec votre IA : « Voici la conception de ma chaîne et mes deux ADR : [collez]. Joue un ingénieur principal en revue de conception : pose-moi les cinq questions les plus dures sur les modes de défaillance (que se passe-t-il si le registre est indisponible, si Argo CD est arrêté, si une mauvaise image passe les tests…), une par une, et attends ma réponse à chacune. »

Synthèse (10 min)

Trois lignes : la chaîne que vous allez construire, votre cible et pourquoi, ce qu'est un ADR. Puis redessinez la chaîne de mémoire.

Jour 55 · 27/12 — Projet final 2 : intégration continue

Objectif : une chaîne qui analyse, teste, scanne et publie une image étiquetée par commit, et qui protège main.

Théorie 1/2 : l'ordre des jobs

Les échecs bon marché et probables d'abord, les coûteux en dernier ; ne publier que ce qui a tout passé ; une image construite une fois et promue, jamais reconstruite par environnement (ce que vous avez testé est ce que vous livrez).

lint ──┐
test ──┼──> image (construire, scanner, envoyer :SHA) ──> deploy (jour 56)
secrets┘

La préproduction et la production doivent-elles recevoir des images construites séparément à partir du même commit ?

  1. Oui, une construction par environnement
  2. Non : construire une fois, promouvoir la même image (même empreinte)
Réponse

Reconstruire, c'est livrer quelque chose que vous n'avez pas testé.

Théorie 2/2 : la protection de branche

La chaîne ne protège main que si l'on ne peut pas pousser directement sur main : une branche protégée exige une pull request, des vérifications de CI réussies et (en équipe) une revue. Même seul, elle vous empêche de pousser un correctif rapide qui saute tout.

La CI est verte sur les pull requests, mais vous pouvez encore pousser directement sur main. Main est-elle protégée ?

  1. Non : la protection de branche doit exiger les vérifications
  2. Oui, la CI suffit
Réponse

Sans la règle, la chaîne n'est qu'une suggestion.

Le scan d'image trouve une vulnérabilité critique corrigeable. La chaîne doit…

  1. envoyer l'image quand même
  2. sauter le scan
  3. échouer avant l'envoi
Réponse

Votre politique du jour 52 : échouer sur l'élevé et le critique corrigeables.

Pratique (30 min)

  1. Écrivez le workflow : jobs lint (ruff, shellcheck, actionlint), test (pytest), secrets (gitleaks), puis image (a besoin des trois ; construire, scanner avec votre seuil, envoyer :SHA ; sur main seulement).
  2. Ajoutez un test de fumée au job d'image : lancer l'image construite, interroger /health, échouer si ce n'est pas 200 (votre action du jour 51).
  3. Épinglez chaque action par empreinte ; posez permissions: contents: read en tête.
  4. Protégez main : pull request obligatoire, vérifications obligatoires. Testez : un push direct est refusé.

Avec votre IA : « Voici mon ci.yml final : [collez]. Vérifie-le avec cette liste et réponds par un tableau (point / respecté / ligne) : jobs du moins cher au plus cher ; image construite une fois ; publication sur main seulement ; test de fumée ; actions épinglées par empreinte ; droits minimaux par job ; aucun secret disponible pour les pull requests venant de forks. »

Le faire faire par un agent : vous avez écrit chaque morceau de cette chaîne à la main au module 2 ; un agent peut maintenant l'assembler. Vous relisez encore le diff complet, le lancez sur une pull request et sur main, et vérifiez vous-même l'étiquette et l'empreinte publiées.

Synthèse (10 min)

Trois lignes : l'ordre des jobs, construire une fois et promouvoir, la protection de branche. Puis redessinez le graphe des jobs de mémoire.

Jour 56 · 28/12 — Projet final 3 : déploiement continu

Objectif : chaque fusion sur main arrive seule en production, avec une barrière que vous contrôlez.

Théorie 1/2 : l'étape de déploiement de la cible A

Après le job d'image, un job deploy écrit la nouvelle étiquette dans k8s/overlays/prod/kustomization.yaml (son champ images: … newTag:) et la commite. Argo CD voit le commit et synchronise le cluster. Sur GitHub, un commit poussé avec le GITHUB_TOKEN du workflow ne déclenche pas de nouvelle exécution, ce qui évite une boucle sans fin. Un environnement GitHub nommé production avec un relecteur obligatoire transforme ce job en livraison continue (un clic) au lieu de déploiement, si vous voulez la barrière.

Qu'est-ce qui déploie la nouvelle image dans la cible A ?

  1. La CI lance kubectl apply
  2. Argo CD, après que la CI a commité la nouvelle étiquette dans Git
Réponse

Git change ; l'agent dans le cluster applique.

Théorie 2/2 : vérifier après le déploiement

Un déploiement est fini quand il est vérifié : le déploiement progressif est terminé, la vérification de santé répond, le SLI n'a pas baissé. Argo CD affiche « Synced » et « Healthy » ; le point d'accès de version montre la nouvelle empreinte ; le tableau de bord ne montre aucun pic d'erreurs. Sinon : annulez le commit d'étiquette dans Git, et Argo CD revient en arrière.

En GitOps, quelle commande Git ramène la production à l'étiquette précédente ?

Réponse

git revert du commit de mise à jour de l'étiquette (par une pull request si main est protégée).

Argo CD affiche Synced mais pas Healthy. Le déploiement est…

  1. pas fini : les nouveaux Pods ne sont pas prêts
  2. fini
Réponse

Synced veut dire appliqué ; Healthy veut dire qui marche.

Pratique (30 min)

  1. Installez Argo CD dans votre cluster kind en suivant sa page de prise en main ; créez une Application qui pointe vers k8s/overlays/prod de votre dépôt public, avec synchronisation automatique.
  2. Ajoutez le job deploy (a besoin d'image, main seulement, permissions: contents: write) : il remplace newTag par l'empreinte du commit et pousse le commit.
  3. Fusionnez un changement visible (le message de /) : regardez la CI, puis Argo CD, puis curl par un port-forward : la nouvelle version répond.
  4. Revenez en arrière avec git revert du commit d'étiquette ; vérifiez que l'ancienne version revient. (Cible B : la même chose avec un play Ansible lancé par le runner auto-hébergé, et --check --diff sur les pull requests.)

Avec votre IA : « Voici mon job deploy et le manifeste de mon Application Argo CD : [collez]. Déroule ce qui se passe, étape par étape avec le composant responsable, depuis une fusion sur main jusqu'à un Pod prêt avec la nouvelle image. Puis nomme deux façons dont cette chaîne peut échouer en silence et comment je m'en apercevrais. »

Le faire faire par un agent : un agent peut suivre un déploiement de bout en bout et annoncer « déployé et vérifié » ou « revenu en arrière ». C'est vous qui définissez ce que « vérifié » veut dire (quel point d'accès, quel seuil de SLI), et vous regardez le tableau de bord après les premiers déploiements automatiques.

Synthèse (10 min)

Trois lignes : comment l'étiquette atteint le cluster, Synced ou Healthy, retour arrière par revert. Puis redessinez la chaîne de déploiement de mémoire.

Jour 57 · 29/12 — Projet final 4 : observabilité et SLO

Objectif : l'appli en production est mesurée, a un tableau de bord, un SLO et une alerte avec son runbook.

Théorie 1/2 : à quoi ressemble « fini »

La production est observable quand, pour toute alerte, on va de la notification au tableau de bord, du tableau de bord aux journaux et traces des requêtes en échec, et de là au runbook. Chaque étape est un lien, pas une recherche.

Une alerte se déclenche. Que doit contenir sa notification ?

  1. Seulement son nom
  2. Ce qui ne va pas, à quel point, et les liens vers le tableau de bord et le runbook
Réponse

Tout ce dont la personne d'astreinte a besoin dans la première minute.

Théorie 2/2 : la supervision dans le cluster

Dans Kubernetes, Prometheus découvre ses cibles par l'API (des Pods annotés, ou des objets ServiceMonitor avec le Prometheus Operator). Pour ce projet, la configuration la plus simple qui marche suffit : la pile Compose de supervision des jours 44 à 48 qui collecte l'appli par un NodePort ou un port-forward, ou Prometheus déployé dans le cluster avec un job de collecte statique. Une simplicité que vous comprenez vaut mieux qu'un chart que vous ne savez pas déboguer.

Vous pouvez installer un gros chart de supervision que vous ne comprenez pas, ou une petite configuration que vous avez construite. Pour un projet de portfolio ?

  1. La petite, documentée, que vous savez expliquer
  2. La grosse, elle fait plus professionnel
Réponse

Un recruteur demandera comment elle marche.

L'alerte SLO n'a pas de runbook. Avant que le projet soit fini, vous…

  1. supprimez l'alerte
  2. la laissez
  3. écrivez le runbook et le liez dans les annotations de l'alerte
Réponse

Pas d'alerte sans runbook.

Pratique (30 min)

  1. Pointez Prometheus vers l'appli de production ; vérifiez que la cible est up.
  2. Provisionnez le tableau de bord des signaux d'or (jour 46) et un panneau SLO qui montre le budget d'erreur restant.
  3. Écrivez le SLO et son alerte de brûlure (jour 49), avec les annotations runbook_url et dashboard.
  4. Écrivez docs/runbooks/slo-burn.md ; vérifiez que chaque lien de l'alerte fonctionne.

Avec votre IA : « Voici mon SLO, ma règle d'alerte et mon runbook : [collez]. Joue l'ingénieur d'astreinte qui reçoit cette alerte à 3 h du matin sans autre contexte : dis-moi, étape par étape, ce que tu ferais avec ces seuls documents, et où tu bloques. »

Le faire faire par un agent : un agent peut vérifier que chaque alerte a un lien de runbook qui répond et que chaque panneau a des données. Vous relisez encore le runbook comme à moitié endormi : il doit pouvoir se suivre sans réfléchir.

Synthèse (10 min)

Trois lignes : alerte → tableau de bord → journaux et traces → runbook, le SLO, l'alerte de brûlure. Puis écrivez les annotations de l'alerte de mémoire.

Jour 58 · 30/12 — Projet final 5 : exercice de panne et postmortem

Objectif : casser la production exprès, détecter, atténuer, et écrire le postmortem.

Théorie 1/2 : exercices de panne et ingénierie du chaos

Un exercice de panne (game day) est un exercice prévu où une équipe injecte une défaillance pour tester sa détection, ses runbooks et ses réflexes. Netflix a rendu l'idée célèbre avec Chaos Monkey (2011), qui arrête au hasard des instances en production pour que les systèmes soient conçus pour y survivre ; les principes de l'ingénierie du chaos décrivent la méthode : poser une hypothèse sur l'état stable, injecter une défaillance réaliste, chercher une différence, garder un rayon d'impact petit.

Qu'écrivez-vous avant d'injecter la défaillance ?

  1. Le postmortem
  2. L'hypothèse : ce que vous attendez du système et des alertes
Réponse

Sans hypothèse, on ne peut rien apprendre du résultat.

Théorie 2/2 : trois scénarios

  • Mauvaise version : fusionner un changement dont /health échoue (le test de fumée l'attrape-t-il ? Si vous le contournez, le déploiement se bloque-t-il et l'alerte part-elle ?).
  • Dépendance morte : arrêter Redis (l'appli se dégrade-t-elle ou plante-t-elle ? la sonde de disponibilité réagit-elle ?).
  • Épuisement de ressources : baisser la limite mémoire jusqu'à OOMKilled (le tableau de bord le montre-t-il ? l'alerte part-elle ?).

Votre hypothèse disait que l'alerte partirait en 5 minutes ; elle n'est jamais partie. L'exercice…

  1. a réussi : il a trouvé un trou à combler
  2. a échoué : recommencez jusqu'à ce qu'elle parte
Réponse

Trouver le trou sans danger, c'est le but.

Comment garder petit le rayon d'impact d'un exercice de panne ?

  1. Le lancer le vendredi soir
  2. Injecter toutes les défaillances à la fois
  3. Une défaillance à la fois, avec une condition d'arrêt et un retour arrière prêt
Réponse

Maîtrisé, une variable, avec une sortie.

Pratique (30 min)

  1. Choisissez un scénario. Écrivez l'hypothèse (ce que feront le système, les alertes et vous, en combien de temps).
  2. Lancez-le avec une boucle de curl qui mesure l'impact ; tenez une chronologie ; suivez votre runbook.
  3. Écrivez postmortems/2026-12-30-game-day.md avec le modèle du jour 51, y compris là où l'hypothèse était fausse.
  4. Réglez une action aujourd'hui et liez-la.

Avec votre IA : « Je prépare un exercice de panne sur mon cluster kind. Scénario : [décrivez]. Conteste mon hypothèse et ma condition d'arrêt : liste ce qui pourrait se passer autrement que prévu, et ce que je devrais mesurer pour le savoir. Ne propose pas d'autres scénarios. »

Le faire faire par un agent : un agent peut lancer l'injection de panne et les mesures selon un calendrier que vous fixez, et tenir la chronologie. Vous menez encore la réponse vous-même : le but de l'exercice est d'entraîner des personnes, pas l'agent.

Synthèse (10 min)

Trois lignes : ce qu'est un exercice de panne, hypothèse et rayon d'impact, ce que vous avez appris aujourd'hui. Puis listez les parties de votre postmortem de mémoire.

Jour 59 · 31/12 — Projet final 6 : documentation et portfolio

Objectif : rendre le projet lisible par un inconnu en cinq minutes, et clore le parcours.

Théorie 1/2 : le README qui obtient un entretien

Un recruteur ou un ingénieur ouvre votre dépôt quelques minutes. Le haut du README répond : ce que c'est (une phrase), le schéma de la chaîne, comment le lancer en local (des commandes à copier-coller qui marchent), ce qui est testé et scanné, comment il est déployé et ramené en arrière, comment il est observé (une capture du tableau de bord), et les liens vers les ADR, les runbooks et les postmortems. Des limites honnêtes (« un seul nœud, pas de TLS ») se lisent mieux que des promesses.

Qu'est-ce qui impressionne le plus un relecteur dans le projet DevOps d'un junior ?

  1. Le nombre d'outils
  2. Une chaîne claire, des commandes qui marchent, et un postmortem qui montre comment vous pensez
Réponse

La compréhension se voit ; les listes d'outils, non.

Théorie 2/2 : révision du parcours

Quelle métrique DORA votre chaîne finale améliore-t-elle le plus directement ?

  1. Le délai des changements
  2. Les lignes de code
Réponse

L'automatisation raccourcit le temps du commit à la production (et permet des déploiements fréquents).

Un plan montre la destruction d'une ressource que vous n'attendiez pas. Vous…

  1. appliquez pour voir
  2. vous arrêtez et cherchez pourquoi avant d'appliquer
Réponse

Lire le plan, toujours.

Un incident est atténué. Ensuite ?

  1. Trouver qui l'a causé
  2. L'oublier
  3. Un postmortem sans reproche avec des actions attribuées
Réponse

Apprendre, corriger le système.

Exercice généré sans fin (JavaScript requis) : les droits, une dernière fois.

Exercice généré sans fin (JavaScript requis) : les codes HTTP, une dernière fois.

Pratique (30 min)

  1. Écrivez le README final comme décrit ; ajoutez une capture du tableau de bord (sans noms ni adresses internes dedans).
  2. Suivez votre propre README sur un clone propre, commande par commande ; corrigez ce qui casse.
  3. Épinglez vos quatre livrables et le projet final sur votre profil de forge, avec une phrase chacun.
  4. Cochez la liste de fin de parcours sur la page du parcours ; pour chaque case qui ne se coche pas, notez la séance à refaire.

Avec votre IA : « Joue un recruteur pour un poste DevOps ou SRE junior. Voici le README de mon projet final : [collez]. Pose-moi huit questions d'entretien dessus, une par une, en mélangeant "pourquoi as-tu choisi" et "que se passe-t-il si". Après chaque réponse, dis-moi ce qu'une réponse solide aurait ajouté. »

Le faire faire par un agent : désormais, laissez les agents faire les parties répétitives de ce travail, comme chaque séance l'a montré. Continuez à faire à la main, régulièrement, ce que vous devez savoir juger : lire un plan, un diff, une trace et un postmortem.

Synthèse (10 min)

Écrivez trois lignes sur ce que vous savez faire aujourd'hui et que vous ne saviez pas le 3 novembre. Puis choisissez la suite : Kubernetes en profondeur, un fournisseur cloud, la sécurité, ou le SRE.

Sources

Utile ? Dites-nous ce qu'il faut mesurer ensuite.