Aller au contenu
Edouard Topin's Blog
Observabilité as Code sur VCF & Kubernetes / Série 02/05

Prometheus & Grafana sur VKS : la stack de monitoring en production

Déployer kube-prometheus-stack sur VKS, configurer ServiceMonitors et PodMonitors, mettre en place les alertes, et intégrer les dashboards Grafana — un guide de production annoté.

Edouard Topin
6 min de lecture
Illustration éditoriale abstraite d'un panneau de graphe de séries temporelles avec des métriques Prometheus et des éléments de dashboard Grafana.

Prometheus est le standard de monitoring Kubernetes de facto depuis sa graduation CNCF en 2018. Chaque composant Kubernetes expose un endpoint /metrics. Chaque outil d’observabilité de l’écosystème comprend le format d’exposition Prometheus. La question pour un déploiement VKS n’est pas de savoir si utiliser Prometheus, mais comment le déployer et le configurer pour la production.

Cet article couvre le cycle de déploiement complet : installation de kube-prometheus-stack via Helm avec des valeurs annotées, configuration des ressources ServiceMonitor et PodMonitor pour instrumenter vos applications, mise en place du routage Alertmanager, et connexion de Grafana aux dashboards essentiels. On passe directement aux patterns qui survivent au contact de la production.

Le modèle de données Prometheus

Avant de toucher un seul fichier YAML, comprendre le modèle de données est essentiel. Le modèle de données Prometheus définit une série temporelle comme un ensemble de valeurs float64 horodatées identifiées par un nom de métrique et un ensemble de labels clé-valeur.

# HELP node_cpu_seconds_total Seconds the CPU spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 72891.43
node_cpu_seconds_total{cpu="0",mode="system"} 842.17
node_cpu_seconds_total{cpu="1",mode="idle"} 71934.88

Le nom de métrique et les labels identifient ensemble de façon unique une série temporelle. La cardinalité — le nombre de combinaisons uniques de valeurs de labels — détermine la consommation mémoire. Une haute cardinalité (par exemple, un label contenant un UUID de requête) peut épuiser la mémoire de Prometheus. Gardez les valeurs de labels bornées : namespace, pod, container, node sont de bons labels ; les IDs de requêtes ne le sont pas.

Prometheus définit quatre types de métriques principaux :

  • Counter — valeur qui augmente de façon monotone (nombre de requêtes, nombre d’erreurs). Ne décroît jamais sauf au redémarrage.
  • Gauge — valeur qui peut monter ou descendre (utilisation mémoire, connexions actives, température).
  • Histogram — observations d’échantillons regroupées en buckets configurables (durée de requête, taille de réponse). Expose des séries _bucket, _sum et _count. Utilisé pour les calculs de quantiles.
  • Summary — similaire à l’histogramme mais calcule les quantiles côté client. Préférez les histogrammes dans la plupart des cas — ils peuvent être agrégés entre réplicas, pas les summaries.

L’Opérateur Prometheus étend ce modèle avec les Exemplars : des observations d’échantillons qui portent un trace ID, permettant la corrélation depuis une observation d’histogramme directement vers la trace distribuée dans Tempo ou Jaeger.

Déployer kube-prometheus-stack

Le chart Helm kube-prometheus-stack regroupe Prometheus, Alertmanager, Grafana, node-exporter, kube-state-metrics et l’Opérateur Prometheus. C’est la voie d’installation standard pour les clusters en production.

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm upgrade --install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  --values prometheus-values.yaml \
  --version 65.x

Le fichier prometheus-values.yaml est là où vit la configuration de production. Les valeurs par défaut fonctionnent pour une démo mais nécessitent des ajustements pour VKS :

# prometheus-values.yaml — configuration production pour VKS
prometheus:
  prometheusSpec:
    # Rétention : 15 jours local, remote_write pour le long terme
    retention: 15d
    retentionSize: "45GB"

    # Stockage : politique vSAN pour le TSDB
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: vsan-default-storage-policy
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 50Gi

    # Limites ressources : calibrées pour 300 targets / 1M séries actives
    resources:
      requests:
        cpu: 500m
        memory: 2Gi
      limits:
        cpu: 2000m
        memory: 6Gi

    # Intervalle de scrape : 30s est le défaut production
    scrapeInterval: 30s
    evaluationInterval: 30s

    # IMPORTANT : surveiller les ServiceMonitors dans tous les namespaces
    serviceMonitorSelectorNilUsesHelmValues: false
    serviceMonitorNamespaceSelector: {}
    serviceMonitorSelector: {}
    podMonitorSelectorNilUsesHelmValues: false
    podMonitorNamespaceSelector: {}
    podMonitorSelector: {}

    # Stockage Exemplar (pour la corrélation avec les traces)
    enableFeatures:
      - exemplar-storage

alertmanager:
  alertmanagerSpec:
    storage:
      volumeClaimTemplate:
        spec:
          storageClassName: vsan-default-storage-policy
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 5Gi

grafana:
  persistence:
    enabled: true
    storageClassName: vsan-default-storage-policy
    size: 10Gi
  adminPasswordSecret: grafana-admin-secret
  adminPasswordSecretKey: password

nodeExporter:
  enabled: true

kubeStateMetrics:
  enabled: true

Schémas ServiceMonitor et PodMonitor

L’Opérateur Prometheus définit deux ressources personnalisées pour configurer les cibles de scrape : ServiceMonitor cible les Services Kubernetes, PodMonitor cible directement les pods.

ServiceMonitor (monitoring.coreos.com/v1)

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-api-metrics
  namespace: production
  labels:
    release: kube-prometheus-stack
spec:
  selector:
    matchLabels:
      app: my-api
  namespaceSelector:
    matchNames:
      - production
  endpoints:
    - port: metrics          # Port nommé sur le Service
      interval: 30s
      path: /metrics
      scheme: http
      # Relabeling : supprimer les labels haute cardinalité avant le stockage
      metricRelabelings:
        - sourceLabels: [__name__]
          regex: "go_.*"
          action: drop        # Supprimer les métriques runtime Go

PodMonitor (monitoring.coreos.com/v1)

Utilisez PodMonitor quand il n’y a pas de Service Kubernetes devant les pods — par exemple des jobs batch ou des pods qui exposent des métriques sans avoir besoin de load balancing.

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: batch-job-metrics
  namespace: processing
spec:
  selector:
    matchLabels:
      app: batch-processor
  podMetricsEndpoints:
    - port: metrics
      interval: 60s
      path: /metrics

Règles d’alerte essentielles

Prometheus évalue les règles d’enregistrement et d’alerte sur les séries temporelles collectées selon un intervalle configurable. L’Opérateur Prometheus utilise des ressources PrometheusRule.

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: platform-alerts
  namespace: monitoring
  labels:
    release: kube-prometheus-stack
spec:
  groups:
    - name: kubernetes.workload
      interval: 30s
      rules:
        - alert: PodRestartingFrequently
          expr: |
            increase(kube_pod_container_status_restarts_total[15m]) > 3
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "Pod {{ $labels.pod }} redémarre fréquemment"
            description: "{{ $labels.container }} dans {{ $labels.namespace }}/{{ $labels.pod }} a redémarré {{ $value }} fois en 15m"

        - alert: DeploymentReplicasMismatch
          expr: |
            kube_deployment_spec_replicas != kube_deployment_status_available_replicas
          for: 10m
          labels:
            severity: critical
          annotations:
            summary: "Déploiement {{ $labels.deployment }} incohérence de réplicas"

    - name: kubernetes.resource
      rules:
        - record: node:cpu_utilization:rate5m
          expr: |
            1 - avg by(node) (rate(node_cpu_seconds_total{mode="idle"}[5m]))

Les cinq dashboards Grafana essentiels

La bibliothèque de dashboards Grafana propose des dashboards maintenus par la communauté qui fonctionnent directement avec kube-prometheus-stack. Importez par ID depuis l’UI Grafana (+ → Import → Entrer l’ID du dashboard).

Dashboard 15760 — Kubernetes / Views / Global. Vue d’ensemble à l’échelle du cluster : nombre de pods, santé des déploiements, pression ressources nœuds, utilisation PVC. Le point de départ en vue unique pour tout incident.

