KUBERNETES · FINOPS · SRE
Le Kubernetes scale-to-zero peut supprimer le coût des workers inactifs, mais seulement si le réveil, la file d’attente et le SLA sont conçus ensemble. Voici une méthode pour choisir les bonnes charges et les tester sans mettre la production en danger.
💶
Ciblez les bons workers
Les traitements asynchrones et intermittents sont de meilleurs candidats que les API synchrones.
⏱️
Mesurez le réveil
Le coût évité ne compense pas un délai de démarrage incompatible avec votre engagement client.
🧱
Protégez la reprise
Une métrique durable et une file tampon empêchent la perte de travail pendant le retour à zéro.
📋 Au programme
Le scale-to-zero consiste à autoriser un déploiement à descendre à zéro réplique lorsqu’il ne traite plus de charge. Pour une équipe SaaS, l’intérêt est concret : ne plus réserver des pods de workers pendant les nuits, week-ends ou creux d’activité.
La décision ne se résume pourtant pas à régler minReplicas: 0. Une requête HTTP n’attend pas toujours le temps nécessaire pour créer un pod, télécharger une image et rendre l’application prête. Le bon périmètre est donc un choix de service, pas un simple réglage de coût.
Kubernetes scale-to-zero : ce que vous gagnez, et ce que vous échangez
Avec un autoscaler classique, un service conserve souvent une ou plusieurs répliques minimales. Elles absorbent les premières requêtes et maintiennent les connexions chaudes, mais elles représentent aussi une consommation permanente de CPU, mémoire et parfois de nœuds.
Le scale-to-zero transfère ce coût vers un délai de reprise. Ce délai comprend le déclenchement de l’autoscaling, le placement du pod, le pull éventuel de l’image, le démarrage applicatif et les contrôles de disponibilité. Il doit être comparé à un objectif de service explicite.
Le bon indicateur n’est pas le nombre de pods
Suivez le temps entre l’arrivée du travail et le premier traitement réussi. C’est cette latence de reprise qui détermine si zéro réplique reste acceptable.
Quels workloads peuvent vraiment passer à zéro ?
Les meilleurs candidats sont les consommateurs de file : génération de rapports, conversion de documents, synchronisation, tâches planifiées, analyse d’images ou traitements IA par lot. Le travail persiste dans une file et peut attendre quelques secondes ou minutes.
Une API client ou un endpoint de paiement est plus délicat. Sans proxy, buffering ou capacité minimale, la première requête peut expirer avant que le pod soit prêt. Garder une réplique, ou séparer l’API du worker asynchrone, est généralement plus sûr.
✅
Bon candidat
Worker qui consomme RabbitMQ, SQS ou Kafka, avec message durable et idempotence.
⚖️
À tester
Backend HTTP peu fréquenté, derrière un proxy capable de tamponner ou de déclencher le réveil.
⛔
À éviter au départ
Service synchrone critique, connexion longue durée ou composant qui conserve un état non répliqué.
Une architecture qui absorbe le réveil sans perdre de travail
Flux à garder en tête
La file protège le travail ; l’autoscaler transforme sa profondeur en capacité de calcul.
KEDA est souvent adapté à ce modèle parce qu’il sait déclencher des déploiements à partir de nombreuses sources de métriques, dont les files. Le HPA Kubernetes peut aussi être utilisé lorsque la métrique objet ou externe est disponible et correctement exposée.
Dans les deux cas, la métrique doit survivre à l’absence de pods. Une métrique calculée uniquement par l’application arrêtée ne peut pas déclencher son propre redémarrage. Préférez la profondeur de file, un compteur externe ou un événement durable.
Préparez les images et dépendances
Un gros téléchargement d’image ou une migration exécutée au démarrage peut faire exploser le délai de reprise. Mesurez-le sur un nœud froid, pas seulement sur votre poste.
Mini-lab : tester un worker Redis avec KEDA en 20 minutes
Faites ce test dans un cluster de développement, un namespace isolé et avec une instance Redis dédiée. N’utilisez pas une file de production : l’objectif est de mesurer le comportement de reprise sans impacter les consommateurs existants.
✅ Pré-requis
kubectl configuréDéployez d’abord un worker minimal, puis appliquez un ScaledObject. La commande suivante force un déploiement sans réplique initiale ; adaptez l’image et la connexion Redis à votre environnement de test.
kubectl -n scale-lab create deployment worker --image=busybox:1.36 \
-- /bin/sh -c 'while true; do echo worker-ready; sleep 30; done'
kubectl -n scale-lab scale deployment worker --replicas=0
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: worker-from-queue
namespace: scale-lab
spec:
scaleTargetRef:
name: worker
minReplicaCount: 0
maxReplicaCount: 5
pollingInterval: 15
cooldownPeriod: 120
triggers:
- type: redis
metadata:
address: redis.scale-lab.svc.cluster.local:6379
listName: jobs
listLength: "1"
Ajoutez ensuite un message dans la file de test et observez le déploiement. Le résultat attendu est le passage de zéro à au moins un pod Ready, sans disparition du message avant son traitement effectif.
kubectl -n scale-lab get deploy,pods -w
# Dans un second terminal, injecter un message dans la file de test.
Notez l’heure de l’injection, l’heure de création du pod et l’heure du premier traitement confirmé. Répétez après avoir supprimé le pod et, si possible, sur un nœud où l’image n’est pas en cache. Vous obtenez ainsi un budget de démarrage à froid réaliste.
Pour revenir en arrière, supprimez le ScaledObject puis remettez une réplique minimale. Vérifiez enfin que la file est vide avant de supprimer le namespace de test.
kubectl -n scale-lab delete scaledobject worker-from-queue
kubectl -n scale-lab scale deployment worker --replicas=1
# Après vérification : kubectl delete namespace scale-lab
Passer en production sans dégrader le SLA
Commencez par un seul worker non critique et définissez un seuil de succès : par exemple, 99 % des travaux pris en charge en moins de 30 secondes, y compris après une période inactive. Sans seuil, vous ne saurez pas arbitrer entre économie et expérience client.
Ajoutez des alertes sur l’âge du message le plus ancien, la profondeur de file, les échecs de traitement et la durée de démarrage. Une alerte CPU ne suffit pas lorsque l’application est volontairement à zéro.
Ne confondez pas économie et absence de capacité
Gardez une capacité minimale pour les chemins synchrones et pour les opérations de reprise. Une file qui grandit sans limite devient une indisponibilité différée.
Les erreurs qui font échouer un scale-to-zero
⏱ Une sonde de démarrage trop optimiste
Le pod existe, mais l’application n’est pas prête. Utilisez une startupProbe et ne considérez le réveil terminé qu’après le premier traitement réussi.
📬 Une file non durable
Si le message disparaît avant l’accusé de traitement, un arrêt ou un redémarrage produit des pertes. Exigez des acknowledgements et de l’idempotence.
📉 Un cooldown mal réglé
Un retour à zéro trop rapide crée du yo-yo. Réglez le délai à partir du rythme réel des événements et observez les oscillations.
Piloter le coût et la fiabilité dans le même tableau de bord
Un projet scale-to-zero doit être suivi par le produit, la plateforme et le support. Le gain financier est visible dans les heures de ressources évitées, mais le risque apparaît d’abord dans la latence des tâches et les tickets clients.
Construisez un tableau de bord par workload. Affichez le nombre de réveils, la durée médiane et p95 de démarrage, l’âge des messages, les échecs, la consommation demandée et le coût estimé par période inactive.
Ajoutez un repère métier : délai de livraison d’un export, temps de génération d’un document ou date de traitement d’une synchronisation. Une métrique technique seule ne dit pas si l’attente devient visible pour le client.
Fixez un budget de reprise avant de réduire la capacité. Si un worker doit répondre en moins de dix secondes et que le démarrage p95 atteint vingt secondes, la bonne décision est une réplique minimale, une image plus légère ou un chemin asynchrone.
Évitez aussi de faire descendre simultanément tous les composants. La file, le stockage des résultats, l’observabilité et le mécanisme de déclenchement doivent rester disponibles, sinon aucun signal fiable ne peut relancer les workers.
Un déploiement progressif est plus sûr
Activez le scale-to-zero sur un pourcentage réduit des traitements ou sur un tenant interne. Observez plusieurs cycles de charge faible et de reprise. Augmentez ensuite le périmètre lorsque les délais et les erreurs restent dans le budget fixé.
Gardez un rollback simple dans le manifeste : remonter minReplicaCount à un ou désactiver le ScaledObject. Ce changement doit être connu de l’astreinte et testé avant que le mécanisme ne devienne une dépendance de production.
Décision pragmatique
Commencez par les workers dont la file retient déjà le travail. C’est le chemin le plus court pour faire baisser les coûts sans déplacer le risque sur une requête utilisateur.
FAQ : Kubernetes scale-to-zero
▶ Le scale-to-zero convient-il aux API HTTP ?
▶ Faut-il choisir HPA ou KEDA ?
▶ Comment mesurer un démarrage à froid ?
▶ Quelle est la première alerte à ajouter ?
Le scale-to-zero est un excellent levier FinOps quand il s’applique à des traitements asynchrones, observables et réversibles. La meilleure première mise en œuvre est modeste : un worker, une file durable, un seuil de latence et un rollback documenté.
Réduire les coûts Kubernetes sans sacrifier la disponibilité
Linux-Man vous aide à qualifier vos workloads, mesurer le démarrage à froid et sécuriser le passage en production.

