TP28 : FinOps (OpenCost, rightsizing) et métriques DORA
Une plateforme se pilote avec des chiffres. Ce TP en introduit deux familles :
- FinOps : dans Kubernetes, on paie ce que l’on réserve (
requests), pas ce que l’on consomme. Mesurer l’écart, l’attribuer à des équipes avec OpenCost, puis redimensionner (rightsizing) à partir de données réelles ; - DORA : quatre indicateurs, issus des travaux Accelerate, mesurent la performance de livraison d’une équipe : fréquence de déploiement, délai de mise en production, taux d’échec des changements, temps de restauration.
Fichiers de départ :
dora.zip,manifests.zip,promql.zip,values.zip
1. Objectifs pédagogiques
À l’issue du TP, vous serez capable de :
- expliquer le modèle de coût d’un cluster Kubernetes (requests, nœuds, capacité inutilisée) ;
- comparer demandé et consommé par workload avec PromQL ;
- installer OpenCost et répartir les coûts par namespace, Deployment et label ;
- obtenir des recommandations avec le VPA en mode
Off, redimensionner et chiffrer le gain ; - définir et calculer les quatre métriques DORA, et en connaître les limites.
Les images de cette page sont des schémas explicatifs, pas des captures d’écran.
2. Environnement du TP
-
Le cluster K3s avec la pile kube-prometheus-stack du TP21 (release
kps) et Helm (TP15). -
Le dépôt GitOps du TP19 (pour DORA) et Python 3 sur la VM.
-
Déployer les workloads surdimensionnés :
kubectl apply -f manifests/oversized.yaml
3. Partie 1 : Demandé contre consommé
- Exécuter les requêtes de
promql/requests-vs-usage.mdet compléter les deux requêtesTODO(efficacité, gaspillage). - Remplir le tableau pour au moins quatre workloads (dont
web,workeret ceux des TP précédents) :
| Workload | CPU demandé | CPU consommé | RAM demandée | RAM consommée | Efficacité CPU |
|---|---|---|---|---|---|
kubectl describe node: comparer Allocated resources (somme des requests) et la consommation réelle (kubectl top node). Pourquoi un nœud peut-il refuser un Pod alors que son CPU est presque inactif ?
4. Partie 2 : OpenCost
-
Installer OpenCost branché sur le Prometheus du TP21, avec les prix de référence de
values/opencost.yaml:helm repo add opencost https://opencost.github.io/opencost-helm-chart && helm repo update helm install opencost opencost/opencost -n opencost --create-namespace -f values/opencost.yaml kubectl -n opencost port-forward svc/opencost 9090:9090 9003:9003 & -
Consulter l’interface (
http://localhost:9090) et l’API d’allocation :curl -s "http://localhost:9003/allocation/compute?window=1d&aggregate=namespace" | jq '.data[0] | map_values(.totalCost)' curl -s "http://localhost:9003/allocation/compute?window=1d&aggregate=controller" | jq '.data[0] | to_entries | sort_by(-.value.totalCost) | .[0:5] | map({(.key): .value.totalCost}) | add' -
Ajouter un label
teamà vos Deployments et agréger les coûts par équipe (aggregate=label:team) : c’est le principe du showback (ou chargeback si l’on refacture). -
Quelle part du coût correspond à la capacité inutilisée (idle) du cluster ?
5. Partie 3 : Recommandations et rightsizing
-
Installer le VPA (composant recommender uniquement) puis créer les objets de
manifests/vpa.yaml:helm repo add fairwinds-stable https://charts.fairwinds.com/stable && helm repo update helm install vpa fairwinds-stable/vpa -n vpa --create-namespace --set updater.enabled=false --set admissionController.enabled=false kubectl apply -f manifests/vpa.yaml kubectl -n tp28 describe vpa web # Target, Lower Bound, Upper Bound (après quelques minutes) -
Choisir de nouvelles valeurs de
requests/limitspourwebetworkeren vous appuyant sur le VPA et sur les percentiles observés dans Prometheus (quantile_over_time(0.95, …[1h])). Justifier la marge conservée. -
Appliquer les nouvelles valeurs, attendre, puis comparer le coût avant / après dans OpenCost :
| Workload | Coût mensuel estimé avant | Après | Économie |
|---|---|---|---|
- Quels risques un rightsizing trop agressif fait-il courir (OOMKilled, throttling CPU, HPA) ? Pourquoi beaucoup d’équipes ne fixent-elles pas de
limits.cpu?
6. Partie 4 : Les métriques DORA
| Métrique | Définition | Source possible |
|---|---|---|
| Deployment Frequency | Nombre de déploiements en production par période | commits sur envs/prod, Argo CD |
| Lead Time for Changes | Délai entre un commit et son arrivée en production | Git (app) + Git (GitOps) |
| Change Failure Rate | Part des déploiements qui provoquent un incident ou un rollback | reverts, incidents |
| Time to Restore | Délai pour rétablir le service après un échec | alertes, incidents, reverts |
-
Lire le script
dora/dora.pyet ses conventions. Les appliquer à votre dépôt GitOps du TP19 :python3 dora/dora.py ~/tp19-gitops 30 -
Compléter le calcul du Lead Time for Changes (rapprochement entre le tag d’image promu et le commit applicatif correspondant).
-
Générer de l’activité réaliste : trois promotions, dont une ratée puis annulée par
git revert, et relancer le calcul. -
Présenter les quatre valeurs dans un dashboard Grafana : par exemple en exposant les résultats du script comme métriques (fichier au format texte Prometheus lu par le textfile collector de node-exporter) ou en les poussant dans une table affichée par Grafana.
-
Discuter les limites : que se passe-t-il si une équipe est jugée sur ces chiffres (loi de Goodhart) ? Pourquoi faut-il regarder débit et stabilité ensemble ?
Défi
- Installer Goldilocks (Fairwinds) pour obtenir un tableau de bord des recommandations VPA de tous les namespaces.
- Calculer le coût par requête de l’API
demo(coût OpenCost du Deployment ÷ nombre de requêtes servies, mesuré par Prometheus) : c’est une unit economics, l’indicateur FinOps le plus parlant pour le métier.
7. Livrables
Captures à déposer dans captures/ :
| Fichier | Contenu attendu |
|---|---|
requests-vs-usage.png |
Dashboard ou requêtes : demandé / consommé par workload |
opencost-ui.png |
Coûts par namespace dans OpenCost |
opencost-team.png |
Coûts agrégés par label team |
vpa-reco.png |
Recommandations du VPA pour web |
rightsizing.png |
Coût avant / après redimensionnement |
dora-dashboard.png |
Les quatre métriques DORA |
Ainsi que : requêtes PromQL complétées, tableaux remplis, dora.py complété et les nouvelles valeurs de requests / limits justifiées.