Dashboard 15757 — Kubernetes / Views / Namespaces. Détail par namespace : CPU, mémoire, nombre de pods et I/O réseau. Utile pour les discussions de chargeback et de planification de capacité.

Dashboard 15758 — Kubernetes / Views / Workloads. Performance individuelle des deployments/statefulsets/daemonsets avec drill-down au niveau pod.

Dashboard 1860 — Node Exporter Full. Le dashboard de référence pour les métriques nœud physique/virtuel : utilisation CPU par mode, détail mémoire (buffers/cache/disponible), I/O disque, trafic réseau, utilisation système de fichiers. Fonctionne avec le node-exporter inclus dans kube-prometheus-stack.

Dashboard 7587 — Prometheus 2.0 Overview. Méta-monitoring : performance de Prometheus lui-même — durée de scrape, taille de la tête TSDB, latence d’évaluation des règles, troncature WAL. Essentiel pour détecter que Prometheus lui-même devient un goulot d’étranglement.

Dashboard 9578 — Alertmanager. Alertes actives, silences, inhibitions et visualisation de l’arbre de routage. Le centre opérationnel pour la gestion des alertes. À coupler avec une intégration PagerDuty ou Slack configurée dans les routes Alertmanager.

Rétention et dimensionnement du stockage

Prometheus stocke les séries temporelles dans un TSDB local (base de données de séries temporelles) avec un write-ahead log et des compactions périodiques. Le dimensionnement suit une formule basée sur les séries actives et la durée de rétention.

Pour un cluster avec 300 cibles de scrape et un intervalle de 30 secondes :

  • Octets moyens par échantillon : environ 1,5 octet (après compression TSDB)
  • Estimation des séries actives : 300 cibles × 2 000 métriques/cible = 600 000 séries
  • Rétention 15 jours à 30s : 600 000 × (15j × 24h × 120 échantillons/h) × 1,5 octet ≈ 46 Go

Ce chiffre correspond au retentionSize: "45GB" du fichier de valeurs ci-dessus. Pour une rétention plus longue, l’approche standard est remote_write vers un backend long terme : Thanos, Cortex, VictoriaMetrics ou Mimir. Ces backends stockent des blocs compressés en object storage (S3 ou vSAN Object Storage) et exposent une API compatible Prometheus à Grafana.

Considérations de passage à l’échelle pour les grands estates VCF

Une instance Prometheus scrappant 300 cibles avec 600K séries actives tient confortablement en 4 Go de RAM. À 3 000 cibles ou 6M de séries, il faut fragmenter. L’Opérateur Prometheus supporte le sharding horizontal via shards dans PrometheusSpec.

Pour les estates VCF multi-clusters, le pattern recommandé est un Prometheus par cluster VKS (le scraping fédéré crée des goulots d’étranglement et des points de défaillance uniques) avec un Grafana centralisé utilisant remote_write depuis chaque cluster vers une instance partagée Thanos ou Mimir. Cela donne une isolation par cluster avec des requêtes et des dashboards cross-cluster en un seul endroit.

Références.

Reçois le prochain par email

Les nouveaux articles et séries, envoyés à leur publication. Aucun autre courrier.

Désabonnement en un clic, à tout moment.

Retour au blog
Partager

Articles similaires

  1. 17 min de lecture

    Modèles de coûts FinOps : ce que facturent AWS, Azure et GCP — et ce que VCF calcule

    Un cluster-heure EKS, un palier AKS, une requête de pod GKE et un matériel VCF amorti ne sont pas quatre valeurs de la même variable. Ce que chaque plateforme facture, et ce que VCF calcule.

  2. 23 min de lecture

    Network policies et Cilium : construire un default-deny défendable

    L'API NetworkPolicy est livrée avec Kubernetes ; l'appliquer est le travail du CNI. Ce que Cilium ajoute, ce qui reste standard, et comment atteindre le default-deny sans casser la production.

  3. 18 min de lecture

    RBAC Kubernetes : les fondations, et les pièges qui survivent à l'audit

    Chacun de ces pièges est publié sur kubernetes.io. Ce qui manque, c'est leur mise en ordre — et le chemin qui mène d'un Namespace vSphere jusqu'à cluster-admin.

Suivre le blog

Nouveaux articles, réflexions et mises à jour.