Ce module est le cœur de la formation. Prometheus est le standard de facto pour les métriques sur Kubernetes. Vous allez l’installer, comprendre son fonctionnement en profondeur, et surtout maîtriser PromQL — le langage de requête qui fait toute la puissance de Prometheus.
Pourquoi ce module est-il le plus long ? Parce que Prometheus est la fondation de tout le reste. Sans une bonne compréhension de Prometheus et PromQL, vous ne pourrez pas créer des dashboards efficaces dans Grafana, ni des alertes pertinentes avec Alertmanager.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »À la fin de ce module, vous saurez :
- Expliquer comment Prometheus collecte et stocke les métriques (architecture pull)
- Installer Prometheus sur Kubernetes avec Helm
- Configurer le scraping automatique des pods et services
- Distinguer les 4 types de métriques (counter, gauge, histogram, summary)
- Écrire des requêtes PromQL de base à intermédiaires
- Créer des recording rules pour optimiser les performances
- Diagnostiquer les problèmes courants (targets down, high cardinality)
Prérequis pour ce module
Section intitulée « Prérequis pour ce module »Avant de continuer, vérifiez que vous avez terminé les modules précédents :
-
Le cluster Minikube tourne
Ouvrez un terminal et tapez :
Fenêtre de terminal minikube statusCe que vous devez voir :
minikubetype: Control Planehost: Runningkubelet: Runningapiserver: Runningkubeconfig: ConfiguredSi ce n’est pas le cas, démarrez Minikube :
Fenêtre de terminal minikube start --memory=10240 --cpus=4 -
L’application OpenTelemetry Demo est déployée
Fenêtre de terminal kubectl get pods -n otel-demoCe que vous devez voir : de nombreux pods (~25) en status
Running.Si ce n’est pas le cas, retournez au module 01.
-
Le namespace observability existe
Fenêtre de terminal kubectl get ns observabilitySi le namespace n’existe pas :
Fenêtre de terminal kubectl create namespace observability -
Le repo Helm prometheus-community est ajouté
Fenêtre de terminal helm repo list | grep prometheusCe que vous devez voir : une ligne contenant
prometheus-community.Si ce n’est pas le cas :
Fenêtre de terminal helm repo add prometheus-community https://prometheus-community.github.io/helm-chartshelm repo update
Comprendre Prometheus avant de l’installer
Section intitulée « Comprendre Prometheus avant de l’installer »Avant d’installer quoi que ce soit, comprenons pourquoi Prometheus fonctionne comme il fonctionne. Cette compréhension vous évitera beaucoup de confusion plus tard.
Le modèle “Pull” — une différence fondamentale
Section intitulée « Le modèle “Pull” — une différence fondamentale »La plupart des systèmes de monitoring traditionnels (Graphite, StatsD, InfluxDB) fonctionnent en mode push : vos applications envoient leurs métriques vers le serveur de monitoring.
Prometheus fait l’inverse. Il fonctionne en mode pull : c’est Prometheus qui va chercher les métriques sur vos applications.
Pourquoi ce choix ?
| Push (traditionnel) | Pull (Prometheus) |
|---|---|
| L’application doit connaître l’adresse du serveur | L’application expose juste un endpoint, elle ne sait rien de Prometheus |
| Si le serveur est down, les métriques sont perdues | Si Prometheus est down, il reprendra le scraping au redémarrage |
| Difficile de tester localement | Facile de tester : curl http://localhost:8080/metrics |
| Nécessite une configuration côté application | Configuration centralisée dans Prometheus |
Analogie : Imaginez un journal papier. En mode push, chaque journaliste enverrait son article par courrier à l’imprimerie. En mode pull, un coursier (Prometheus) passe régulièrement chez chaque journaliste pour récupérer les articles. Si un journaliste est absent, le coursier réessaiera plus tard.
L’endpoint /metrics — ce que Prometheus collecte
Section intitulée « L’endpoint /metrics — ce que Prometheus collecte »Chaque application que Prometheus surveille doit exposer un endpoint HTTP /metrics qui retourne du texte dans un format spécifique.
Voyons un exemple concret. Prometheus lui-même expose ses propres métriques. Une fois installé, vous pourrez les consulter :
# Port-forward vers Prometheuskubectl port-forward svc/prometheus-server 9090:80 -n observabilityDans un autre terminal :
curl http://localhost:9090/metrics 2>/dev/null | head -30Ce que vous devez voir — quelque chose comme :
# HELP prometheus_engine_query_duration_seconds Query timings# TYPE prometheus_engine_query_duration_seconds summaryprometheus_engine_query_duration_seconds{slice="inner_eval",quantile="0.5"} 0.000012prometheus_engine_query_duration_seconds{slice="inner_eval",quantile="0.9"} 0.000025# HELP prometheus_tsdb_head_chunks Total number of chunks in the head block.# TYPE prometheus_tsdb_head_chunks gaugeprometheus_tsdb_head_chunks 1234Décortiquons ce format :
| Élément | Signification |
|---|---|
# HELP ... | Documentation humaine de la métrique |
# TYPE ... | Type de métrique (counter, gauge, histogram, summary) |
prometheus_tsdb_head_chunks | Nom de la métrique |
{slice="inner_eval",...} | Labels (dimensions) |
1234 | Valeur actuelle |
Fermez le port-forward (Ctrl+C) avant de continuer.
Architecture complète de Prometheus
Section intitulée « Architecture complète de Prometheus »Maintenant que vous comprenez le modèle pull et le format des métriques, voici l’architecture complète :
Les composants expliqués :
| Composant | Ce qu’il fait | Analogie |
|---|---|---|
| Retrieval | Va chercher les métriques sur chaque target toutes les 15 secondes | Le coursier qui passe régulièrement |
| Service Discovery | Découvre automatiquement les nouveaux pods/services dans Kubernetes | Le GPS du coursier |
| TSDB | Stocke les séries temporelles de manière efficace sur disque | L’archive où tous les articles sont classés |
| HTTP Server | Permet d’interroger les données via l’interface web et l’API | La salle de lecture de l’archive |
| Rule Evaluation | Évalue les règles d’alerte et les recording rules | Le rédacteur en chef qui vérifie si quelque chose d’anormal se passe |
Installer Prometheus sur Kubernetes
Section intitulée « Installer Prometheus sur Kubernetes »Maintenant que vous comprenez comment Prometheus fonctionne, installons-le.
-
Positionnez-vous dans le répertoire du lab
Fenêtre de terminal cd ~/lab-observability -
Examinez la configuration Helm
Avant d’installer, regardons ce qu’on va déployer :
Fenêtre de terminal cat 02-prometheus/helm-values/prometheus-minimal.yamlCe que vous voyez — les points importants :
server:retention: "7d" # Garder les données 7 jourspersistentVolume:size: 8Gi # 8 Go de stockageservice:type: NodePortnodePort: 30090 # Accessible sur ce port# Activer les métriques KuberneteskubeStateMetrics:enabled: true # Métriques sur l'état des objets K8snodeExporter:enabled: true # Métriques système des nodes# Scraper l'OpenTelemetry Collector (installé dans otel-demo au module 01)extraScrapeConfigs: |- job_name: 'otel-collector'metrics_path: /metricsstatic_configs:- targets: ['otel-collector.otel-demo.svc.cluster.local:8889']Cette configuration :
- Installe Prometheus avec 7 jours de rétention
- Active Node Exporter (métriques CPU, RAM, disque des nodes)
- Active kube-state-metrics (métriques sur les pods, deployments, etc.)
- Scrape l’OpenTelemetry Collector (namespace
otel-demo) pour récupérer les métriquesotel_*de l’application
-
Installez Prometheus
Fenêtre de terminal helm upgrade --install prometheus prometheus-community/prometheus \-n observability \-f 02-prometheus/helm-values/prometheus-minimal.yaml \--waitCe que vous devez voir :
Release "prometheus" does not exist. Installing it now.NAME: prometheusLAST DEPLOYED: ...NAMESPACE: observabilitySTATUS: deployed...L’option
--waitfait que Helm attend que tous les pods soient prêts avant de rendre la main. Cela peut prendre 1-2 minutes. -
Vérifiez que tout tourne
Fenêtre de terminal kubectl get pods -n observability | grep -E 'prometheus-server|kube-state-metrics|node-exporter'Ce que vous devez voir :
prometheus-kube-state-metrics-xxx 1/1 Running 0 2mprometheus-prometheus-node-exporter-xxx 1/1 Running 0 2mprometheus-server-xxxxxxxxxx-xxxxx 2/2 Running 0 2mTous les pods doivent être en
Running.Si le pod n’est pas ready après 3 minutes, consultez les logs :
Fenêtre de terminal kubectl logs -n observability -l app.kubernetes.io/name=prometheus -c prometheus-server --tail=50 -
Accédez à l’interface Prometheus
Il y a deux méthodes :
Méthode 1 — NodePort (recommandée pour Minikube) :
Fenêtre de terminal minikube service prometheus-server -n observability --urlCopiez l’URL affichée et ouvrez-la dans votre navigateur.
Méthode 2 — Port-forward :
Fenêtre de terminal kubectl port-forward svc/prometheus-server 9090:80 -n observabilityPuis ouvrez http://localhost:9090
Vous devez maintenant voir l’interface web de Prometheus — une page avec un champ de requête en haut et plusieurs onglets (Graph, Alerts, Status…).
Explorer l’interface Prometheus
Section intitulée « Explorer l’interface Prometheus »Avant d’écrire des requêtes, faisons le tour de l’interface pour comprendre ce que Prometheus nous montre.

