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.
