269 8 min de lecture · 1 553 mots

J’ai arrêté d’écrire mes SLOs Prometheus à la main

J'ai construit nines.arewel.com pour générer mes SLOs Prometheus en trois étapes. Demo : disponibilité de l'UI Proxmox sur heighliner, déploiement du ZIP validé sur hubble.

À chaque nouveau service sur heighliner, je me retrouvais à copier-coller le même bloc de YAML. Recording rules pour le ratio d’erreur sur 5 minutes, 30 minutes, 1 heure, 6 heures. Error budget restant sur 30 jours. Deux paires d’alertes multi-burn-rate avec les coefficients du livre SRE de Google. Et invariablement, j’oubliais de renommer un label, la règle ne matchait plus, le dashboard Grafana restait vide deux jours avant que je comprenne pourquoi.

J’ai compté. Un seul SLI de disponibilité pour une seule URL : 47 lignes de YAML. Multiplié par six services, ça fait une soirée à écrire du YAML au lieu de faire de l’infra.

J’ai construit nines.arewel.com pour résoudre exactement ça.

Pourquoi les SLOs multi-burn-rate sont un piège à écrire manuellement

L’idée de base est simple. Un SLO à 99% sur 30 jours t’autorise 432 minutes d’indisponibilité dans le mois. C’est l’error budget. Une alerte qui se déclenche quand il est épuisé, c’est trop tard. D’où les alertes multi-burn-rate : elles détectent deux vitesses de consommation.

Le fast burn (14.4×) : si ton service consomme le budget 14 fois plus vite que prévu, il sera épuisé en moins d’une heure. Alerte critique, page immédiate. Le slow burn (6×) : fuite silencieuse sur 6 heures, ticket à traiter dans la journée.

Ces coefficients viennent directement du chapitre 6 du livre SRE de Google. Ils fonctionnent bien pour une fenêtre de 30 jours et un SLO à 99%. Mais change l’objectif à 99.5%, et l’error budget change, les seuils changent, les fenêtres de confirmation changent. C’est là que les bugs s’introduisent — pas dans la logique, dans les constantes copiées-collées.

Voilà ce que ça donne pour un seul SLI, la sonde Blackbox sur l’UI Proxmox de heighliner :

groups:
  - name: slo:heighliner_proxmox_ui:rules
    interval: 30s
    rules:
      - record: slo:heighliner_proxmox_ui:error_ratio5m
        expr: |
          1 - avg_over_time(
            probe_success{job="blackbox",instance="https://heighliner.arewel.com:8006"}[5m]
          )
      - record: slo:heighliner_proxmox_ui:error_ratio30m
        expr: |
          1 - avg_over_time(
            probe_success{job="blackbox",instance="https://heighliner.arewel.com:8006"}[30m]
          )
      - record: slo:heighliner_proxmox_ui:error_ratio1h
        expr: |
          1 - avg_over_time(
            probe_success{job="blackbox",instance="https://heighliner.arewel.com:8006"}[1h]
          )
      - record: slo:heighliner_proxmox_ui:error_ratio6h
        expr: |
          1 - avg_over_time(
            probe_success{job="blackbox",instance="https://heighliner.arewel.com:8006"}[6h]
          )
      - record: slo:heighliner_proxmox_ui:error_budget_ratio
        expr: |
          (
            1 - avg_over_time(
              probe_success{job="blackbox",instance="https://heighliner.arewel.com:8006"}[30d]
            )
          ) / (1 - 0.99)

  - name: slo:heighliner_proxmox_ui:alerts
    rules:
      - alert: SLOBurnFast_heighliner_proxmox_ui
        expr: |
          slo:heighliner_proxmox_ui:error_ratio5m > (14.4 * 0.01)
          and
          slo:heighliner_proxmox_ui:error_ratio1h > (14.4 * 0.01)
        for: 2m
        labels:
          severity: critical
          slo: heighliner_proxmox_ui
        annotations:
          summary: "Budget SLO épuisé en < 1h si ce rythme continue"
      - alert: SLOBurnSlow_heighliner_proxmox_ui
        expr: |
          slo:heighliner_proxmox_ui:error_ratio30m > (6 * 0.01)
          and
          slo:heighliner_proxmox_ui:error_ratio6h > (6 * 0.01)
        for: 15m
        labels:
          severity: warning
          slo: heighliner_proxmox_ui
        annotations:
          summary: "Burn lent — fuite silencieuse sur l'error budget"

Quarante-sept lignes. Pour un service. Et si demain tu changes le SLO de 99% à 99.5%, tu dois mettre à jour 0.01 en 0.005 à cinq endroits sans en rater un.

Ce que j’ai construit

nines.arewel.com est un wizard en trois étapes. Aucune IA là-dedans — des templates Twig, déterministes. Le même formulaire donnera toujours le même fichier.

Étape 1 — Service & SLI : nom du service (préfixe de toutes tes métriques), type de SLI parmi dix disponibles (disponibilité, latence, sonde Blackbox, taux d’erreur, fraîcheur de données, couverture, durabilité…), et la métrique Prometheus source. Un aperçu PromQL se met à jour en temps réel pendant que tu tapes. Cinq templates quick-start couvrent les cas les plus courants — REST API, gRPC, Blackbox, Kafka, pipeline.

