Aller au contenu
Outils medium

Configuration de Prometheus

17 min de lecture

Ce guide vous accompagne pour configurer Prometheus de manière efficace. Vous apprendrez à définir vos targets, utiliser le service discovery et configurer les règles d'alerte.

  • Structurer un prometheus.yml : global, scrape_configs, rule_files, alerting
  • Découvrir les targets automatiquement avec Kubernetes, Consul ou des fichiers
  • Transformer les labels avec relabel_configs et metric_relabel_configs
  • Écrire des règles d'alerte et des recording rules exploitables
  • Valider toute la configuration avec promtool avant le reload

Le fichier prometheus.yml est le cœur de la configuration. Il se divise en plusieurs sections.

prometheus.yml
# Paramètres globaux
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
cluster: production
region: eu-west-1
# Fichiers de règles d'alerte
rule_files:
- "rules/*.yml"
# Configuration Alertmanager
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
# Configuration du scraping
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']

La section global définit les paramètres par défaut pour tous les jobs.

global:
scrape_interval: 15s # Intervalle de scraping par défaut
scrape_timeout: 10s # Timeout par requête de scraping
evaluation_interval: 15s # Intervalle d'évaluation des règles
external_labels: # Labels ajoutés à toutes les métriques
cluster: production
env: prod
ParamètreDescriptionValeur recommandée
scrape_intervalFréquence de collecte15s à 60s
scrape_timeoutTimeout HTTP< scrape_interval
evaluation_intervalÉvaluation des alertes= scrape_interval
external_labelsLabels globauxcluster, env, region

C'est ici que vous définissez quoi scraper. Chaque job représente un groupe de targets similaires.

La méthode la plus simple : lister les targets manuellement.

scrape_configs:
- job_name: 'node-exporter'
static_configs:
- targets:
- 'server1:9100'
- 'server2:9100'
- 'server3:9100'
labels:
datacenter: paris

Les labels ajoutés ici seront présents sur toutes les métriques collectées.

Chaque job peut surcharger les paramètres globaux :

scrape_configs:
- job_name: 'slow-endpoints'
scrape_interval: 60s # Surcharge le global
scrape_timeout: 30s
metrics_path: /metrics # Chemin par défaut
scheme: https # http ou https
basic_auth:
username: prometheus
password_file: /etc/prometheus/password
static_configs:
- targets: ['api.example.com:443']
ParamètreDescriptionDéfaut
scrape_intervalIntervalle spécifique au jobglobal
metrics_pathChemin de l'endpoint/metrics
schemeProtocole HTTP(S)http
basic_authAuthentification HTTP Basic-
bearer_token_fileToken pour auth Bearer-
tls_configConfiguration TLS-

Le service discovery permet à Prometheus de découvrir automatiquement les targets dans des environnements dynamiques.

Le plus courant en production. Prometheus découvre les pods, services et nodes.

scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
# Garder uniquement les pods avec l'annotation prometheus.io/scrape
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
# Remplacer le port de l'adresse par celui de l'annotation
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__

La seconde règle mérite un détour, parce que c'est là que les configurations maison se cassent. L'action replace concatène les valeurs de source_labels séparées par un point-virgule, applique la regex sur cette concaténation, puis écrit dans target_label le développement de replacement. Si vous ne mettez que l'annotation en source, __address__ prend pour valeur le numéro de port seul et la target devient injoignable. Il faut donc lire aussi __address__, capturer son hôte d'un côté et le port de l'autre, et les recoller en $1:$2. C'est la forme retenue par l'exemple officiel documentation/examples/prometheus-kubernetes.yml du dépôt Prometheus.

Rôles disponibles pour Kubernetes :

RoleDécouvre
nodeLes nodes du cluster
podLes pods (toutes annotations)
serviceLes services Kubernetes
endpointsLes endpoints de services
endpointsliceEndpointSlices (K8s 1.21+)
ingressLes ingress

Pour les environnements non-Kubernetes utilisant Consul.

scrape_configs:
- job_name: 'consul-services'
consul_sd_configs:
- server: 'consul.example.com:8500'
services: [] # Tous les services
relabel_configs:
- source_labels: [__meta_consul_tags]
regex: .*,prometheus,.*
action: keep

Utile pour alimenter dynamiquement la liste des targets sans service discovery natif.

