Monitoring Kubernetes avec Prometheus et Grafana : guide complet 2025
← Retour au blogDevOps

Monitoring Kubernetes avec Prometheus et Grafana : guide complet 2025

12 mai 202512 min de lectureKubernetesPrometheusGrafana

Un cluster Kubernetes sans observabilité est une bombe à retardement. Découvrez comment mettre en place un stack de monitoring complet avec Prometheus, Grafana, Loki et AlertManager.

Les trois piliers de l'observabilité Kubernetes

Un cluster Kubernetes sans observabilité est une bombe à retardement. Les pannes se produisent — un pod en CrashLoopBackOff, un node en MemoryPressure, un ingress qui cesse de répondre. Sans monitoring, vous apprenez l'incident via les utilisateurs. Avec un stack d'observabilité complet, vous êtes alerté avant que l'impact soit visible.

L'observabilité Kubernetes repose sur trois piliers complémentaires :

  • Métriques (Prometheus) : séries temporelles numériques — CPU, mémoire, nombre de requêtes, latence, taux d'erreur
  • Logs (Loki) : événements textuels structurés ou non-structurés des applications et du système
  • Traces (Tempo / Jaeger) : suivi des requêtes à travers plusieurs microservices

Grafana unifie la visualisation de ces trois sources dans un tableau de bord unique, avec corrélation entre métriques et logs (et traces si configuré).

Installation avec kube-prometheus-stack

kube-prometheus-stack est le chart Helm standard qui déploie Prometheus Operator, Grafana, Alertmanager, et des règles d'alerting préconfigurées pour Kubernetes. C'est le point de départ recommandé pour tout nouveau cluster.

helm repo add prometheus-community   https://prometheus-community.github.io/helm-charts
helm repo update

helm install kube-prometheus-stack   prometheus-community/kube-prometheus-stack   --namespace monitoring   --create-namespace   --version 61.0.0   --values values.yaml
# values.yaml production-ready
grafana:
  adminPassword: "changez-moi-avec-un-secret"
  persistence:
    enabled: true
    storageClassName: gp3
    size: 10Gi
  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-prod
    hosts: ["grafana.monapp.fr"]

prometheus:
  prometheusSpec:
    retention: 30d
    retentionSize: "40GB"
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: gp3
          resources:
            requests:
              storage: 50Gi
    resources:
      requests: { cpu: 500m, memory: 2Gi }
      limits: { memory: 4Gi }

alertmanager:
  alertmanagerSpec:
    storage:
      volumeClaimTemplate:
        spec:
          storageClassName: gp3
          resources:
            requests:
              storage: 5Gi
  config:
    route:
      group_by: [alertname, cluster, namespace]
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 4h
      receiver: slack-critical
    receivers:
      - name: slack-critical
        slack_configs:
          - channel: '#alerts-prod'
            api_url: "YOUR_SLACK_WEBHOOK"
            title: '[{{ .Status }}] {{ .GroupLabels.alertname }}'

Métriques applicatives personnalisées

Les métriques Kubernetes système ne suffisent pas. Il faut instrumenter vos applications avec des métriques métier :

// Node.js — instrumentation avec prom-client
const promClient = require('prom-client');

const httpRequestsTotal = new promClient.Counter({
  name: 'http_requests_total',
  help: 'Total des requêtes HTTP',
  labelNames: ['method', 'route', 'status'],
});

const httpRequestDuration = new promClient.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Durée des requêtes HTTP en secondes',
  labelNames: ['method', 'route'],
  buckets: [0.01, 0.05, 0.1, 0.5, 1, 2, 5],
});

// Middleware Express
app.use((req, res, next) => {
  const end = httpRequestDuration.startTimer();
  res.on('finish', () => {
    httpRequestsTotal.inc({ method: req.method, route: req.route?.path, status: res.statusCode });
    end({ method: req.method, route: req.route?.path });
  });
  next();
});

// Endpoint /metrics pour Prometheus
app.get('/metrics', async (req, res) => {
  res.set('Content-Type', promClient.register.contentType);
  res.end(await promClient.register.metrics());
});

Règles d'alerting critiques

groups:
  - name: kubernetes-critical
    rules:
      - alert: PodCrashLooping
        expr: rate(kube_pod_container_status_restarts_total[5m]) * 60 * 5 > 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Pod {{ $labels.namespace }}/{{ $labels.pod }} crash-loop"
          description: "{{ $value }} restarts en 5 min"

      - alert: NodeDiskPressure
        expr: kube_node_status_condition{condition="DiskPressure",status="true"} == 1
        for: 2m
        labels:
          severity: critical

      - alert: PodMemoryUsageHigh
        expr: |
          container_memory_working_set_bytes{container!=""}
          / on(pod, namespace) kube_pod_container_resource_limits{resource="memory"}
          > 0.9
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "{{ $labels.namespace }}/{{ $labels.pod }} utilise >90% de sa limite mémoire"

      - alert: HighErrorRate
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
          / sum(rate(http_requests_total[5m])) by (service) > 0.05
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Taux d'erreur >5% sur {{ $labels.service }}"

Logs avec Loki et Promtail

helm install loki grafana/loki-stack   --namespace monitoring   --set loki.persistence.enabled=true   --set loki.persistence.storageClassName=gp3   --set loki.persistence.size=20Gi   --set promtail.enabled=true

# Requête LogQL dans Grafana pour voir les erreurs d'une app
{namespace="production", app="api"} |= "ERROR" | json | line_format "{{.level}} {{.message}}"

Dashboards Grafana recommandés

  • ID 15760 : Kubernetes cluster overview (CPU, mémoire, pods, namespaces)
  • ID 13770 : Node Exporter Full (métriques détaillées des nœuds)
  • ID 14205 : Kubernetes API Server (latence, taux d'erreur API)
  • ID 15358 : Kubernetes Nginx Ingress (latence, codes HTTP, trafic)
  • ID 12559 : Loki Logs Explorer (corrélation métriques + logs)

SLOs et error budgets

Les dashboards et alertes n'ont de valeur que si vous définissez des SLOs (Service Level Objectives) clairs. Exemple pour une API :

  • Disponibilité : 99,9 % sur 30 jours (= 43,8 min d'indisponibilité maximum)
  • Latence P99 : < 500 ms pour 99 % des requêtes
  • Taux d'erreur : < 0,1 % sur 5 minutes

Configurez des alertes sur le taux de consommation de votre error budget — si vous consommez 10 % du budget en 1 jour, c'est une alerte. Si vous en consommez 100 % en 1 heure, c'est critique.

Conclusion

Un stack Prometheus/Grafana/Loki peut être opérationnel en moins d'une heure avec kube-prometheus-stack. Mais l'observabilité ne se limite pas aux outils — elle nécessite de définir vos SLOs, d'instrumenter vos applications avec des métriques métier, et de s'assurer que les alertes déclenchent les bons processus de réponse. Un cluster bien monitoré transforme les incidents de surprises en événements gérés.

← Retour au blog