Aller au contenu

Module 4c · Observabilité

Objectifs

  • Distinguer les 3 piliers : métriques, logs, événements (et un mot des traces).
  • Lire la consommation CPU/mémoire des pods et nœuds (metrics-server + k9s).
  • Exploiter logs et events pour diagnostiquer - le réflexe debug.
  • Durée : ~1 h 15 · Pré-requis : Module 4b.

Observer quoi ?

Pilier Question Outil de base
Métriques « combien ? » (CPU, mémoire, nb de pods) metrics-server, kubectl top, :pulses
Logs « qu'a dit l'application ? » kubectl logs, k9s l
Événements « qu'a fait Kubernetes ? » kubectl get events, describe
Traces « par où est passée la requête ? » (hors socle : Jaeger/Tempo)

Métriques - metrics-server

metrics-server collecte CPU/mémoire et alimente kubectl top + l'autoscaling.

kubectl top nodes
kubectl top pods -A

Si top renvoie une erreur

metrics-server n'est peut-être pas installé sur le cluster. Sur la sandbox il l'est en général ; sinon : kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml (en lab, on ajoute parfois --kubelet-insecure-tls).

Dans k9s : la vue :pods affiche des colonnes CPU/MEM en temps réel, et :pulses donne un tableau de bord global (santé du cluster en un coup d'œil).

C'est aussi metrics-server qui nourrit le HPA (HorizontalPodAutoscaler) : « maintiens ce deployment entre 2 et 10 réplicas pour viser 70 % de CPU » - Kubernetes ajuste alors le nombre de pods tout seul, à partir de ces métriques. Pas de metrics-server → pas d'autoscaling.

Logs

l           ← logs du pod (k9s)
f           ← plein écran
0/1/2…      ← fenêtre temporelle (depuis le début / dernières minutes)
/erreur     ← filtre les lignes contenant "erreur"
kubectl logs <pod> -f                 # suivi
kubectl logs <pod> -c <conteneur>     # pod multi-conteneurs
kubectl logs <pod> --previous         # logs du conteneur AVANT son dernier crash (essentiel !)

--previous sauve la vie

Un pod en CrashLoopBackOff a déjà redémarré : ses logs actuels sont vides ou inutiles. --previous montre ce qui s'est passé juste avant le crash.

Événements - la mémoire du cluster

Les events racontent les décisions de Kubernetes (scheduling, pull d'image, probes…).

kubectl get events --sort-by .lastTimestamp
kubectl describe pod <pod>     # events en bas (k9s : touche d)

C'est le premier endroit où regarder quand un pod ne démarre pas : FailedScheduling, ImagePullBackOff, Unhealthy (probe qui échoue)… tout est là.

Probes : rendre l'état observable

Une app peut tourner sans être prête. Les probes informent Kubernetes :

livenessProbe:        # redémarre le conteneur s'il est bloqué
  httpGet: { path: /healthz, port: 8080 }
  initialDelaySeconds: 5
  periodSeconds: 10
readinessProbe:       # retire le pod du Service tant qu'il n'est pas prêt
  httpGet: { path: /ready, port: 8080 }
graph TD
    P[Pod en Running] --> LP{liveness<br/>« es-tu vivant ? »}
    P --> RP{readiness<br/>« prêt à servir ? »}
    LP -->|échoue| K[le kubelet REDÉMARRE<br/>le conteneur · RESTARTS++]
    RP -->|échoue| E[retiré des Endpoints<br/>plus de trafic · tourne toujours]

Les conséquences d'une probe qui échoue ne sont pas les mêmes selon son type - tu vas le constater toi-même à l'exercice 4c.2 (et dans le TP 03c-probes).

Le lien avec la carte d'assemblage du module 3 : la readiness est ce qui décide si un pod entre dans les Endpoints d'un Service. liveness agit sur le pod (le redémarrer), readiness agit sur le trafic (le brancher ou non).

Il existe une troisième probe, pour un cas précis : la startupProbe suspend les deux autres le temps du démarrage. Sans elle, une app lente à démarrer (JVM, grosse base à charger) se fait tuer par sa liveness avant d'avoir fini de booter - et redémarre en boucle sans avoir jamais été en panne. Un CrashLoopBackOff sur une app réputée lente : penses-y.

Pratique

Les TP de ce module, dans le terminal de ta sandbox - une fois la lecture faite :

tp start 03c-probes     # readiness (trafic) vs liveness (redémarrage), endpoints, RESTARTS
tp start yaml-debug-3   # consolidation : réparer une readinessProbe fausse (manifeste YAML)

fais la manip puis tp check (ou tp watch pour l'auto-validation) · tp hint / tp solution si tu bloques.

Pour t'entraîner librement à côté :

Exercice 4c.1 - Qui consomme ?

  1. kubectl top pods -A : repère le pod le plus gourmand en mémoire.
  2. Dans k9s, retrouve-le et lis son describe : a-t-il des limits ?
  3. Discute : que se passerait-il s'il dépassait sa limite mémoire ? (OOMKill)

Exercice 4c.2 - Lire un pod qui crashe (logs --previous)

kubectl run boucle --image busybox:1.36 -- sh -c 'echo je-demarre; exit 1'
Il redémarre en boucle (CrashLoopBackOff). Applique les 3 piliers :

  1. Events : kubectl describe pod boucle → la section Events montre les redémarrages.
  2. Logs : kubectl logs boucle --previous → ce qu'a affiché l'app avant de mourir (--previous lit le conteneur précédent ; sans lui, tu lis le vide).
  3. Supprime : kubectl delete pod boucle.

(Le describe d'un pod à l'image cassée, tu l'as vu au module 2 ; les probes, c'est le TP 03c-probes.)

Ce qu'il faut retenir

  • 3 piliers : métriques (combien), logs (ce que dit l'app), events (ce que fait k8s).
  • Pod qui crashe → kubectl logs --previous + describe/events avant tout.
  • kubectl top / :pulses pour la consommation ; metrics-server doit être présent.
  • Les probes rendent l'état réel d'une app observable (et pilotent liveness/readiness).

Quiz éclair

Teste-toi : réponds de tête, puis déplie.

1. Quels sont les 3 piliers de l'observabilité k8s ?

Métriques (combien : CPU/mémoire), logs (ce que dit l'application), events (ce que fait Kubernetes : scheduling, pull, probes).

2. Un pod redémarre en boucle. Quelle option de kubectl logs ?

--previous : montre les logs du conteneur avant son dernier crash (les logs actuels sont souvent vides).

3. Une readinessProbe échoue. Que se passe-t-il pour le pod ?

Il est retiré du Service (plus de trafic) sans crasher : il tourne mais reste NOT READY. Invisible sans regarder describe/events.

➡️ Suite : Module 4d - Sécurité