scrape_configs:
- job_name: 'file-based'
file_sd_configs:
- files:
- '/etc/prometheus/targets/*.json'
refresh_interval: 5m
/etc/prometheus/targets/nodes.json
[
{
"targets": ["server1:9100", "server2:9100"],
"labels": {
"env": "production",
"team": "infra"
}
}
]

L'avantage : vous pouvez générer ces fichiers avec Ansible, Terraform ou un script.

Le relabeling est une fonctionnalité puissante qui permet de transformer les labels avant le stockage.

Tout repose sur une distinction de moment d'application, et c'est elle qui détermine le coût. relabel_configs s'exécute pendant la découverte, donc avant la moindre requête HTTP : une target écartée à ce stade n'est jamais interrogée. metric_relabel_configs s'exécute à la réception de la réponse : la charge réseau et le travail de l'exporter ont déjà eu lieu, seul le stockage est économisé. Les labels commençant par un double tiret bas (__address__, __meta_*) n'existent que pendant cette phase et sont supprimés avant le stockage.

  • relabel_configs : appliqué avant le scraping (modifie les targets)
  • metric_relabel_configs : appliqué après le scraping (modifie les métriques)

Les trois premières actions travaillent sur les valeurs des labels, les trois dernières sur les noms de labels. Cette différence explique pourquoi drop et labeldrop ne sont pas interchangeables : drop élimine une target ou une série entière, labeldrop retire une étiquette de séries que l'on conserve. Attention, retirer un label avec labeldrop peut fusionner deux séries qui ne se distinguaient que par lui, et Prometheus rejette alors la collecte avec une erreur de série dupliquée.

ActionDescription
replaceRemplace un label par une valeur
keepGarde uniquement les targets matchant
dropSupprime les targets matchant
labelmapRenomme des labels par regex
labeldropSupprime des labels par regex
labelkeepGarde uniquement certains labels

Renommer un label :

relabel_configs:
- source_labels: [__meta_kubernetes_pod_node_name]
target_label: node

Filtrer les targets :

relabel_configs:
- source_labels: [__meta_kubernetes_namespace]
action: keep
regex: production|staging

Extraire d'un label :

relabel_configs:
- source_labels: [__address__]
regex: '(.+):.*'
replacement: '$1'
target_label: instance

Supprimer des métriques inutiles :

metric_relabel_configs:
- source_labels: [__name__]
regex: 'go_.*' # Supprime les métriques Go runtime
action: drop

Les règles définissent les conditions qui déclenchent des alertes.

Référencez vos fichiers de règles dans prometheus.yml :

rule_files:
- "rules/infrastructure.yml"
- "rules/applications.yml"

Une alerte se déclenche quand l'expression expr renvoie au moins une série, pas quand elle renvoie une valeur particulière : c'est le filtre > 80 de l'exemple qui fait tout le travail de sélection. Le champ for est celui qu'on oublie le plus souvent ; sans lui, un pic de trente secondes réveille l'astreinte pour rien. Séparez bien les deux blocs du bas : labels sert au routage dans Alertmanager et doit rester à faible cardinalité, annotations porte le texte lu par un humain et accepte des templates Go.

rules/infrastructure.yml
groups:
- name: node-alerts
interval: 30s # Surcharge evaluation_interval
rules:
- alert: HighCPU
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
team: infra
annotations:
summary: "High CPU on {{ $labels.instance }}"
description: "CPU usage is {{ $value | printf \"%.1f\" }}%"
runbook_url: "https://wiki.example.com/runbooks/high-cpu"
ChampDescription
alertNom de l'alerte
exprExpression PromQL (doit retourner > 0 pour alerter)
forDurée pendant laquelle la condition doit être vraie
labelsLabels ajoutés à l'alerte (pour le routage)
annotationsInformations contextuelles (templates supportés)

Ces trois familles constituent une base à adapter, pas à copier telle quelle : les seuils dépendent de votre plateforme. Deux points de vigilance. L'onglet Infra repose sur les métriques de node_exporter, l'onglet Kubernetes sur celles de kube-state-metrics : sans ces exporters déployés, les expressions ne renvoient rien et les alertes ne se déclenchent jamais, ce qui donne un faux sentiment de calme. L'onglet Applications montre la seule formule de taux d'erreur correcte, un ratio d'un rate sur un autre ; comparer un compteur brut à un seuil fixe produit des alertes qui ne partent qu'une fois et ne s'éteignent jamais.