Étape 2 — Objectif & fenêtre : ton SLO en pourcentage (de 50% à 99.999%), la durée (28 à 30 jours recommandés), le régime horaire. Pour un homelab, 24/7. Pour une appli de bureau, « Standard » (lundi-vendredi 8h-18h) supprime les nuits du calcul d’error budget. Les quatre paires de burn rates sont pré-remplies avec les valeurs Google SRE, modifiables si tu veux expérimenter.

Étape 3 — Révision & téléchargement : récap complet avant validation — SLI, objectif, fenêtre, error budget en minutes, politiques de burn rate. Puis un ZIP.

Le ZIP contient : prometheus/recording-rules.yaml et prometheus/alerting-rules.yaml (validés par promtool avant livraison), alertmanager/routes.yaml avec ses templates de notification, deux dashboards Grafana directement importables, et des runbooks Markdown pour chaque niveau d’alerte. Tout le bundle, pas juste le YAML.

Demo : SLO de disponibilité pour l’UI Proxmox de heighliner

La sonde Blackbox sur l’interface web de Proxmox (port 8006) est un bon exemple de départ. Simple, binaire, directement observable.

Étape 1 : service heighliner-proxmox-ui, template « Blackbox Probe », métrique probe_success, labels job="blackbox" et instance="https://heighliner.arewel.com:8006".

Étape 2 : objectif 99%, fenêtre 30 jours, régime 24/7. Pourquoi 99% et pas 99.9% ? Parce que Proxmox redémarre. Chaque pve-manager update, chaque kernel upgrade nécessite un reboot. Sur 30 jours, j’ai en général 2 à 3 redémarrages de 3 à 5 minutes. Ça fait 6 à 15 minutes d’indisponibilité. Mon error budget à 99% est de 432 minutes. À 99.9%, il serait de 43 minutes. Le SLO doit refléter ce que l’infrastructure peut tenir réalistement — pas un idéal copié d’une config cloud-native.

Étape 3 : valider, télécharger le ZIP.

# Sur hubble — déployer le bundle SLO
unzip heighliner-proxmox-ui-slo.zip -d /tmp/slo-proxmox-ui/

# Vérifier avant de toucher à la config Prometheus
promtool check rules /tmp/slo-proxmox-ui/prometheus/recording-rules.yaml
promtool check rules /tmp/slo-proxmox-ui/prometheus/alerting-rules.yaml
# SUCCESS: 5 rules found
# SUCCESS: 2 rules found

# Copier dans le répertoire de règles
sudo cp /tmp/slo-proxmox-ui/prometheus/*.yaml /etc/prometheus/rules/

# Recharger sans redémarrage
curl -s -X POST http://localhost:9090/-/reload

Le ZIP inclut une règle `business_hours:active` qui vaut toujours 1 en mode 24/7. Elle sert à filtrer les vues de burn rate dans Grafana selon les horaires — utile si tu veux une vue « pendant les heures ouvrées » sans changer ton SLO global.

Pour les dashboards, c’est deux imports dans l’interface Grafana : Dashboards → Import → Upload JSON file, une fois pour le dashboard SLO overview, une fois pour le panneau burn rate temps réel. Deux minutes.

Ce que ça donne en pratique

Depuis quelques semaines sur hubble, j’ai quatre SLOs actifs : l’UI Proxmox, Grafana lui-même, l’interface Synology DS414, et Vaultwarden. L’error budget de l’UI Proxmox a été consommé une fois — quelques minutes lors d’un pve-manager update. L’alerte SLOBurnFast a déclenché sur l’Alertmanager, transmis via webhook Telegram. Résolu avant que la deuxième fenêtre de confirmation ne ferme.

Ce que j’ai gagné concrètement : je sais exactement quelle fraction de mon error budget a été consommée sur 30 jours, service par service. Pas « ça a l’air stable », pas « il y a eu un truc mardi ». Un chiffre, une tendance, une décision à prendre ou pas.

L’opinion tranchée : je pensais que les SLOs étaient réservés à la prod, pas à un homelab. C’est faux. C’est justement dans un homelab qu’on peut les mettre en place sans enjeu financier immédiat, qu’on apprend le mieux ce que signifie un error budget, et que les erreurs de calcul ne coûtent qu’une soirée de debug. Attendre d’être en prod pour s’y mettre, c’est apprendre à conduire sur l’autoroute.

Ce qui manque pour l’instant

Le support des histogrammes natifs de Prometheus 2.40+ n’est pas encore là. Le type « Latency » fonctionne avec les histogrammes classiques _bucket et histogram_quantile, mais pas avec les native histograms. C’est sur la roadmap.

L’export direct vers l’API Grafana non plus. Pour l’instant, tu importes les dashboards à la main via l’interface — deux minutes, mais deux minutes de moins d’automatisation que j’aimerais. Pareil pour Terraform : il n’y a pas encore de provider ou de module pour pousser les règles directement.

La gestion multi-service est absente de l’interface. Chaque SLO est un formulaire séparé, un ZIP séparé. Pas de vue d’ensemble « tous mes SLOs en une passe ». C’est le prochain chantier.


Le wizard est utilisable librement sur nines.arewel.com pour prévisualiser le PromQL généré sans créer de compte. Le téléchargement du ZIP nécessite un compte. Si tu as déjà passé une soirée à déboguer un coefficient de burn rate mal copié-collé, tu vois l’intérêt.

Article connexe de la série Homelab : Monitorer son homelab : Grafana + Prometheus + node_exporter →

Une remarque, un retour ?

Cet article est vivant — corrections, contre-arguments et retours de production sont les bienvenus. Trois canaux, choisissez celui qui vous convient.

Laisser un commentaire