La surveillance et l'alerting Kubernetes doivent vous permettre de répondre rapidement à trois questions : la plateforme est-elle saine, les charges de travail sont-elles saines, et les utilisateurs ressentent-ils un impact ? Ce guide pratique montre quoi mesurer, comment installer une pile fiable mais légère, quels alertes démarrer, comment vérifier et dépanner, et comment récupérer quand quelque chose ne va pas. Vous terminerez avec un projet pilote sûr à exécuter dans un seul cluster et facile à étendre.
Inventaire des Versions et de l'Environnement
Environnement d'exemple (ajustez selon votre réalité) :
- Kubernetes : v1.27 à v1.29
- Prometheus : v2.46+ (instance unique pour le pilote)
- Alertmanager : v0.26+
- kube-state-metrics : v2.10+
- node-exporter : v1.6+
- Grafana : v10+
Prérequis :
- Un rôle cluster-admin ou RBAC équivalent pour créer un espace de noms monitoring, installer des graphiques Helm ou des manifestes, et créer des ClusterRoles.
- Accès réseau pour que Prometheus puisse scraper les cibles sur les IPs du cluster. Si vous utilisez des NetworkPolicies, autorisez le scraping depuis l'espace de noms monitoring vers node-exporter, kube-state-metrics et les composants Kubernetes.
- Stockage : commencez avec 10 à 20 Gi pour le volume persistant Prometheus avec une rétention de 24 à 48h en pilote. Augmentez ensuite.
- Synchronisation temporelle : les nœuds doivent avoir NTP activé pour éviter les timestamps décalés.
Périmètre sûr pour un premier pilote :
- Cluster unique, espace de noms unique : monitoring.
- Cibles principales uniquement : kube-state-metrics, node-exporter, apiserver, kubelet, et charges de travail par défaut dans 1 à 2 espaces de noms.
- Une seule source de données Grafana (Prometheus), un dossier de tableaux de bord, et un petit ensemble d'alertes.
Quoi Surveiller et Pourquoi
Commencez avec le plus petit ensemble de métriques à fort signal qui expliquent la plupart des incidents. Étendez au fur et à mesure que vous apprenez.
| Couche | Métriques ou événements à fort signal | Pourquoi c'est important |
|---|---|---|
| Plan de contrôle | apiserver_request_total, apiserver_request_duration_seconds, apiserver_storage_objects, scheduler_pending_pods | Détecter les erreurs API, les pics de latence et les files d'attente d'ordonnancement qui bloquent les déploiements |
| Nœuds | node_cpu_seconds_total, node_memory_MemAvailable_bytes, node_filesystem_avail_bytes, kube_node_status_condition (Ready, DiskPressure) | Repérer l'épuisement et la pression des nœuds avant que les pods ne soient expulsés ou échouent |
| Charges de travail | container_cpu_usage_seconds_total, container_memory_working_set_bytes, kube_pod_container_status_restarts_total, kube_deployment_status_replicas_unavailable | Identifier les dérives CPU/mémoire et les boucles de crash qui impactent les services |
| Réseau | node_network_receive_errs_total, node_network_transmit_errs_total, RTT réseau pod si disponible | Identifier les erreurs de paquets et le trafic est-ouest dégradé |
| Stockage | kubelet_volume_stats_used_bytes, kubelet_volume_stats_capacity_bytes, statut persistentvolumeclaim | Prévenir les échecs d'écriture et la perte de données quand les PVC se remplissent |
| Ordonnancement/Auto-scaling | kube_pod_status_phase, kube_horizontalpodautoscaler_status_desired_replicas | Expliquer les arriérés et les désaccords d'échelle |
| Événements/Logs | CrashLoopBackOff, OOMKilled, ImagePullBackOff, back-off restarting | Contexte rapide quand les métriques montrent des symptômes |
Notes :
- Privilégiez les taux et ratios plutôt que les compteurs absolus (ex: rate(apiserver_request_total[5m]) avec filtres sur les codes d'erreur) pour éviter les faux positifs.
- Utilisez les labels avec parcimonie dans les requêtes. Filtrez par espace de noms ou application quand possible.
Chemin de Configuration Sûr
Ce chemin déploie une pile à portée limitée et à faible risque dans un espace de noms dédié. Il suppose que Helm est disponible. Ajustez les demandes de ressources à la taille de votre cluster.
- Créer un espace de noms monitoring
kubectl create namespace monitoring
- Ajouter le dépôt de graphiques et créer un fichier de valeurs
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
cat > values-monitoring.yaml <<'EOF'
global:
scrape_interval: 30s
alertmanager:
config:
route:
receiver: 'null'
group_by: ['alertname', 'namespace']
group_wait: 30s
group_interval: 5m
repeat_interval: 3h
receivers:
- name: 'null'
alertmanagerSpec:
replicas: 1
prometheus:
prometheusSpec:
replicas: 1
retention: 36h
resources:
requests:
cpu: 200m
memory: 1Gi
limits:
cpu: 1
memory: 4Gi
enableAdminAPI: false
scrapeInterval: 30s
ruleSelectorNilUsesHelmValues: false
serviceMonitorSelectorNilUsesHelmValues: false
podMonitorSelectorNilUsesHelmValues: false
additionalScrapeConfigs: []
service:
type: ClusterIP
kube-state-metrics:
selfMonitor:
enabled: false
nodeExporter:
tolerations:
- operator: Exists
resources:
requests:
cpu: 50m
memory: 64Mi
kubelet:
serviceMonitor:
cAdvisor: true
grafana:
enabled: true
adminUser: admin
adminPassword: admin
service:
type: ClusterIP
defaultDashboardsEnabled: true
sidecar:
dashboards:
enabled: true
resources:
requests:
cpu: 100m
memory: 256Mi
EOF
- Installer kube-prometheus-stack
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--values values-monitoring.yaml
- Limiter le scraping à quelques espaces de noms (optionnel mais recommandé dans les gros clusters)
Étiqueter les espaces de noms surveillés :
kubectl label namespace default monitor=true --overwrite
kubectl label namespace kube-system monitor=true --overwrite
Contraindre la découverte en activant les sélecteurs de labels sur les ServiceMonitors/PodMonitors si vous introduisez des moniteurs personnalisés plus tard. Pour les composants principaux fournis par le graphique, commencez avec les valeurs par défaut et examinez le nombre de cibles dans Prometheus.
- Ajouter un fichier de règles d'alerte pilote
Créer un PrometheusRule minimal avec quelques alertes à haute valeur (voir section suivante) et l'appliquer à l'espace de noms monitoring.
Règles d'Alerte Pratiques
Commencez avec une poignée d'alertes actionnables. Gardez les sévérités cohérentes : critique pour impact utilisateur ou risque de données ; avertissement pour dégradation méritant investigation en heures ouvrées. Les expressions ci-dessous sont des exemples ; ajustez les seuils à votre environnement.
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: pilot-k8s-alerts
namespace: monitoring
labels:
role: alert-rules
spec:
groups:
- name: k8s.pilot.rules
rules:
- alert: KubeAPIServerHighErrorRate
expr: |
sum(rate(apiserver_request_total{code=~"5.."}[5m]))
/
sum(rate(apiserver_request_total[5m])) > 0.05
for: 10m
labels:
severity: critical
annotations:
summary: Ratio d'erreurs 5xx API server élevé (>5% pendant 10m)
runbook: Vérifier les logs apiserver, la santé etcd, et les pics de charge.
- alert: NodeNotReady
expr: kube_node_status_condition{condition="Ready",status="true"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: Nœud non prêt depuis 5m
runbook: kubectl describe node; vérifier la pression et le kubelet.
- alert: NodeDiskPressure
expr: kube_node_status_condition{condition="DiskPressure",status="true"} == 1
for: 5m
labels:
severity: warning
annotations:
summary: Nœud sous pression disque
runbook: Libérer de l'espace sur le nœud; vérifier le GC d'images et les logs.
- alert: PodCrashLooping
expr: increase(kube_pod_container_status_restarts_total[10m]) > 5
for: 5m
labels:
severity: warning
annotations:
summary: Pod redémarrant fréquemment (>5 en 10m)
runbook: kubectl logs; inspecter OOMKilled ou erreurs de config.
- alert: PVCFillingUp
expr: |
(kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes) > 0.9
for: 10m
labels:
severity: warning
annotations:
summary: Utilisation PVC >90%
runbook: Étendre le PVC ou nettoyer les données; vérifier la rétention de l'app.
- alert: HighPodCPU
expr: |
sum by (namespace, pod) (rate(container_cpu_usage_seconds_total{image!=""}[5m])) > 2
for: 10m
labels:
severity: warning
annotations:
summary: Pod utilisant >2 cœurs CPU pendant 10m (seuil d'exemple)
runbook: Vérifier l'auto-scaling ou limiter les chemins chauds.
Correspondance compacte des alertes courantes vers les premières actions :
| Alerte | Quand elle se déclenche (exemple) | Première réponse |
|---|---|---|
| KubeAPIServerHighErrorRate | Ratio API 5xx > 5% pendant 10m | Vérifier logs apiserver et etcd; réduire la charge si pic |
| NodeNotReady | Node Ready=false 5m | kubectl describe node; vérifier pression et statut kubelet |
| NodeDiskPressure | DiskPressure=true 5m | Libérer disque, purger images/logs; envisager de tainter le nœud |
| PodCrashLooping | >5 redémarrages en 10m | kubectl logs et événements; chercher OOMKilled, erreurs config |
| PVCFillingUp | PVC >90% pendant 10m | Nettoyer données ou étendre volume; vérifier politiques rétention |
| HighPodCPU | Pod CPU >2 cœurs pendant 10m | Confirmer auto-scaling; vérifier endpoints chauds et limites |
Tableaux de Bord Qui Comptent
Les tableaux de bord doivent répondre à la question « où est le problème », pas seulement montrer de jolies courbes. Ensemble de départ recommandé :
- Vue d'ensemble Santé Cluster : latence et ratio d'erreurs API server, pods en attente scheduler, total pods et nœuds Ready, percentiles utilisation PVC, panneau résumé alertes.
- Carte de Chaleur Nœuds : CPU, mémoire disponible, disque disponible, et conditions de pression par nœud ; mettre en surbrillance les principaux contrevenants.
- SLO Charges de Travail : Pour vos 3 services principaux, tracer requêtes par seconde, taux d'erreur, percentiles latence (depuis métriques applicatives si disponibles), et redémarrages pods.
- Statut Déploiements : Réplicas désirés vs disponibles, âge du déploiement, et échecs récents pour espaces de noms ciblés.
- Surveillance Stockage : Taux d'utilisation PVC, système de fichiers disponible, et top 10 volumes à croissance la plus rapide.
Astuce : Mettez des liens vers les runbooks et one-liners kubectl dans les descriptions de panneaux pour la rapidité d'astreinte.
Vérification et Diagnostics
Après l'installation et la création des règles, vérifiez de bout en bout.
- Vérifier les pods et services
kubectl get pods -n monitoring
kubectl get svc -n monitoring
Attendez-vous à ce que Prometheus, Alertmanager, Grafana, node-exporter DaemonSets, et kube-state-metrics soient Running.
- Vérifier les cibles Prometheus et requête de base
Port-forward temporaire et ouvrez http://localhost:9090.
kubectl -n monitoring port-forward svc/monitoring-kube-prometheus-prometheus 9090:9090
Naviguez vers Status -> Targets ; attendez-vous à des cibles Up avec un dernier scrap récent.
- Vérifier Grafana
Port-forward et connectez-vous (admin/admin depuis les valeurs d'exemple ; changez en usage réel) :
kubectl -n monitoring port-forward svc/monitoring-grafana 3000:80
Ajoutez la source de données Prometheus si pas auto-provisionnée (URL http://monitoring-kube-prometheus-prometheus:9090 à l'intérieur du cluster). Chargez un tableau de bord vue d'ensemble cluster et confirmez que les données s'affichent.
- Vérifier qu'une alerte se déclenche
Créez une alerte de test toujours active et vérifiez l'UI Alertmanager.
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: test-alert
namespace: monitoring
spec:
groups:
- name: test
rules:
- alert: AlwaysOnTest
expr: vector(1)
for: 0m
labels:
severity: warning
annotations:
summary: Ceci est une alerte de test
Appliquez-la, attendez jusqu'à 1 minute, puis ouvrez Alertmanager via port-forward :
kubectl apply -f test-alert.yaml
kubectl -n monitoring port-forward svc/monitoring-kube-prometheus-alertmanager 9093:9093
Ouvrez http://localhost:9093 et confirmez que l'alerte apparaît. Supprimez la règle de test quand c'est fini :
kubectl delete -f test-alert.yaml
- Diagnostiquer les problèmes courants
- Si certaines cibles sont Down dans Prometheus -> Targets : cliquez sur une cible pour voir l'erreur. Souvent un désaccord de label ServiceMonitor ou blocage NetworkPolicy.
- Si aucune série n'apparaît pour kube-state-metrics : vérifiez que le service est dans kube-system ou monitoring et que les sélecteurs ServiceMonitor correspondent.
- Si les tableaux de bord chargent lentement : vérifiez les limites de ressources Prometheus ; réduisez l'auto-rafraîchissement des tableaux de bord ; simplifiez les requêtes.
Flux de Réponse aux Incidents
Quand une alerte se déclenche, utilisez un flux court et reproductible pour réduire le temps d'atténuation.
- Classifier rapidement
- Est-ce la plateforme (plan de contrôle, nœuds) ou la charge de travail (espaces de noms, déploiements) ? Vérifiez les labels d'alerte et le tableau de bord vue d'ensemble cluster.
- Confirmer l'impact utilisateur
- Cherchez un taux d'erreur et une latence élevés dans le tableau de bord SLO charges de travail. Si seules les métriques infrastructure montent mais que les SLO tiennent, baissez l'urgence.
- Rassembler les changements récents
- Listez les déploiements récents dans l'espace de noms affecté :
kubectl get deploy -n <ns>
kubectl rollout history deploy/<name> -n <ns>
- Vérifiez événements et logs
- Événements :
kubectl get events -A --sort-by=.lastTimestamp | tail -n 50
- Logs d'un pod qui crashe :
kubectl -n <ns> logs deploy/<name> --tail=200
kubectl -n <ns> describe pod <pod>
Cherchez OOMKilled, CrashLoopBackOff, ImagePullBackOff, back-off restarting.
- Stabiliser
- Pour pression nœud : cordon et drain le pire nœud si vous avez de la capacité :
kubectl cordon <node>
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
- Pour CrashLoopBackOff dû à la config : revenez au dernier ReplicaSet fonctionnel :
kubectl -n <ns> rollout undo deploy/<name>
- Boucler la boucle
- Ajoutez une note à l'alerte ou au runbook avec ce qui a marché. Ajustez les seuils si l'alerte était bruyante ou trop tardive.
Modes de Défaillance et Récupération
Pièges courants et comment récupérer en sécurité.
- Pics mémoire Prometheus ou OOMKills
Symptômes : Prometheus redémarre ; tableaux de bord en timeout.
- Atténuation : baisser la rétention (ex: 24-36h), augmenter l'intervalle de scrap (ex: 30s à 60s), et supprimer les labels à haute cardinalité via relabelings.
- Récupération : modifiez les valeurs, puis mettez à jour la release Helm. Si nécessaire, scalez Prometheus à zéro et remontez pour vider la surcharge :
kubectl -n monitoring scale statefulset monitoring-kube-prometheus-prometheus --replicas=0
sleep 10
kubectl -n monitoring scale statefulset monitoring-kube-prometheus-prometheus --replicas=1
- Pas de données depuis kube-state-metrics ou node-exporter
- Cause : désaccords labels ServiceMonitor, blocages NetworkPolicy, ou RBAC.
- Correction : vérifiez labels Service/ServiceMonitor, autorisez l'egress depuis l'espace de noms monitoring, et assurez-vous que ClusterRole/Binding existent pour l'opérateur.
- Bruit d'alertes et fatigue
- Cause : seuils trop bas, pas de regroupement, pas de temps mort entre répétitions.
- Correction : augmenter group_wait à 30s, group_interval à 5m ; ajouter des durées for: ; relever les seuils ; router avertissements vers chat, critiques vers pager.
- Tableaux de bord Grafana cassés après mise à niveau
- Correction : re-valider la source de données ; importer d'abord les tableaux de bord minimaux. Gardez les tableaux de bord personnalisés en contrôle de source comme JSON.
- Rollback et désinstallation
- Silenciez les alertes avant changements majeurs :
# Utilisez l'UI Alertmanager pour créer un silence pour matcher severity=~".*" pendant 1h
- Rollback Helm vers une révision connue bonne :
helm -n monitoring history monitoring
helm -n monitoring rollback monitoring <REVISION>
- Désinstallation complète (garde les PVCs par défaut ; supprimez-les seulement si vous êtes sûr) :
helm -n monitoring uninstall monitoring
kubectl -n monitoring get pvc | awk 'NR>1 {print $1}' | xargs -I{} kubectl -n monitoring delete pvc {}
kubectl delete namespace monitoring
- Décalage d'horloge cassant le timing des alertes
- Symptôme : échantillons scrapés semblent obsolètes ; conditions for: des alertes se déclenchent de façon imprévisible.
- Correction : assurez NTP sur les nœuds ; redémarrez les services de temps des nœuds si décalés.
Liste de Contrôle Opérationnelle
Quotidien
- Vérifier Alertmanager pour alertes critiques ouvertes et acquitter ou résoudre.
- Scanner le tableau de bord vue d'ensemble cluster pour ratio d'erreurs API et pression nœuds.
- Revoir top 10 pods par redémarrages sur les dernières 24h.
Hebdomadaire
- Ajuster toute alerte qui a pagé plus de deux fois sans action.
- Revoir la croissance d'utilisation PVC ; planifier les extensions avant 85%.
- Valider que nouveaux espaces de noms ou services sont scrapés (vue targets dans Prometheus).
Avant releases ou mises à niveau cluster
- Silencier alertes non-critiques pour la fenêtre de changement.
- Confirmer la sauvegarde du volume persistant Prometheus si vous stockez des données long-terme ailleurs.
- Valider les tableaux de bord Grafana contre les clusters de staging d'abord.
Capacité et hygiène
- Gardez la rétention Prometheus petite en pilote instance unique (24-48h). Utilisez remote write pour stockage long-terme seulement après que le pilote se stabilise.
- Imposer l'hygiène des labels dans les métriques applicatives. Évitez les labels non-bornés (ex: user_id) qui font exploser le nombre de séries.
Conclusion
Vous avez déployé une pile de surveillance et d'alerting Kubernetes à portée limitée, vérifié les chemins de données et d'alertes, et mis en place les premiers tableaux de bord et runbooks. À partir de là, étendez par petits pas sûrs : ajoutez un espace de noms à la fois, une nouvelle alerte par semaine, et un tableau de bord par équipe. À mesure que vous grandissez, envisagez la haute disponibilité pour Prometheus et Alertmanager, le stockage distant pour une rétention plus longue, et les tableaux de bord SLO applicatifs pour vos services principaux. La même approche disciplinée que vous avez utilisée dans le pilote maintiendra la surveillance fiable à mesure que vous scalez.