groups:
- name: infrastructure
rules:
- alert: InstanceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} down"
- alert: HighMemory
expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 90
for: 5m
labels:
severity: warning
annotations:
summary: "High memory on {{ $labels.instance }}"
- alert: DiskFull
expr: (1 - node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100 > 85
for: 10m
labels:
severity: warning
annotations:
summary: "Disk {{ $labels.mountpoint }} full on {{ $labels.instance }}"

Avant de déployer, validez la syntaxe :

Fenêtre de terminal
promtool check rules rules/*.yml

Les recording rules pré-calculent des expressions coûteuses et les stockent comme nouvelles métriques.

groups:
- name: recording-rules
rules:
- record: job:http_requests:rate5m
expr: sum(rate(http_requests_total[5m])) by (job)
- record: instance:cpu_usage:percent
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Avantages :

  • Dashboard plus rapide (pas de calcul à chaque refresh)
  • Expressions plus simples dans les alertes
  • Réduit la charge sur Prometheus

Trois sujets font la différence entre une instance qui tient un an et une instance qu'il faut redémarrer tous les mois : le rangement des fichiers, la cohérence des labels entre équipes, et la maîtrise de la cardinalité. Les deux premiers coûtent peu et se décident au démarrage ; le troisième est celui qu'on découvre en production, quand la mémoire du serveur sature.

Cette arborescence sépare ce qui change rarement de ce qui change souvent. Le prometheus.yml est stable, alors que rules/ évolue à chaque nouveau service et que targets/ peut être régénéré à chaque déploiement. Le glob rules/*.yml de la section rule_files fait que déposer un fichier suffit à l'activer au prochain reload, sans toucher à la configuration principale.

/etc/prometheus/
├── prometheus.yml # Config principale
├── rules/
│ ├── infrastructure.yml # Alertes infra
│ ├── applications.yml # Alertes applicatives
│ └── recording.yml # Recording rules
└── targets/
├── nodes.json # Targets file-based
└── services.json

Utilisez des labels cohérents dans tout l'écosystème :

LabelUsageExemples
envEnvironnementproduction, staging, dev
teamÉquipe responsablebackend, infra, data
serviceNom du serviceapi-gateway, auth-service
datacenterLocalisationparis, dublin

La cardinalité est le nombre de séries temporelles uniques. C'est le principal facteur de consommation mémoire.

promtool est livré avec Prometheus et doit tourner avant tout rechargement, en local comme dans votre pipeline. Il ne vérifie pas que la configuration est pertinente, seulement qu'elle est valide : une target injoignable ou une expression qui ne renvoie jamais rien passeront le contrôle sans broncher. Notez que check config suit aussi les rule_files référencés et valide les fichiers de règles au passage. Un code de sortie différent de zéro suffit à faire échouer un job CI, ce qui évite de découvrir une erreur de syntaxe après le systemctl reload.

Fenêtre de terminal
# Vérifier prometheus.yml (et les fichiers de règles qu'il référence)
promtool check config /etc/prometheus/prometheus.yml
# Vérifier les règles
promtool check rules /etc/prometheus/rules/*.yml
# Tester une requête PromQL
promtool query instant http://localhost:9090 'up'

Ces quatre symptômes ont un point commun : Prometheus ne signale aucune erreur, c'est le résultat attendu qui manque. Commencez toujours par la page Status > Targets de l'interface web, qui affiche pour chaque target son état, la date du dernier scrape et le message d'erreur exact. Pour les alertes muettes, collez l'expression telle quelle dans l'onglet Graph : si elle ne renvoie aucune série, la règle ne se déclenchera jamais, quel que soit le seuil.

SymptômeCause probableSolution
Target toujours "DOWN"Réseau / firewallcurl http://target:port/metrics
Pas de métriques après reloadSyntaxe YAMLpromtool check config
Trop de sériesCardinalité élevéemetric_relabel_configs avec drop
Alertes ne se déclenchent pasExpression jamais vraieTester dans l'UI
  • scrape_configs : définit les targets à scraper
  • Service Discovery : automatise la découverte (Kubernetes, Consul, files)
  • Relabeling : transforme les labels (avant ou après scraping)
  • Recording rules : pré-calcule les expressions coûteuses
  • promtool : valide toujours la config avant reload

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn