Ce guide couvre le déploiement de Prometheus sur Kubernetes avec kube-prometheus-stack. Vous apprendrez le pattern Operator, les ServiceMonitors, et comment monitorer vos applications en 5 minutes.
Pourquoi un Operator (et pas juste un Deployment) ?
Section intitulée « Pourquoi un Operator (et pas juste un Deployment) ? »Sur Kubernetes, on pourrait déployer Prometheus “classiquement” (Deployment + ConfigMap). Mais ça pose des problèmes :
| Problème | Avec ConfigMap | Avec Operator |
|---|---|---|
| Ajouter une cible | Éditer ConfigMap + reload | Créer un ServiceMonitor |
| Multi-équipe | Conflits sur le même fichier | Chaque équipe gère ses CRDs |
| Validation | Aucune (YAML brut) | Schéma Kubernetes |
| Découverte | Manuelle | Automatique (labels) |
Le pattern Operator : au lieu de modifier un fichier de config central, chaque équipe déclare un ServiceMonitor (CRD Kubernetes). L’Operator génère automatiquement la config Prometheus.
Ce qu’installe kube-prometheus-stack
Section intitulée « Ce qu’installe kube-prometheus-stack »| Composant | Rôle |
|---|---|
| Prometheus Operator | Surveille les CRDs, génère la config |
| Prometheus | Collecte et stockage (TSDB) |
| Alertmanager | Routing des alertes |
| Grafana | Dashboards préconfigurés |
| Node Exporter | Métriques système des nodes |
| kube-state-metrics | État des objets K8s (pods, deployments…) |
Installation
Section intitulée « Installation »-
Ajouter le repository Helm
Fenêtre de terminal helm repo add prometheus-community \https://prometheus-community.github.io/helm-chartshelm repo update -
Installer la stack (version pinnée)
Fenêtre de terminal helm install prometheus prometheus-community/kube-prometheus-stack \--namespace monitoring \--create-namespace \--version 69.8.2 -
Vérifier le déploiement (tous les pods Running)
Fenêtre de terminal kubectl get pods -n monitoring -wAttendez ~2-3 minutes. Tous les pods doivent être
Running:NAME READY STATUSalertmanager-prometheus-kube-prometheus-alertmanager-0 2/2 Runningprometheus-grafana-xxx 3/3 Runningprometheus-kube-prometheus-operator-xxx 1/1 Runningprometheus-kube-state-metrics-xxx 1/1 Runningprometheus-prometheus-kube-prometheus-prometheus-0 2/2 Runningprometheus-prometheus-node-exporter-xxx 1/1 Running -
Vérification rapide : Prometheus fonctionne
Fenêtre de terminal kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090 &curl -s localhost:9090/api/v1/targets | jq '.data.activeTargets | length'# Attendu : un nombre > 10 (les targets K8s)
Accéder aux interfaces
Section intitulée « Accéder aux interfaces »# Prometheuskubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090
# Grafana (mot de passe par défaut: prom-operator)kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80
# Alertmanagerkubectl port-forward -n monitoring svc/prometheus-kube-prometheus-alertmanager 9093:9093Les CRDs à connaître
Section intitulée « Les CRDs à connaître »L’Operator surveille ces Custom Resource Definitions :
| CRD | Rôle | Qui le crée |
|---|---|---|
| ServiceMonitor | ”Scrappe ce Service” | Équipe app |
| PodMonitor | ”Scrappe ces Pods” (sans Service) | Équipe app |
| PrometheusRule | Alertes et recording rules | Équipe app/SRE |
| Prometheus | Instance Prometheus | Ops/Platform |
| Alertmanager | Instance Alertmanager | Ops/Platform |
Workflow typique :
- L’équipe platform installe kube-prometheus-stack
- Chaque équipe app crée ses ServiceMonitors + PrometheusRules
- L’Operator génère la config automatiquement
Votre premier ServiceMonitor (5 minutes)
Section intitulée « Votre premier ServiceMonitor (5 minutes) »Créons un ServiceMonitor pour une application qui expose /metrics.
Prérequis : une app avec métriques
Section intitulée « Prérequis : une app avec métriques »apiVersion: apps/v1kind: Deploymentmetadata: name: my-app namespace: default labels: app: my-appspec: replicas: 2 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app image: my-app:latest ports: - containerPort: 8080 name: http - containerPort: 9090 name: metrics---apiVersion: v1kind: Servicemetadata: name: my-app namespace: default labels: app: my-appspec: ports: - port: 8080 name: http - port: 9090 name: metrics selector: app: my-appServiceMonitor
Section intitulée « ServiceMonitor »apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata: name: my-app namespace: default # Peut être dans le namespace de l'app labels: release: prometheus # ⚠️ OBLIGATOIRE - voir ci-dessousspec: selector: matchLabels: app: my-app # Matche le label du Service endpoints: - port: metrics # Nom du port dans le Service interval: 15s path: /metricsVérification
Section intitulée « Vérification »# ServiceMonitor créé ?kubectl get servicemonitor -A
# Visible dans Prometheus Targets ?kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090# Puis : Status → Targets → cherchez "my-app"PodMonitor : quand il n’y a pas de Service
Section intitulée « PodMonitor : quand il n’y a pas de Service »Pour les pods éphémères (Jobs, CronJobs) ou sans Service :
apiVersion: monitoring.coreos.com/v1kind: PodMonitormetadata: name: batch-jobs namespace: monitoring labels: release: prometheusspec: selector: matchLabels: type: batch-job namespaceSelector: any: true # Tous les namespaces podMetricsEndpoints: - port: metrics interval: 30sPrometheusRule : alertes Kubernetes-native
Section intitulée « PrometheusRule : alertes Kubernetes-native »Les alertes sont aussi des CRDs :
apiVersion: monitoring.coreos.com/v1kind: PrometheusRulemetadata: name: my-app-alerts namespace: monitoring labels: release: prometheus # ⚠️ Même piège que ServiceMonitorspec: groups: - name: my-app rules: - alert: MyAppDown expr: up{job="my-app"} == 0 for: 2m labels: severity: critical team: backend annotations: summary: "{{ $labels.instance }} is down" runbook_url: "https://wiki/runbooks/my-app-down"
- alert: MyAppHighErrorRate expr: | sum(rate(http_requests_total{job="my-app", status=~"5.."}[5m])) / sum(rate(http_requests_total{job="my-app"}[5m])) > 0.05 for: 3m labels: severity: warning team: backend annotations: summary: "Error rate > 5%"Configuration production (values.yaml)
Section intitulée « Configuration production (values.yaml) »# Prometheusprometheus: prometheusSpec: retention: 15d retentionSize: 50GB replicas: 2 # HA storageSpec: volumeClaimTemplate: spec: storageClassName: gp3 accessModes: ["ReadWriteOnce"] resources: requests: storage: 100Gi
# IMPORTANT : scraper tous les ServiceMonitors (pas seulement release=prometheus) serviceMonitorSelectorNilUsesHelmValues: false podMonitorSelectorNilUsesHelmValues: false ruleSelectorNilUsesHelmValues: false
# Alertmanageralertmanager: alertmanagerSpec: replicas: 3 storage: volumeClaimTemplate: spec: storageClassName: gp3 accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi config: global: resolve_timeout: 5m route: receiver: 'slack-default' group_by: ['alertname', 'namespace', 'service'] routes: - matchers: - severity="critical" receiver: 'pagerduty' receivers: - name: 'slack-default' slack_configs: - api_url: 'https://hooks.slack.com/services/...' channel: '#alerts' - name: 'pagerduty' pagerduty_configs: - routing_key: '$PAGERDUTY_KEY'
# Grafanagrafana: adminPassword: 'VotreMotDePasseSecurise' persistence: enabled: true size: 10Gi
# Node Exporter sur TOUS les nodes (y compris taints)prometheus-node-exporter: tolerations: - operator: Exists
# kube-state-metrics : labels custom sur les podskube-state-metrics: metricLabelsAllowlist: - pods=[app,version,team] - deployments=[app,version]helm upgrade prometheus prometheus-community/kube-prometheus-stack \ -n monitoring \ -f values.yaml \ --version 69.8.2Métriques Kubernetes automatiques
Section intitulée « Métriques Kubernetes automatiques »kube-prometheus-stack collecte automatiquement :
kube-state-metrics (état des objets)
Section intitulée « kube-state-metrics (état des objets) »| Métrique | Description |
|---|---|
kube_pod_status_phase | Phase du pod (Pending, Running…) |
kube_pod_container_status_restarts_total | Restarts |
kube_deployment_status_replicas_available | Replicas ready |
kube_node_status_condition | État des nodes |
kubelet/cAdvisor (ressources conteneurs)
Section intitulée « kubelet/cAdvisor (ressources conteneurs) »| Métrique | Description |
|---|---|
container_cpu_usage_seconds_total | CPU par container |
container_memory_usage_bytes | Mémoire par container |
container_network_receive_bytes_total | Réseau |
Requêtes PromQL Kubernetes
Section intitulée « Requêtes PromQL Kubernetes »# Pods en CrashLoopBackOffkube_pod_container_status_waiting_reason{reason="CrashLoopBackOff"} > 0
# CPU par pod (cores)sum(rate(container_cpu_usage_seconds_total{container!=""}[5m])) by (pod, namespace)
# Mémoire par namespace (GB)sum(container_memory_usage_bytes{container!=""}) by (namespace) / 1e9
# Deployments avec replicas manquantskube_deployment_status_replicas_available < kube_deployment_spec_replicas
# Nodes NotReadykube_node_status_condition{condition="Ready", status="true"} == 0Alertes incluses (centaines)
Section intitulée « Alertes incluses (centaines) »kube-prometheus-stack inclut des règles d’alerte préconfigurées :
| Alerte | Sévérité | Description |
|---|---|---|
KubeNodeNotReady | Warning | Node non prêt |
KubePodCrashLooping | Warning | Pod en crash loop |
KubeDeploymentReplicasMismatch | Warning | Replicas manquants |
KubePersistentVolumeFillingUp | Critical | PV bientôt plein |
PrometheusNotConnectedToAlertmanagers | Warning | Prometheus → Alertmanager cassé |
TargetDown | Warning | Target non scrapable |
# Lister toutes les règleskubectl get prometheusrules -n monitoring
# Voir le détailkubectl get prometheusrules -n monitoring \ prometheus-kube-prometheus-kubernetes-apps -o yamlScraper des services externes
Section intitulée « Scraper des services externes »Pour monitorer des services hors Kubernetes :
apiVersion: v1kind: Secretmetadata: name: additional-scrape-configs namespace: monitoringstringData: additional-scrape-configs.yaml: | - job_name: 'external-nodes' static_configs: - targets: - 'external-db.example.com:9104' - 'legacy-server.example.com:9100'Référencez dans values.yaml :
prometheus: prometheusSpec: additionalScrapeConfigsSecret: enabled: true name: additional-scrape-configs key: additional-scrape-configs.yamlLes pièges classiques
Section intitulée « Les pièges classiques »| Piège | Symptôme | Solution |
|---|---|---|
Label release manquant | ServiceMonitor ignoré | Ajouter release: prometheus |
| Namespace non surveillé | Target absent | Vérifier namespaceSelector |
| Port name incorrect | Scrape timeout | Matcher le nom du port Service |
| Selector trop large | Explosion targets | Être plus spécifique |
| Pas de PVC | Données perdues au restart | Configurer storageSpec |
Dépannage
Section intitulée « Dépannage »| Symptôme | Commande de debug |
|---|---|
| ServiceMonitor pas scrapé | kubectl get servicemonitor -A -o yaml | grep -A3 labels |
| Prometheus OOM | kubectl top pod -n monitoring + réduire cardinalité |
| Config générée | Voir ci-dessous |
| Alertes pas envoyées | kubectl logs -n monitoring alertmanager-... |
Voir la config Prometheus générée :
kubectl get secret -n monitoring \ prometheus-prometheus-kube-prometheus-prometheus \ -o jsonpath='{.data.prometheus\.yaml\.gz}' | base64 -d | gunzip | head -100Logs utiles :
# Operator (génère la config)kubectl logs -n monitoring deploy/prometheus-kube-prometheus-operator
# Prometheuskubectl logs -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 -c prometheus
# Alertmanagerkubectl logs -n monitoring alertmanager-prometheus-kube-prometheus-alertmanager-0À retenir
Section intitulée « À retenir »- Operator pattern : les CRDs remplacent les fichiers de config
- ServiceMonitor : déclare un Service à scraper
- Label
release: prometheus: obligatoire par défaut (le piège #1) - Dashboards inclus : observabilité K8s prête à l’emploi
- HA :
replicas: 2pour Prometheus,replicas: 3pour Alertmanager - Stockage : toujours configurer
storageSpecen production