infra / kubernetes
Observabilité : logs et métriques
Explication
Ce que vous allez apprendre
- Comprendre pourquoi les logs d'un conteneur doivent toujours passer par stdout/stderr
- Diagnostiquer un Pod en
CrashLoopBackOffavec le flag--previous - Utiliser
kubectl toppour obtenir une vue instantanée de la consommation CPU/mémoire - Comprendre le rôle de Prometheus et Grafana pour une observabilité dans la durée
- Lire les événements du cluster avec
kubectl get eventspour trouver une cause racine
Dans quel contexte ?
Un Pod redémarre en boucle en pleine nuit, déclenchant une alerte. Un développeur de garde lance kubectl logs mon-pod et ne voit... presque rien : le conteneur vient tout juste de redémarrer et n'a encore rien écrit dans ses logs. Sans connaître le flag --previous, il perdrait un temps précieux à chercher la cause au mauvais endroit. Cette leçon rassemble les réflexes de diagnostic indispensables — logs, métriques, événements — pour comprendre rapidement ce qui se passe réellement dans un cluster, au-delà de sa simple définition YAML.
Voir ce qui se passe réellement, pas seulement ce qu'on a défini
D'abord, toutes les leçons précédentes ont montré comment définir un état désiré et laisser Kubernetes le maintenir. Mais quand quelque chose ne se passe pas comme prévu, comme un Pod qui redémarre en boucle, il faut pouvoir observer ce qui se passe réellement.
Ce que rassemble l'observabilité
C'est le rôle de l'observabilité : rassembler logs, métriques et événements pour comprendre l'état vivant du système, pas seulement sa définition YAML.
| Outil | Ce qu'il révèle |
|---|---|
kubectl logs | Les logs du conteneur actuel (stdout/stderr) |
kubectl logs --previous | Les logs du conteneur juste avant son dernier crash |
kubectl top | Un instantané de consommation CPU/mémoire (nécessite metrics-server) |
| Prometheus + Grafana | Des métriques collectées et visualisées dans la durée |
kubectl get events | L'historique des décisions prises par Kubernetes lui-même |
Prérequis
kubectl top réutilise metrics-server, déjà installé pour le HPA en début de cette partie du cours : si cette brique n'est pas encore en place, revois la leçon sur le scaling automatique avant de continuer.
Une convention à respecter absolument
Un principe central des applications conteneurisées est d'écrire leurs logs directement sur la sortie standard, stdout/stderr, jamais dans un fichier interne au conteneur.
Pourquoi cette convention est si importante
Un fichier écrit dans le conteneur disparaît définitivement quand le Pod est détruit, alors que Kubernetes capture automatiquement tout ce qui transite par stdout/stderr et le rend accessible via kubectl logs.
Un Pod qui redémarre en boucle : un cas particulier
Face à un Pod en CrashLoopBackOff, qui redémarre en boucle, consulter les logs du conteneur actuel ne sert souvent à rien : il vient tout juste de redémarrer et n'a encore rien loggé.
Bonne pratique
Face à un CrashLoopBackOff, le réflexe à avoir immédiatement est kubectl logs <pod> --previous : il récupère les logs du conteneur juste avant son dernier crash, l'endroit où se trouve presque toujours la vraie cause du problème.
Le réflexe à avoir dans ce cas précis
Le flag --previous récupère les logs du conteneur juste AVANT son dernier crash. C'est l'outil de diagnostic indispensable dans cette situation, à avoir systématiquement en tête.
Des métriques pour une vue d'ensemble
kubectl top, qui nécessite metrics-server déjà vu pour le HPA, donne une vue rapide de consommation CPU/mémoire, mais reste un instantané limité dans le temps.
Aller plus loin dans la durée
Une stack plus complète, Prometheus pour collecter des métriques dans la durée et Grafana pour les visualiser, permet une observabilité bien au-delà du simple instantané.
Ne pas négliger les événements du cluster
Enfin, les événements du cluster, kubectl get events, racontent l'histoire des décisions prises par Kubernetes : échec de scheduling, manque de ressources, image introuvable. Ils révèlent souvent la cause racine avant même d'ouvrir les logs applicatifs.
Maintenant que tu sais observer le cluster, la leçon suivante s'attaque à un risque de sécurité souvent ignoré : le réseau totalement ouvert par défaut entre tous les Pods.
Commandes & code
Observabilité
# Logs : premier réflexe de debug
kubectl logs <pod>
kubectl logs <pod> -c <conteneur> # pod multi-conteneurs
kubectl logs <pod> --previous # logs du conteneur AVANT son dernier crash
kubectl logs -l app=api --all-containers --prefix -f # tous les Pods d'un label, en direct
kubectl logs deployment/api-deployment --since=1h
# Métriques (nécessite metrics-server)
kubectl top nodes
kubectl top pods
kubectl top pods --containers -l app=api# Format de logs structurés recommandé côté application (JSON, un log par ligne sur stdout)
# {"level":"info","msg":"request handled","path":"/api/users","status":200,"duration_ms":42}
#
# Les conteneurs doivent écrire sur stdout/stderr : Kubernetes/Docker capturent ce flux,
# PAS de fichiers de logs à l'intérieur du conteneur (perdus à la destruction du Pod).# Stack d'observabilité typique : Prometheus (métriques) + Grafana (dashboards) + Loki (logs)
# ServiceMonitor : indique à Prometheus Operator comment scraper un Service
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: api-monitor
labels:
release: prometheus
spec:
selector:
matchLabels:
app: api
endpoints:
- port: metrics
path: /metrics
interval: 30s# Exposer des métriques Prometheus depuis l'application (exemple Python)
from prometheus_client import Counter, Histogram, generate_latest
REQUEST_COUNT = Counter("http_requests_total", "Total requests", ["method", "status"])
REQUEST_LATENCY = Histogram("http_request_duration_seconds", "Latence des requêtes")
@app.route("/metrics")
def metrics():
return generate_latest()# Événements du cluster : souvent la vraie cause d'un problème (OOMKilled, FailedScheduling...)
kubectl get events --sort-by=.lastTimestamp -A | tail -30
# Débogage réseau/process directement dans un conteneur "de secours" attaché au Pod
kubectl debug -it <pod> --image=busybox --target=<conteneur>Résumé
- Toujours logger sur stdout/stderr, jamais dans un fichier interne au conteneur.
kubectl logs --previousest indispensable pour diagnostiquer un CrashLoopBackOff.metrics-serveralimentekubectl topet le HPA ; Prometheus/Grafana pour l'observabilité poussée.kubectl get events --sort-byrévèle souvent la cause racine avant même les logs applicatifs.
Exercices pratiques
Mission : trouver la cause racine avant que l'alerte ne réveille tout le monde
Objectif : Diagnostiquer un Pod en CrashLoopBackOff en combinant logs, événements et métriques, sans se limiter au premier réflexe insuffisant.
Contexte
Une alerte se déclenche en pleine nuit : le Pod api-7d9f-xk2m1 redémarre en boucle. Le développeur de garde lance kubectl logs api-7d9f-xk2m1 et n'obtient presque rien, le conteneur vient tout juste de redémarrer et n'a rien écrit dans ses logs actuels. Il doit rassembler plusieurs sources d'information, pas une seule, pour comprendre ce qui se passe réellement avant de réveiller le reste de l'équipe.