Retour au cours

infra / kubernetes

Observabilité : logs et métriques

Leçon 181 exercice

Explication

Ce que vous allez apprendre

  • Comprendre pourquoi les logs d'un conteneur doivent toujours passer par stdout/stderr
  • Diagnostiquer un Pod en CrashLoopBackOff avec le flag --previous
  • Utiliser kubectl top pour 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 events pour 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.

OutilCe qu'il révèle
kubectl logsLes logs du conteneur actuel (stdout/stderr)
kubectl logs --previousLes logs du conteneur juste avant son dernier crash
kubectl topUn instantané de consommation CPU/mémoire (nécessite metrics-server)
Prometheus + GrafanaDes métriques collectées et visualisées dans la durée
kubectl get eventsL'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é

bash
# 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
yaml
# 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).
yaml
# 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
python
# 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()
bash
# É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 --previous est indispensable pour diagnostiquer un CrashLoopBackOff.
  • metrics-server alimente kubectl top et le HPA ; Prometheus/Grafana pour l'observabilité poussée.
  • kubectl get events --sort-by révèle souvent la cause racine avant même les logs applicatifs.

Exercices pratiques

1 disponible
1

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.

Résoudre l’exercice →