Le HPA scale par défaut sur le CPU ou la mémoire, une métrique pertinente pour un workload dont la charge se traduit directement en consommation de calcul. Un worker qui traite une file d’attente de messages ne suit pas ce schéma : il peut tourner à 5 % de CPU tout en étant complètement submergé par une file qui grandit sans cesse, le CPU ne mesurant jamais la vraie contrainte du système.

Le décalage entre CPU et charge réelle

Un consommateur de file d’attente passe le plus clair de son temps à attendre (un appel réseau, une écriture disque), pas à calculer : sa consommation CPU reste basse même sous forte charge, parce que la charge se traduit en profondeur de file, pas en cycles CPU consommés. Un HPA basé sur le CPU pour ce type de workload ne scale jamais assez tôt, ou pas du tout, alors que la file continue de s’accumuler sans limite visible pour Kubernetes.

Prometheus Adapter : exposer une métrique métier à l’API HPA

Le HPA ne sait interroger que des métriques exposées via une API Kubernetes spécifique (custom.metrics.k8s.io), jamais directement PromQL. Prometheus Adapter comble ce pont : il traduit une requête PromQL en réponse conforme à cette API, ce qui permet au HPA de scaler sur n’importe quelle métrique déjà collectée par Prometheus, la profondeur d’une file d’attente y compris.

# Prometheus Adapter : traduit une requête PromQL
# en métrique consommable directement par le HPA
rules:
  - seriesQuery: 'queue_depth{namespace!=""}'
    resources:
      overrides:
        namespace: {resource: "namespace"}
    metricsQuery: 'avg(queue_depth{<<.LabelMatchers>>})'

Le HPA référence la métrique custom comme n’importe quelle autre

Une fois exposée via Prometheus Adapter, la métrique se référence dans le HPA exactement comme le CPU ou la mémoire, avec sa propre valeur cible.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: queue-worker
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: queue-worker
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Pods
      pods:
        metric:
          name: queue_depth
        target:
          type: AverageValue
          averageValue: "10"

Cette configuration scale pour maintenir en moyenne 10 messages en file par replica : au-delà, le HPA ajoute des replicas ; en dessous, il en retire, exactement la même logique de calcul que pour le CPU, mais appliquée à une métrique qui reflète réellement la contrainte du système.

Le piège : une métrique custom mal choisie scale sur du bruit

Une métrique trop volatile (qui varie fortement d’une seconde à l’autre sans tendance réelle) déclenche des oscillations de scaling erratiques, le HPA réagissant à du bruit statistique plutôt qu’à une tendance de charge réelle. Une moyenne glissante sur quelques minutes, plutôt qu’une valeur instantanée, stabilise généralement la métrique avant qu’elle ne pilote un scaling qui, sinon, oscille sans jamais se stabiliser.

À retenir

Le HPA sur CPU ou mémoire ne convient pas à tout workload : un consommateur de file d’attente peut rester à faible consommation CPU tout en étant réellement submergé, une contrainte invisible pour ces deux métriques par défaut. Prometheus Adapter comble le pont entre PromQL et l’API custom metrics que le HPA sait consommer, permettant de scaler sur n’importe quelle métrique métier réellement représentative de la charge. Choisir une métrique stable (moyenne glissante plutôt que valeur instantanée) évite un scaling qui réagit au bruit plutôt qu’à la tendance réelle, un des ajustements fins qui distinguent un autoscaling qui fonctionne réellement d’un autoscaling qui coche seulement la case, central pour toute fiabilité et observabilité qui dépasse les workloads purement CPU-bound.