EN
en direct

Kubernetes 1.37 met les consommateurs de files d’attente à zéro réplica via le HPA

Le 2 septembre 2026, Kubernetes 1.37 active par défaut la mise à l’échelle horizontale jusqu’à zéro réplica (Beta) dès qu’une métrique objet ou externe, comme la longueur d’une file d’attente, le permet. Les consommateurs de files et les traitements par lots peuvent libérer les CPU et GPU réservés pendant l’inactivité, à condition d’accepter la latence de démarrage à froid.

Une rangée d’unités de baie de serveurs grises identiques, un emplacement vide bordé d’un unique voyant ambre.

Kubernetes 1.16. Le passage à zéro réplica du HorizontalPodAutoscaler entre en Alpha. 2 septembre 2026. La fonctionnalité passe en Beta et devient activée par défaut dans Kubernetes 1.37, avec la condition ScaledToZero pour distinguer un arrêt automatique d’une pause manuelle. 2026. Le chantier, porté par SIG Autoscaling, aura mis sept ans à mûrir. Pourquoi c’est important : pour la première fois, mettre un Deployment à zéro réplica quand sa file est vide fait partie du cœur de Kubernetes, sans add-on externe.

Pourquoi le passage à zéro changeait de métrique

Le HPA scale classiquement sur le CPU ou la mémoire. Le piège est mécanique : ces deux métriques proviennent des Pods en cours d’exécution. Une fois le nombre de réplicas tombé à zéro, il n’y a plus de Pod à mesurer, donc plus aucun signal pour redémarrer. La mise à zéro exigeait donc un add-on comme KEDA, un composant externe, ou l’activation d’un feature gate Alpha.

Les métriques objet et externe n’ont pas cette limite. La longueur d’une file d’attente existe indépendamment des workers qui la consomment : le HPA peut continuer à la lire pendant qu’aucun worker ne tourne. C’est ce changement de métrique qui rend la mise à zéro native possible. La contrepartie est le démarrage à froid : le HPA doit observer la métrique, planifier un Pod et lancer l’application avant de traiter la charge.

Un HPA piloté par la file d’attente

L’exemple canonique est un consommateur de file dont on suit le retard via Prometheus. La série queue_consumer_lag est exposée au HPA par un adapter de métriques — l’implémentation de référence est le Prometheus Adapter, qui publie la série via l’API external metrics :

yaml
externalRules:
- seriesQuery: '{__name__="queue_consumer_lag",name!=""}'
  metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (name)
  resources:
    overrides:
      namespace:
        resource: namespace

Avant de créer le HPA, on vérifie que Kubernetes sait lire la métrique — sinon le HPA ne pourra jamais remonter de zéro :

bash
kubectl get --raw \
  '/apis/external.metrics.k8s.io/v1beta1/namespaces/default/queue_consumer_lag?labelSelector=name%3Dworker_tasks'

Le HPA qui suit vise un Deployment queue-worker, autorise de zéro à dix réplicas et demande un réplica pour 30 tâches en attente :

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: queue-worker
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: queue-worker
  minReplicas: 0
  maxReplicas: 10
  metrics:
  - type: External
    external:
      metric:
        name: queue_consumer_lag
        selector:
          matchLabels:
            name: worker_tasks
      target:
        type: Value
        value: "30"

File vide, le HPA réduit le Deployment à zéro réplica ; des tâches arrivent, la métrique externe reste disponible et le HPA recalcule un nombre de réplicas plafonné par maxReplicas. Le downscale stabilization window par défaut de cinq minutes évite qu’une brève baisse de la file ne supprime tous les workers : on peut l’ajuster via spec.behavior.scaleDown.

La condition ScaledToZero, ou comment distinguer pause et arrêt

Mettre un Deployment à zéro crée une ambiguïté : zéro réplica peut signifier que le HPA a réduit la charge, ou qu’un opérateur l’a mise en pause manuellement. Historiquement, fixer un Deployment à zéro à la main gelait l’autoscaling.

Le contrôleur tranche avec une condition de statut ScaledToZero. Quand le HPA fait passer une charge de un ou plusieurs réplicas à zéro, il enregistre ScaledToZero=True : la réconciliation ultérieure sait que le contrôleur possède cet état zéro et continue d’évaluer les métriques. Après la remontée, la condition passe à ScaledToZero=False avec la raison NotScaledToZero. Une charge à zéro sans ScaledToZero=True reste considérée comme mise en pause — le HPA ne la réveillera pas, comme avant.

bash
kubectl describe hpa queue-worker

Si l’adapter ne renvoie pas la métrique, le HPA signale ScalingActive=False avec une raison du type FailedGetExternalMetric. Il faut alors restaurer la métrique ou remonter la charge manuellement pour récupérer la capacité. Ce comportement est le point de vigilance principal : un HPA à zéro dépend entièrement de la disponibilité de sa métrique.

Ce qu’il ne faut pas faire

