Article principal · Ce tutoriel fait partie de la série Kubernetes domestique sur Proxmox VE. Tutoriel précédent : Argo CD GitOps. Tutoriel suivant : Velero backups.
Sans observabilité, on opère un cluster Kubernetes les yeux bandés : on apprend qu un nœud est saturé quand les utilisateurs s en plaignent, on découvre qu un pod boucle après plusieurs heures de redémarrages, on ne sait pas si les sauvegardes sont vraiment passées la nuit dernière. Le chart Helm kube-prometheus-stack assemble en une installation cohérente Prometheus, Alertmanager, Grafana, node-exporter, kube-state-metrics et l opérateur Prometheus. La version 84.5.0 sortie en mai 2026 livre Prometheus 3.0, Grafana 11.7 et l opérateur Prometheus 0.90. Ce tutoriel installe le chart, vérifie que les métriques arrivent bien, configure les premières règles d alerte, et expose Grafana via Ingress avec authentification.
Étape 1 — Préparer le namespace et les volumes
Prometheus, Alertmanager et Grafana persistent leur état sur disque. Avec Rook-Ceph en place (tutoriel précédent), on dispose de la StorageClass rook-ceph-block par défaut. Aucun volume manuel à créer : le chart provisionne ce qu il faut.
kubectl create namespace monitoring
# Vérifier que la StorageClass par défaut est bien rook-ceph-block
kubectl get sc
# DEFAULT doit être (true) sur rook-ceph-block
Une StorageClass par défaut active évite de devoir spécifier storageClassName dans les valeurs Helm. Si plusieurs classes sont marquées par défaut, Kubernetes choisit aléatoirement, ce qui pose problème. La commande kubectl patch sc permet de basculer la mention is-default-class d une classe à l autre si besoin.
Étape 2 — Installer kube-prometheus-stack avec Helm
Le chart est dans le dépôt prometheus-community. L installation prend trois à cinq minutes pour télécharger les images et démarrer les pods.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
cat > values.yaml <<EOF
prometheus:
prometheusSpec:
retention: 15d
retentionSize: 30GiB
storageSpec:
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 50Gi
alertmanager:
alertmanagerSpec:
storage:
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
grafana:
persistence:
enabled: true
size: 10Gi
adminPassword: "ChangeMeQuickly"
defaultDashboardsEnabled: true
defaultDashboardsTimezone: Europe/Paris
EOF
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
--version 84.5.0 \
--namespace monitoring \
--values values.yaml
Le chart déploie environ 25 ressources : Prometheus, Alertmanager, Grafana, le DaemonSet node-exporter, kube-state-metrics, l opérateur Prometheus, plus une vingtaine de ServiceMonitor et de PrometheusRule prêts à l emploi. Vérifier que tout tourne avec kubectl get pods -n monitoring.
Étape 3 — Accéder à Grafana et explorer les dashboards livrés
Grafana est exposé sur un Service ClusterIP. Pour le premier accès, un port-forward suffit, on configurera l Ingress plus loin.
kubectl -n monitoring port-forward svc/kube-prometheus-stack-grafana 3000:80 &
# Ouvrir http://localhost:3000
# Login : admin
# Mot de passe : ChangeMeQuickly (à changer immédiatement après la connexion)
Au premier login, on découvre une trentaine de dashboards préconfigurés dans la barre latérale gauche : Kubernetes / Compute Resources / Cluster, Kubernetes / Networking / Cluster, Node Exporter / Nodes, Kubernetes / API server et d autres. Voir des graphes peuplés de données réelles confirme que Prometheus scrape correctement les exporters et que Grafana lit bien la datasource Prometheus configurée par défaut.
Étape 4 — Vérifier les ServiceMonitor pour Cilium et Rook
Les composants installés aux tutoriels précédents (Cilium, Rook-Ceph) exposent des métriques Prometheus. L opérateur Prometheus les découvre automatiquement via les ServiceMonitor, à condition que ces ServiceMonitor existent.
# Vérifier que les ServiceMonitor Cilium et Rook sont là
kubectl get servicemonitor -A
# Doit lister cilium, hubble, rook-ceph-mgr, rook-ceph-exporter
# Si manquant, l activer côté Helm de Cilium :
# helm upgrade cilium ... --set prometheus.enabled=true \
# --set operator.prometheus.enabled=true \
# --set hubble.metrics.enabled="{dns,drop,tcp,flow,icmp,http}"
Voir les ServiceMonitor permet d ouvrir dans Grafana les dashboards spécifiques à Cilium et Ceph, qui s importent depuis grafana.com par leur ID (Cilium ID 16611, Ceph Cluster ID 2842). On obtient une vue détaillée du débit eBPF par nœud, du nombre d objets Ceph par pool, des PG en cours de placement.
Étape 5 — Écrire la première règle d alerte personnalisée
Les PrometheusRule livrés couvrent les bases (nœud DiskFull, Pod en CrashLoop, etcd quorum perdu). Pour les charges métier, on ajoute des règles dédiées. Le manifest ci-dessous alerte si un service applicatif renvoie plus de 5 % d erreurs 5xx pendant cinq minutes.
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: app-error-rate
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
groups:
- name: app.errors
rules:
- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
/ sum(rate(http_requests_total[5m])) by (service) > 0.05
for: 5m
labels:
severity: warning
annotations:
summary: "Service {{ $labels.service }} returns >5% errors"
description: "Error rate is {{ $value | humanizePercentage }} over 5 minutes"
kubectl apply -f app-error-rate.yaml
# Vérifier que la règle est chargée
kubectl -n monitoring exec -it kube-prometheus-stack-prometheus-0 \
-c prometheus -- promtool check rules /etc/prometheus/rules/*.yaml | head
Une règle qui apparaît dans l interface Prometheus (Status → Rules) confirme que l opérateur Prometheus l a bien intégrée. Le label release: kube-prometheus-stack est essentiel : il déclare la règle au Prometheus principal, sans lui le manifest est ignoré silencieusement.
Étape 6 — Configurer Alertmanager pour notifier les bons canaux
Alertmanager reçoit les alertes de Prometheus, déduplique, regroupe et envoie aux canaux configurés (email, Discord, Slack, PagerDuty). Pour un homelab, un webhook Discord ou Telegram suffit largement.
apiVersion: v1
kind: Secret
metadata:
name: alertmanager-kube-prometheus-stack-alertmanager
namespace: monitoring
stringData:
alertmanager.yaml: |
route:
receiver: discord
group_by: ['alertname', 'severity']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- match:
severity: critical
receiver: discord
repeat_interval: 30m
receivers:
- name: discord
webhook_configs:
- url: https://discord.com/api/webhooks/...
send_resolved: true
Après kubectl apply, Alertmanager recharge sa configuration en quelques secondes (l opérateur surveille le Secret). Les alertes critiques arrivent toutes les 30 minutes, les alertes warning toutes les 4 heures, ce qui évite les rafales tout en gardant un signal vivant.
Étape 7 — Exposer Grafana via Ingress avec TLS
L accès permanent à Grafana via un nom DNS local (par exemple grafana.lan) est plus pratique que le port-forward. On utilise cert-manager avec un challenge DNS-01 pour obtenir un certificat Let s Encrypt valide même sur un domaine non exposé sur Internet.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana
namespace: monitoring
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod-dns
spec:
ingressClassName: cilium
tls:
- hosts:
- grafana.exemple.lan
secretName: grafana-tls
rules:
- host: grafana.exemple.lan
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kube-prometheus-stack-grafana
port:
number: 80
Une fois le certificat émis (visible via kubectl get certificate -n monitoring), Grafana répond en HTTPS sur l URL choisie. La même mécanique s applique aux autres composants à exposer (Argo CD, Hubble UI, dashboard Ceph), ce qui consolide une plateforme cohérente.
Étape 8 — Vérifier la collecte des métriques applicatives
Au-delà des métriques d infrastructure, les applications métier exposent souvent leurs propres métriques au format Prometheus sur /metrics. On les expose à Prometheus via un ServiceMonitor.
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: myapp
namespace: demo
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app: myapp
endpoints:
- port: metrics
interval: 30s
path: /metrics
kubectl apply -f myapp-servicemonitor.yaml
# Vérifier dans Prometheus UI : Status → Targets
# myapp doit apparaître avec State UP
Voir le target en état UP dans l interface Prometheus confirme que les métriques applicatives sont scrapées toutes les 30 secondes. Elles deviennent immédiatement requêtables en PromQL et utilisables dans des dashboards Grafana ou des règles d alerte.
Étape 9 — Vérifier la rétention et la consommation disque
Avec 15 jours de rétention et plafond à 30 Gio, Prometheus se débrouille seul. Les blocs anciens sont compactés et supprimés automatiquement. Vérifier régulièrement que la consommation reste sous le plafond.
kubectl -n monitoring exec kube-prometheus-stack-prometheus-0 -c prometheus \
-- du -sh /prometheus
# Doit afficher une taille croissante puis se stabiliser autour de 25 à 30 Gio
# Si la consommation menace le plafond, augmenter le PVC
kubectl -n monitoring patch pvc \
prometheus-kube-prometheus-stack-prometheus-db-prometheus-kube-prometheus-stack-prometheus-0 \
--patch '{"spec":{"resources":{"requests":{"storage":"100Gi"}}}}'
Le PVC est extensible parce que allowVolumeExpansion: true est défini sur la StorageClass Rook-Ceph. Le redimensionnement est en ligne, sans interruption de Prometheus. Pour les besoins de longue rétention (un an de métriques), prévoir Thanos ou VictoriaMetrics qui externalisent les blocs vers un objectstore S3 (le bucket Rook créé au tutoriel précédent fait l affaire).
Erreurs fréquentes et résolutions
| Symptôme | Cause | Résolution |
|---|---|---|
| Le pod Prometheus reste en CrashLoopBackOff | PVC non lié, StorageClass introuvable | Vérifier kubectl get pvc -n monitoring et la StorageClass |
| Grafana affiche « No data » sur les dashboards | Datasource Prometheus mal configurée ou network policy bloque | Vérifier dans Grafana Configuration → Data Sources |
| Les ServiceMonitor sont ignorés | Label release: kube-prometheus-stack manquant |
Ajouter le label sur les ServiceMonitor et PrometheusRule |
| Alertmanager ne notifie pas | Webhook URL invalide ou bloqué par firewall | Tester le webhook avec curl depuis un pod du cluster |
| Mémoire de Prometheus explose | Trop de séries actives, cardinality bomb | Identifier la métrique fautive avec topk(10, count by (__name__)({__name__=~".+"})) |
Pour la suite du parcours
L observabilité est en place : métriques collectées, dashboards lisibles, alertes notifiées. La dernière brique du parcours concerne la sauvegarde : sans Velero, une erreur de manipulation peut anéantir des semaines de travail. Le tutoriel Sauvegardes Kubernetes avec Velero détaille la mise en place de sauvegardes programmées vers le bucket S3 Ceph et la procédure de restauration testée. Pour la vue d ensemble, retourner au guide principal Kubernetes domestique sur Proxmox VE.
Ressources et documentation officielle
- kube-prometheus-stack chart : github.com/prometheus-community/helm-charts
- Documentation Prometheus : prometheus.io/docs
- Documentation Grafana : grafana.com/docs/grafana
- Documentation Alertmanager : prometheus.io/docs/alerting
- Spec PrometheusRule : prometheus-operator.dev/api
- Spec ServiceMonitor : prometheus-operator.dev/design
Étape 10 — Versionner les valeurs Helm dans Argo CD
Le fichier values.yaml qui pilote l installation est aussi important que les manifestes générés. Le perdre signifie devoir reconstituer mentalement les options choisies. La pratique recommandée consiste à le commiter dans le dépôt GitOps et à laisser Argo CD piloter le déploiement de kube-prometheus-stack via une Application Helm.
mkdir -p clusters/homelab/infra/kube-prometheus-stack
cp values.yaml clusters/homelab/infra/kube-prometheus-stack/values.yaml
cat > clusters/homelab/infra/kube-prometheus-stack/application.yaml <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: kube-prometheus-stack
namespace: argocd
spec:
project: default
sources:
- repoURL: https://prometheus-community.github.io/helm-charts
targetRevision: 84.5.0
chart: kube-prometheus-stack
helm:
valueFiles:
- \$values/clusters/homelab/infra/kube-prometheus-stack/values.yaml
- repoURL: git@github.com:moncompte/homelab-gitops.git
ref: values
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
selfHeal: true
EOF
git add clusters/homelab/infra/kube-prometheus-stack
git commit -m "Manage kube-prometheus-stack via Argo CD"
git push
Une fois cette Application synchronisée, mettre à niveau Prometheus revient à incrémenter targetRevision dans le manifest et committer. Argo CD applique l upgrade Helm de manière transactionnelle, et selfHeal protège contre les modifications hors-Git.
Étape 11 — Surveiller la santé des sauvegardes Velero (anticipation)
Le tutoriel suivant déploiera Velero pour les sauvegardes. Anticipation utile : Velero expose des métriques Prometheus qui se branchent immédiatement sur le stack qu on vient d installer. Le ServiceMonitor Velero apparaît automatiquement quand on installe Velero avec le flag --set metrics.enabled=true. Les dashboards Grafana à importer (ID 11055) affichent : nombre de sauvegardes par jour, durée moyenne, taux d échec, taille du dernier snapshot par namespace.
Configurer dès maintenant une PrometheusRule qui alerte si une sauvegarde Velero échoue ou n a pas tourné depuis plus de 26 heures évite la mauvaise surprise du jour où l on a vraiment besoin d une restauration.
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: velero-backup-health
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
groups:
- name: velero
rules:
- alert: VeleroBackupFailed
expr: velero_backup_failure_total > 0
for: 10m
labels:
severity: critical
- alert: VeleroBackupTooOld
expr: time() - velero_backup_last_successful_timestamp > 93600
for: 30m
labels:
severity: critical
Avec ces deux règles en place, on saura sans délai si une sauvegarde nocturne a échoué ou si Velero a cessé de fonctionner. C est exactement le type de signal qu on n a pas naturellement et qu on regrette de ne pas avoir le jour de l incident.
Étape 12 — Comprendre les coûts mémoire et CPU du stack
kube-prometheus-stack n est pas léger, et c est utile de mesurer sa consommation réelle pour dimensionner correctement le cluster. Sur un homelab à six nœuds avec 30 ServiceMonitor actifs et 15 jours de rétention, les ordres de grandeur observés en mai 2026 sont les suivants : Prometheus consomme 1,5 à 2,5 Gio de RSS et 0,3 à 0,6 vCPU en moyenne ; Grafana consomme 200 Mio de RSS et 0,05 vCPU au repos ; Alertmanager consomme 100 Mio ; node-exporter consomme 30 à 50 Mio par nœud ; kube-state-metrics consomme environ 200 Mio sur un cluster de moins de 500 pods.
Le poste qui croît le plus vite est Prometheus, et sa croissance est dominée par la cardinalité des séries plus que par le nombre de métriques. Une métrique avec un label request_id unique par requête peut générer des millions de séries actives en quelques heures et faire exploser la mémoire. Les exporters bien conçus (node-exporter, kube-state-metrics) ne posent pas ce problème ; les métriques applicatives écrites à la va-vite si.
Le bouton à connaître pour ces situations est storage.tsdb.head-chunks-write-queue-size et le profiler intégré accessible via /debug/pprof/ sur le pod Prometheus. Mais la vraie réponse consiste à auditer les métriques applicatives avant de les laisser entrer en production : lister les séries top-cardinality dans Prometheus pour identifier les coupables potentiels avant qu ils ne deviennent un problème opérationnel.
Le savoir-faire qui paie sur la durée consiste à régulièrement passer en revue les métriques actives et à supprimer celles qui ne servent à rien. Un cluster en bonne santé observe ce qu il faut, et seulement ce qu il faut.
Cette discipline d hygiène métrologique s acquiert en quelques mois et fait toute la différence entre un cluster qu on observe sereinement et un cluster qui s observe lui-même au point d en consommer toutes ses ressources.