Onglet Status → Targets
Section intitulée « Onglet Status → Targets »Cliquez sur Status dans le menu du haut, puis Targets.
Cette page est la plus importante pour le dépannage. Elle montre toutes les cibles que Prometheus scrape, avec leur état.
Ce que vous devez voir :
| Job | Targets | État attendu |
|---|---|---|
kubernetes-apiservers | 1 | 🟢 UP |
kubernetes-nodes | 1 (Minikube n’a qu’un node) | 🟢 UP |
kubernetes-nodes-cadvisor | 1 | 🟢 UP |
kubernetes-service-endpoints | Variable | 🟢 UP (la plupart) |
prometheus | 1 | 🟢 UP |
otel-collector | 1 | 🟢 UP |
Comment lire cette page :
- 🟢 UP (vert) : Prometheus scrape avec succès
- 🔴 DOWN (rouge) : Le scraping échoue
- Last Scrape : Quand le dernier scrape a eu lieu
- Scrape Duration : Combien de temps le scrape a pris
- Error : Si DOWN, le message d’erreur
Onglet Status → Configuration
Section intitulée « Onglet Status → Configuration »Cliquez sur Status → Configuration.
Vous voyez la configuration YAML complète de Prometheus. C’est utile pour vérifier que vos scrape configs ont bien été appliqués.
Cherchez la section scrape_configs et vérifiez les jobs présents (kubernetes-nodes, kubernetes-service-endpoints, prometheus…).
Onglet Graph — l’espace de requêtage
Section intitulée « Onglet Graph — l’espace de requêtage »Cliquez sur Graph.
C’est ici que vous passerez le plus de temps. Le champ en haut permet d’écrire des requêtes PromQL.
Première requête — testez que tout fonctionne :
Tapez dans le champ de requête :
upCliquez sur Execute.
Ce que vous devez voir :
Une liste de lignes, chacune avec :
- Des labels entre
{}(job, instance, namespace…) - Une valeur :
1(UP) ou0(DOWN)
Cette métrique spéciale up est créée automatiquement par Prometheus pour chaque target. Elle vaut 1 si le dernier scrape a réussi, 0 sinon.
Passez en vue graphique :
Cliquez sur l’onglet Graph (sous le champ de requête, pas dans le menu).
Vous voyez maintenant l’évolution de la métrique dans le temps. Comme up vaut généralement 1, vous verrez des lignes horizontales.
Les 4 types de métriques — comprendre avant de requêter
Section intitulée « Les 4 types de métriques — comprendre avant de requêter »Avant d’apprendre PromQL, vous devez absolument comprendre les 4 types de métriques. Chaque type s’utilise différemment, et confondre les types est l’erreur n°1 des débutants.
Counter (compteur) — ça ne fait qu’augmenter
Section intitulée « Counter (compteur) — ça ne fait qu’augmenter »Un counter est une valeur qui ne fait qu’augmenter (ou redémarre à 0 quand l’application redémarre).
Exemples concrets :
- Nombre total de requêtes HTTP reçues
- Nombre total d’erreurs
- Nombre total de bytes transférés
- Nombre total de connexions ouvertes (cumulatif)
Analogie : C’est comme le compteur kilométrique de votre voiture. Il augmente toujours, il ne diminue jamais. Si vous voulez savoir à quelle vitesse vous roulez, vous ne regardez pas le compteur brut — vous calculez la différence sur une période.
Erreur classique — utiliser un counter brut :
# ❌ MAUVAIS — la valeur brute n'est pas interprétablehttp_requests_total
# Cette requête retourne par exemple 123456, 123789, 124012...# Ces nombres ne vous disent rien d'utile !La bonne façon — utiliser rate() :
# ✅ BON — taux de requêtes par seconde sur les 5 dernières minutesrate(http_requests_total[5m])
# Cette requête retourne par exemple 12.5, 13.2, 11.8...# = 12.5 requêtes par seconde, bien plus utile !Exercice pratique — exécutez ces requêtes dans Prometheus :
# 1. Valeur brute (regardez, c'est un nombre qui augmente)prometheus_http_requests_total
# 2. Taux par seconde (maintenant c'est exploitable)rate(prometheus_http_requests_total[5m])
# 3. Augmentation totale sur la dernière heureincrease(prometheus_http_requests_total[1h])Gauge (jauge) — ça monte et ça descend
Section intitulée « Gauge (jauge) — ça monte et ça descend »Un gauge est une valeur qui peut monter et descendre librement.
Exemples concrets :
- Mémoire actuellement utilisée
- Température actuelle
- Nombre de connexions actuellement ouvertes
- Nombre de tâches dans une file d’attente
Analogie : C’est comme le thermomètre ou la jauge d’essence de votre voiture. La valeur fluctue en fonction de l’état actuel.
Utilisation — la valeur brute est directement exploitable :
# ✅ Mémoire disponible sur les nodes (en bytes)node_memory_MemAvailable_bytes
# ✅ Convertir en GB pour plus de lisibiliténode_memory_MemAvailable_bytes / 1024 / 1024 / 1024
# ✅ Pourcentage de mémoire utilisée(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100Exercice pratique — exécutez ces requêtes :
# 1. Mémoire disponiblenode_memory_MemAvailable_bytes
# 2. En gigabytes (plus lisible)node_memory_MemAvailable_bytes / 1024 / 1024 / 1024
# 3. Pourcentage de mémoire utilisée (le calcul complet)(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100Ce que vous devez voir : Un pourcentage entre 0 et 100. Sur Minikube, c’est probablement entre 30% et 70%.
Histogram — pour les distributions et percentiles
Section intitulée « Histogram — pour les distributions et percentiles »Un histogram mesure la distribution d’une valeur, typiquement des durées (latence).
Pourquoi un histogram et pas un simple moyenne ?
Imaginez un service web. La moyenne de latence est 100ms. Ça semble bien. Mais si 99% des requêtes prennent 10ms et 1% prennent 10 secondes, la moyenne cache un gros problème — 1% de vos utilisateurs ont une expérience horrible.
Les histograms permettent de calculer des percentiles :
- P50 (médiane) : 50% des requêtes sont plus rapides que cette valeur
- P90 : 90% des requêtes sont plus rapides
- P99 : 99% des requêtes sont plus rapides (important pour détecter les outliers)
Comment ça fonctionne ?
Un histogram stocke les valeurs dans des “buckets” (tranches) :
# Requêtes avec durée <= 5ms : 100# Requêtes avec durée <= 10ms : 250# Requêtes avec durée <= 25ms : 400# Requêtes avec durée <= 50ms : 450# Requêtes avec durée <= 100ms : 480# Requêtes avec durée <= +Inf : 500Prometheus peut alors calculer : “99% des requêtes (495) ont pris moins de X ms”.
Utilisation — calculer un percentile :
# P99 de la latence des requêtes HTTP Prometheus (99% des requêtes sont plus rapides que cette valeur)histogram_quantile( 0.99, rate(prometheus_http_request_duration_seconds_bucket[5m]))Décortiquons cette requête :
prometheus_http_request_duration_seconds_bucket: les données brutes du histogramrate(...[5m]): on calcule le taux par seconde (obligatoire pour les histograms)histogram_quantile(0.99, ...): on calcule le percentile 99
Exercice pratique :
# P50 (médiane) — la moitié des requêtes sont plus rapideshistogram_quantile( 0.50, rate(prometheus_http_request_duration_seconds_bucket[5m]))
# P90 — 90% des requêtes sont plus rapideshistogram_quantile( 0.90, rate(prometheus_http_request_duration_seconds_bucket[5m]))
# P99 — 99% des requêtes sont plus rapides (détecte les outliers)histogram_quantile( 0.99, rate(prometheus_http_request_duration_seconds_bucket[5m]))Ce que vous devez voir : Des valeurs en secondes. Le P99 devrait être plus élevé que le P50.
Summary — percentiles pré-calculés (à éviter)
Section intitulée « Summary — percentiles pré-calculés (à éviter) »Un summary ressemble à un histogram mais les percentiles sont calculés côté application, pas par Prometheus.
Différences avec les histograms :
| Aspect | Histogram | Summary |
|---|---|---|
| Calcul des percentiles | Par Prometheus (flexible) | Par l’application (fixe) |
| Agrégation possible | Oui | Non (les percentiles ne s’additionnent pas) |
| Recommandation | ✅ Préféré | ⚠️ À éviter si possible |
Pourquoi éviter les summaries ?
Si vous avez 10 pods et que chacun calcule son P99, vous ne pouvez pas calculer le P99 global correct. Les percentiles ne s’additionnent pas mathématiquement.
Avec les histograms, Prometheus peut calculer le P99 global à partir des buckets agrégés.
Exemple de summary (juste pour reconnaître le format) :
http_request_duration_seconds{quantile="0.99"}http_request_duration_seconds{quantile="0.5"}PromQL — apprendre par la pratique
Section intitulée « PromQL — apprendre par la pratique »Maintenant que vous comprenez les types de métriques, apprenons PromQL en pratiquant.
Syntaxe de base — les sélecteurs
Section intitulée « Syntaxe de base — les sélecteurs »L’unité de base en PromQL est le sélecteur. Il permet de récupérer des séries temporelles.
Sélecteur simple — toutes les séries d’une métrique :
prometheus_http_requests_totalExécutez cette requête. Vous voyez toutes les séries avec cette métrique, chacune avec ses labels (code, handler, job…).
Filtrer par label (égalité) :
prometheus_http_requests_total{code="200"}Maintenant vous ne voyez que les requêtes avec un code 200.
Filtrer par label (regex) :
# Seulement les handlers qui commencent par /apiprometheus_http_requests_total{handler=~"/api.*"}
# Tout sauf les 200prometheus_http_requests_total{code!="200"}
# Tous les codes 5xx (regex)prometheus_http_requests_total{code=~"5.."}Combiner des filtres :
prometheus_http_requests_total{handler="/metrics", code="200"}Résumé des opérateurs de matching :
| Opérateur | Signification | Exemple |
|---|---|---|
= | Égal | code="200" |
!= | Différent | code!="200" |
=~ | Correspond au regex | code=~"5.." |
!~ | Ne correspond pas au regex | handler!~"/health.*" |
Les fonctions essentielles
Section intitulée « Les fonctions essentielles »Voici les fonctions que vous utiliserez 80% du temps :
rate() — taux par seconde d’un counter
Section intitulée « rate() — taux par seconde d’un counter »# Requêtes HTTP par seconde (sur les 5 dernières minutes)rate(prometheus_http_requests_total[5m])Le [5m] est une “range vector”. Il dit à Prometheus de regarder les 5 dernières minutes de données pour calculer le taux.
Quelle fenêtre choisir ?
| Fenêtre | Usage |
|---|---|
[1m] | Très réactif, peut être bruité |
[5m] | Bon compromis (le plus courant) |
[15m] | Lissé, masque les pics courts |
[1h] | Vue très lissée |
Exercice — comparez les résultats avec différentes fenêtres :
rate(prometheus_http_requests_total[1m])rate(prometheus_http_requests_total[5m])rate(prometheus_http_requests_total[15m])Passez en vue Graph et observez : la courbe avec [1m] est plus “nerveuse”, celle avec [15m] est plus lisse.
sum() — agréger des séries
Section intitulée « sum() — agréger des séries »Sans agrégation, rate() retourne une série par combinaison de labels. C’est souvent trop détaillé.
# AVANT — une série par handler, par code...rate(prometheus_http_requests_total[5m])
# APRÈS — une seule valeur : le total de toutes les requêtessum(rate(prometheus_http_requests_total[5m]))Agréger par certains labels — avec by :
# Total par code HTTPsum by (code) (rate(prometheus_http_requests_total[5m]))
# Total par handlersum by (handler) (rate(prometheus_http_requests_total[5m]))
# Total par code ET par handlersum by (code, handler) (rate(prometheus_http_requests_total[5m]))Exclure certains labels — avec without :
# Tout sauf le label "instance" (utile quand vous avez plusieurs pods)sum without (instance) (rate(prometheus_http_requests_total[5m]))avg(), max(), min() — autres agrégations
Section intitulée « avg(), max(), min() — autres agrégations »# Moyenne de l'utilisation mémoire par nodeavg by (instance) (node_memory_MemAvailable_bytes)
# Maximum de la latence P99max(histogram_quantile(0.99, rate(prometheus_http_request_duration_seconds_bucket[5m])))
# Minimum par handlermin by (handler) (rate(prometheus_http_requests_total[5m]))count() — compter les séries
Section intitulée « count() — compter les séries »# Combien de targets sont surveillés ?count(up)
# Combien de targets sont UP ?count(up == 1)
# Combien de pods dans le namespace observability ?count(kube_pod_info{namespace="observability"})topk() et bottomk() — les extrêmes
Section intitulée « topk() et bottomk() — les extrêmes »# Les 5 handlers avec le plus de requêtestopk(5, sum by (handler) (rate(prometheus_http_requests_total[5m])))
# Les 3 handlers avec le moins de requêtesbottomk(3, sum by (handler) (rate(prometheus_http_requests_total[5m])))Opérateurs arithmétiques et de comparaison
Section intitulée « Opérateurs arithmétiques et de comparaison »Arithmétique — pour calculer des ratios, des pourcentages :
# Mémoire utilisée (total - disponible)node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes
# Pourcentage de mémoire utilisée(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
# Taux d'erreur en pourcentagesum(rate(prometheus_http_requests_total{code=~"5.."}[5m]))/sum(rate(prometheus_http_requests_total[5m]))* 100Comparaison — pour filtrer les résultats :
# Seulement les targets DOWNup == 0
# Handlers avec plus de 0.1 req/ssum by (handler) (rate(prometheus_http_requests_total[5m])) > 0.1
# Utilisation mémoire > 80%(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) > 0.8Exercices guidés — mettez en pratique
Section intitulée « Exercices guidés — mettez en pratique »Ces exercices vous permettent de valider votre compréhension. Faites-les dans l’ordre.
Exercice 1 : Compter et filtrer les targets
Section intitulée « Exercice 1 : Compter et filtrer les targets »Objectif : Vérifier l’état de santé de votre infrastructure.
-
Comptez tous les targets
count(up)Ce que vous devez voir : Un nombre (probablement entre 10 et 20).
-
Comptez les targets UP
count(up == 1) -
Comptez les targets DOWN
count(up == 0)Ce que vous devez voir : Idéalement 0. Si ce n’est pas 0, notez quels targets sont DOWN.
-
Listez les targets DOWN
up == 0Cette requête retourne les séries avec leurs labels, vous pouvez identifier quel service pose problème.
Exercice 2 : Analyser l’utilisation CPU
Section intitulée « Exercice 2 : Analyser l’utilisation CPU »Objectif : Comprendre comment calculer l’utilisation CPU.
-
Affichez le temps CPU idle
node_cpu_seconds_total{mode="idle"}C’est un counter : le nombre total de secondes passées en idle.
-
Calculez le taux de temps idle par seconde
rate(node_cpu_seconds_total{mode="idle"}[5m])Cela retourne une valeur proche de 1 (1 seconde d’idle par seconde = 100% idle).
-
Moyennez sur tous les cores
avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) -
Convertissez en pourcentage d’utilisation
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)Ce que vous devez voir : Un pourcentage entre 0 et 100. C’est l’utilisation CPU de votre node Minikube.
Exercice 3 : Analyser les requêtes HTTP
Section intitulée « Exercice 3 : Analyser les requêtes HTTP »Objectif : Mesurer le trafic HTTP de Prometheus.
-
Total de requêtes par seconde
sum(rate(prometheus_http_requests_total[5m]))Ce que vous devez voir : Un nombre (ex: 0.5 = 0.5 requêtes par seconde sur l’API Prometheus).
-
Requêtes par handler
sum by (handler) (rate(prometheus_http_requests_total[5m]))Passez en vue Graph. Vous voyez quels endpoints Prometheus sont les plus sollicités.
-
Requêtes par code de statut HTTP
sum by (code) (rate(prometheus_http_requests_total[5m]))Idéalement, la majorité devrait être en 200.
-
Pourcentage d’erreurs (5xx)
sum(rate(prometheus_http_requests_total{code=~"5.."}[5m]))/sum(rate(prometheus_http_requests_total[5m]))* 100Ce que vous devez voir : Un pourcentage. Si c’est supérieur à 1%, vous avez un problème.
Exercice 4 : Mesurer la latence
Section intitulée « Exercice 4 : Mesurer la latence »Objectif : Calculer les percentiles de latence.
-
P50 global (médiane)
histogram_quantile(0.50,sum(rate(prometheus_http_request_duration_seconds_bucket[5m])) by (le))Note :
by (le)est obligatoire carhistogram_quantilea besoin des buckets. -
P99 global
histogram_quantile(0.99,sum(rate(prometheus_http_request_duration_seconds_bucket[5m])) by (le)) -
P99 par handler
histogram_quantile(0.99,sum by (handler, le) (rate(prometheus_http_request_duration_seconds_bucket[5m])))Ce que vous devez voir : Une latence en secondes pour chaque handler.
-
Identifiez le handler le plus lent
topk(1,histogram_quantile(0.99,sum by (handler, le) (rate(prometheus_http_request_duration_seconds_bucket[5m]))))
Exercice 5 : Combiner les métriques (SLI)
Section intitulée « Exercice 5 : Combiner les métriques (SLI) »Objectif : Créer un indicateur de niveau de service (SLI) simple.
Un SLI courant : “Pourcentage de requêtes réussies avec une latence acceptable”.
-
Définissez “latence acceptable” = moins de 500ms
On compte les requêtes dans le bucket <= 0.5s :
sum(rate(prometheus_http_request_duration_seconds_bucket{le="0.5"}[5m])) -
Comparez au total des requêtes
sum(rate(prometheus_http_request_duration_seconds_bucket{le="0.5"}[5m]))/sum(rate(prometheus_http_request_duration_seconds_count[5m]))* 100Ce que vous devez voir : Un pourcentage. “X% des requêtes ont une latence < 500ms”.
-
Ajoutez le critère “pas d’erreur”
(sum(rate(prometheus_http_request_duration_seconds_bucket{le="0.5", code!~"5.."}[5m]))/sum(rate(prometheus_http_request_duration_seconds_count[5m]))) * 100C’est votre SLI : ”% de requêtes réussies en moins de 500ms”.
Configuration du scraping — comment Prometheus découvre les targets
Section intitulée « Configuration du scraping — comment Prometheus découvre les targets »Vous vous demandez peut-être comment Prometheus sait quels pods scraper. C’est le Service Discovery Kubernetes.
Le mécanisme d’annotations (culture générale)
Section intitulée « Le mécanisme d’annotations (culture générale) »Dans certains clusters Kubernetes, Prometheus peut scraper automatiquement les pods via des annotations. C’est un pattern courant hors de ce cours :
# Ce que notre configuration fait automatiquement# Pour chaque pod avec l'annotation prometheus.io/scrape: "true"# Prometheus va scraper l'endpoint /metricsPour qu’un pod soit scrapé automatiquement via annotations, il doit avoir :
apiVersion: v1kind: Podmetadata: name: mon-app annotations: prometheus.io/scrape: "true" # Active le scraping prometheus.io/port: "8080" # Port de l'endpoint /metrics prometheus.io/path: "/metrics" # Chemin (par défaut /metrics)Ce que Prometheus scrape dans ce lab
Section intitulée « Ce que Prometheus scrape dans ce lab »| Source | Métriques | Comment |
|---|---|---|
| Node Exporter | node_* (CPU, RAM, disque) | Via service discovery Kubernetes |
| kube-state-metrics | kube_* (pods, deployments) | Via service discovery Kubernetes |
| cAdvisor | container_* (conteneurs) | Via kubelet |
| OTel Collector | otel_* (métriques applicatives) | Via job statique otel-collector |
Ajouter un job de scraping personnalisé
Section intitulée « Ajouter un job de scraping personnalisé »Si vous voulez scraper un service qui n’a pas les annotations, vous pouvez ajouter un job statique :
Éditez 02-prometheus/helm-values/prometheus-minimal.yaml et ajoutez :
extraScrapeConfigs: | # Job pour l'OpenTelemetry Collector (métriques OTel Demo) - job_name: 'otel-collector' static_configs: - targets: ['otel-collector.observability.svc.cluster.local:8889']
# NOUVEAU — job personnalisé pour un service externe - job_name: 'mon-service-externe' static_configs: - targets: ['mon-service.example.com:9090']Puis appliquez :
helm upgrade prometheus prometheus-community/prometheus \ -n observability \ -f 02-prometheus/helm-values/prometheus-minimal.yamlAttendez 1 minute et vérifiez dans Status → Targets que le nouveau job apparaît.
Recording rules — optimiser les performances
Section intitulée « Recording rules — optimiser les performances »Les recording rules permettent de pré-calculer des requêtes complexes. Au lieu de calculer une requête à chaque affichage de dashboard, Prometheus calcule le résultat régulièrement et le stocke comme une nouvelle métrique.
Pourquoi des recording rules ?
Section intitulée « Pourquoi des recording rules ? »| Sans recording rule | Avec recording rule |
|---|---|
| Calcul à chaque requête | Calcul périodique (ex: toutes les 30s) |
| Lent si la requête est complexe | Rapide (résultat pré-calculé) |
| Consomme du CPU à chaque affichage | Consomme du CPU une fois |
Créer une recording rule
Section intitulée « Créer une recording rule »Créez le fichier 02-prometheus/recording-rules.yaml :
groups: - name: http_recording_rules interval: 30s # Calculer toutes les 30 secondes rules: # Requêtes par seconde par handler - record: job:http_requests_per_second:rate5m expr: sum by (handler) (rate(prometheus_http_requests_total[5m]))
# Erreurs par seconde par handler - record: job:http_errors_per_second:rate5m expr: sum by (handler) (rate(prometheus_http_requests_total{code=~"5.."}[5m]))
# Taux d'erreur par handler - record: job:http_error_rate:ratio expr: | job:http_errors_per_second:rate5m / job:http_requests_per_second:rate5m
# Latence P99 par handler - record: job:http_latency_p99:seconds expr: | histogram_quantile(0.99, sum by (handler, le) (rate(prometheus_http_request_duration_seconds_bucket[5m])) )Convention de nommage :
- Format :
level:metric:operation level: niveau d’agrégation (job, instance, cluster…)metric: ce que ça mesureoperation: l’opération appliquée (rate5m, ratio, seconds…)
Exercice : Une fois les rules appliquées, vous pouvez utiliser job:http_error_rate:ratio au lieu de la requête complète. C’est plus lisible et plus rapide.
Stockage et rétention
Section intitulée « Stockage et rétention »Combien de temps Prometheus garde les données ?
Section intitulée « Combien de temps Prometheus garde les données ? »Par défaut dans notre configuration : 7 jours. Après, les données sont supprimées automatiquement.
Vous pouvez modifier ça dans les values :
server: retention: "30d" # Garder 30 joursCombien d’espace disque ?
Section intitulée « Combien d’espace disque ? »Règle approximative : 1-2 bytes par sample après compression.
Calcul :
Espace = nb_séries × samples_par_jour × jours × 2 bytesExemple : 10 000 séries, scrape toutes les 15s, rétention 30 jours :
10000 × (86400 ÷ 15) × 30 × 2 = ~3.5 GBVérifier l’utilisation actuelle
Section intitulée « Vérifier l’utilisation actuelle »# Nombre de séries activesprometheus_tsdb_head_series
# Taille du stockageprometheus_tsdb_storage_blocks_bytesDépannage — résoudre les problèmes courants
Section intitulée « Dépannage — résoudre les problèmes courants »Problème : Target DOWN
Section intitulée « Problème : Target DOWN »Symptôme : Un target est rouge (DOWN) dans Status → Targets.
Diagnostic étape par étape :
-
Notez le message d’erreur dans la colonne Error
-
Vérifiez que le pod tourne
Fenêtre de terminal kubectl get pods -n <namespace> -
Testez l’endpoint manuellement
Fenêtre de terminal kubectl port-forward pod/<nom-du-pod> 8080:<port-metrics>curl http://localhost:8080/metricsSi ça fonctionne : le problème est probablement réseau entre Prometheus et le pod.
Si ça échoue : le pod n’expose pas correctement ses métriques.
-
Vérifiez les annotations
Fenêtre de terminal kubectl get pod <nom-du-pod> -o yaml | grep -A5 annotations
Problème : High cardinality (Prometheus lent)
Section intitulée « Problème : High cardinality (Prometheus lent) »Symptôme : Prometheus consomme beaucoup de mémoire, les requêtes sont lentes.
Cause probable : Trop de séries temporelles (high cardinality).
Diagnostic :
# Top 10 des métriques par nombre de sériestopk(10, count by (__name__) ({__name__!=""}))Ce que vous devez voir : Si une métrique a des dizaines de milliers de séries, c’est probablement le problème.
Causes fréquentes :
- Label
user_idourequest_id(une série par utilisateur/requête !) - Label
pathavec des IDs variables (/users/123,/users/456…) - Label
timestamp(erreur classique)
Solutions :
- Corriger l’instrumentation côté application (supprimer les labels problématiques)
- Utiliser
metric_relabel_configspour supprimer les labels au niveau Prometheus
Problème : Prometheus redémarre (OOMKilled)
Section intitulée « Problème : Prometheus redémarre (OOMKilled) »Symptôme : Le pod Prometheus redémarre régulièrement.
Diagnostic :
kubectl describe pod prometheus-server-xxx -n observability | grep -A10 "Last State"Si vous voyez OOMKilled : Prometheus manque de mémoire.
Solutions :
- Augmentez les limites de ressources :
server: resources: requests: memory: "1Gi" limits: memory: "2Gi"- Réduisez la rétention ou le nombre de séries
Validation finale
Section intitulée « Validation finale »Avant de passer au module suivant, vérifiez que tout fonctionne.
-
Prometheus est accessible
Fenêtre de terminal curl -s http://localhost:9090/api/v1/status/config | jq .statusRésultat attendu :
"success" -
Les targets sont UP
Fenêtre de terminal curl -s http://localhost:9090/api/v1/targets | jq '.data.activeTargets | map(select(.health=="up")) | length'Résultat attendu : Un nombre > 0 (idéalement tous vos targets)
-
Les métriques système sont présentes
Fenêtre de terminal curl -s 'http://localhost:9090/api/v1/query?query=node_memory_MemAvailable_bytes' | jq '.data.result | length'Résultat attendu : Un nombre > 0 (les métriques node_exporter)
-
Vous savez écrire des requêtes PromQL
Testez cette requête dans l’interface :
topk(3, sum by (handler) (rate(prometheus_http_requests_total[5m])))Résultat attendu : Les 3 handlers Prometheus avec le plus de requêtes par seconde.
Ce que vous avez appris
Section intitulée « Ce que vous avez appris »Récapitulons les concepts clés de ce module :
- Architecture pull : Prometheus va chercher les métriques sur les endpoints
/metrics - 4 types de métriques :
- Counter : toujours utiliser
rate()ouincrease() - Gauge : valeur directement utilisable
- Histogram : pour les percentiles avec
histogram_quantile() - Summary : à éviter si possible
- Counter : toujours utiliser
- PromQL :
- Sélecteurs avec labels :
{method="GET", status=~"2.."} - Fonctions :
rate(),sum(),avg(),histogram_quantile() - Agrégation :
by (label),without (label)
- Sélecteurs avec labels :
- Service Discovery : Prometheus découvre les pods Kubernetes automatiquement
- Recording rules : pré-calcul pour de meilleures performances
Prochaine étape
Section intitulée « Prochaine étape »Vous avez maintenant Prometheus qui collecte les métriques. Mais l’interface de Prometheus est… basique. Dans le prochain module, nous installons Grafana pour créer de vrais dashboards exploitables.