La fonctionnalité a des limites nettes, et les ignorer coûte cher. Les Services Kubernetes ne mettent pas en mémoire tampon les requêtes pendant qu’aucun Pod n’est prêt : une charge HTTP ou pilotée par requêtes mise à zéro laissera les requêtes échouer au lieu d’attendre. Ces cas exigent une couche de tampon distincte — c’est précisément le créneau de KEDA, qui scale sur la profondeur d’une file ou d’un sujet Kafka et sait exposer une URL de scaled object.

Deux contraintes opérationnelles complètent le tableau. minReplicas: 0 exige au moins une métrique objet ou externe : le serveur d’API rejette un HPA qui ne contient que des métriques de ressources comme le CPU ou la mémoire. Et pendant une montée de version à version skew, il faut attendre que kube-apiserver et kube-controller-manager supportent la fonctionnalité avant de créer des HPA à zéro : un contrôleur au feature gate désactivé traite replicas: 0 comme une pause manuelle et peut laisser une charge bloquée à zéro.

HPA natif ou KEDA : le vrai arbitrage

La question n’est pas « lequel est le meilleur » mais « quelle sémantique votre charge attend ». Le HPA natif à zéro convient au cas simple : un consommateur de file dont le travail peut attendre dans une file durable, et dont chaque Pod réserve des ressources coûteuses — CPU dédiés, GPU. L’économie y est maximale : un pool de workers GPU qui tourne à vide brûle de l’argent en continu.

KEDA reste supérieur dès que la charge est pilotée par événements au sens large : files Kafka, RabbitMQ, fonctions déclenchées, ou toute source qui exige un scaler spécialisé et une gestion fine du tampon. La progression du HPA ne remplace pas KEDA ; elle en réduit la nécessité pour le cas le plus courant.

Le calcul qui rend la mise à zéro rentable

L’économie se mesure en ressources réservées, pas en réplicas. Un pool de workers GPU de dix réplicas qui tourne à vide réserve dix GPU en permanence — une dépense qui continue de courir même quand aucune tâche n’est en file. La mise à zéro ne supprime pas le coût de l’infrastructure sous-jacente, mais elle libère les nœuds pour d’autres charges : dans un cluster où les GPU sont rares, un worker arrêté est un GPU rendu disponible pour un entraînement ou un batch.

Le gain ne vaut que si le travail peut attendre. Une file durableRedis, RabbitMQ, Kafka ou une file cloud managée — est la condition d’entrée : si le travail doit être traité immédiatement, la latence de démarrage à froid devient un défaut produit, pas un compromis d’infrastructure.

Le point de bascule concret se situe sur la latence. Le HPA observe la métrique à intervalle régulier : entre l’arrivée d’une tâche et la remontée d’un réplica, il peut s’écouler plusieurs dizaines de secondes, plus encore avec le démarrage à froid. KEDA, en s’abonnant directement à la source d’événements, réduit ce délai. Pour un batch nocturne ou un consommateur qui tolère trente secondes de retard, la différence est négligeable ; pour une file à faible latence, elle ne l’est pas.

Enfin, gardez à l’esprit le couplage caché : un HPA à zéro dépend entièrement de la disponibilité de sa métrique. Si Prometheus ou l’adapter tombe, le HPA ne peut plus remonter — une panne de supervision devient une panne du pool de workers. C’est le prix à intégrer au calcul d’économie, surtout quand la mise à zéro vise précisément les périodes creuses.

Verdict

Si vous exploitez un consommateur de file d’attente dont les Pods réservent des ressources chères et dont le travail peut patienter dans une file durable, passez en Kubernetes 1.37 et déclarez minReplicas: 0 avec une métrique externe : vous coupez le coût des périodes creuses sans add-on.

Si votre charge est HTTP ou pilotée par requêtes, ne mettez pas à zéro avec le HPA seul : gardez une couche de tampon, ou restez sur KEDA pour absorber les requêtes pendant le démarrage.

Dans tous les cas, testez la remontée de zéro en condition réelle avant de l’activer en production, et surveillez ScalingActive : un HPA qui ne lit plus sa métrique est une charge qui ne redémarrera pas.

Références

Le brief cyber, chaque mardi

Les failles qui comptent, les correctifs à appliquer, en dix minutes de lecture.

Pas de spam. Désinscription en un clic.
à lire ensuite

Sur le même sujet

GitHub Actions ajoute un jeton vulnérabilités et le contexte job des workflows réutilisables

Le 3 septembre 2026, GitHub a livré trois mises à jour de GitHub Actions : une permission vulnérabilités pour GITHUB_TOKEN, le contexte job des workflows réutilisables et une API de dépréciation des runners. Remplacez vos portées larges par la permission vulnérabilités et adoptez job.workflow_ref dans vos workflows réutilisables.

← Retour au fil

Tapez au moins deux caractères.

naviguer ouvrir esc fermer