Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Horizontal Pod Autoscaler (HPA) — Mise à l'échelle automatique

17 min de lecture

logo kubernetes

Le Horizontal Pod Autoscaler (HPA) ajuste automatiquement le nombre de réplicas d’une application pour suivre la charge observée. Il interroge périodiquement les métriques de vos Pods et augmente ou réduit leur nombre en fonction de seuils que vous définissez. C’est le mécanisme principal de mise à l’échelle horizontale dans Kubernetes.

Ce guide couvre la configuration du HPA avec autoscaling/v2, le rôle critique des requests, le contrôle du comportement de scaling, et le debug — tout ce qu’il faut pour la CKAD et la production.

  • Comment le HPA prend ses décisions et la formule de calcul
  • Le rôle critique des requests pour le calcul d’utilisation
  • Configurer un HPA basé sur CPU, mémoire ou plusieurs métriques
  • Contrôler la vitesse de scaling avec behavior
  • Débugger un HPA qui affiche <unknown> ou ne scale pas
  • Ce qu’il faut savoir pour la CKAD

Le HPA observe les métriques de vos Pods et ajuste leur nombre pour maintenir un niveau d’utilisation cible :

SituationAction du HPA
Charge élevée (métriques > seuil)Augmente le nombre de réplicas
Charge faible (métriques < seuil)Réduit le nombre de réplicas (prudemment)
Métriques indisponiblesAttend sans modifier les réplicas
OutilAgit surCas d’usage
HPANombre de PodsApplications stateless, montée en charge
VPATaille des Pods (requests/limits)Applications avec besoins variables
Cluster AutoscalerNombre de nœudsCapacité cluster insuffisante

Avant de créer un HPA, deux éléments sont impératifs :

Le HPA récupère les métriques via le Metrics Server. Vérifiez qu’il est opérationnel :

Fenêtre de terminal
kubectl get deployment -n kube-system metrics-server
kubectl top pods -A

Si kubectl top affiche des valeurs CPU/mémoire, le Metrics Server fonctionne.

Installation si absent :

Fenêtre de terminal
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

C’est le point le plus important pour le HPA.

Pour un HPA basé sur averageUtilization, le calcul d’utilisation est :

Utilisation = (consommation actuelle / request) × 100

Sans requests définies, le HPA ne peut pas calculer le pourcentage d’utilisation et affichera <unknown> dans TARGETS.

# ✅ OBLIGATOIRE pour le HPA basé sur Utilization
resources:
requests:
cpu: "100m"
memory: "128Mi"
Réplicas voulus = Réplicas actuels × (Utilisation actuelle / Objectif)

Exemple : 2 Pods à 80% d’utilisation, objectif 50%

Réplicas voulus = 2 × (80 / 50) = 3.2 → 4 Pods

La formule représente le principe général, mais le HPA applique aussi :

  • Une tolérance de ±10% avant de décider d’un scaling (évite les oscillations)
  • L’exclusion des Pods non Ready ou en cours de suppression
  • Une fenêtre de stabilisation avant de scale down (par défaut 5 minutes)
  • L’attente si des métriques sont manquantes
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.28
resources:
requests:
cpu: "100m" # ← OBLIGATOIRE pour le HPA
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIP
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50

Ce que ça signifie : Le HPA maintiendra l’utilisation CPU moyenne des Pods autour de 50%. Si elle dépasse, il ajoute des Pods. Si elle descend, il en retire (après stabilisation).

Fenêtre de terminal
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-hpa.yaml
kubectl get hpa
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
# nginx-hpa Deployment/nginx-deployment 10%/50% 1 10 1

Le HPA avec autoscaling/v2 supporte quatre types de métriques :

TypeDescriptionExemple
ResourceCPU, mémoire des conteneursaverageUtilization: 50
PodsMétrique agrégée par PodRequêtes/seconde par Pod
ObjectMétrique liée à un objet K8sRequêtes sur un Ingress
ExternalMétrique externe au clusterQueue AWS SQS, Pub/Sub
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: multi-metric-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 20
metrics:
# Métrique 1 : CPU
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
# Métrique 2 : Mémoire
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70

Pour les métriques custom (Pods, Object) ou external, vous avez besoin d’un adaptateur de métriques comme :

  • Prometheus Adapter — expose les métriques Prometheus au HPA
  • KEDA — autoscaler événementiel avec nombreuses sources

Le Metrics Server seul suffit uniquement pour CPU et mémoire.

Le champ behavior permet de contrôler finement la vitesse de scale up et scale down :

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: controlled-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # Attendre 5 min avant scale down
policies:
- type: Percent
value: 10 # Réduire max 10% par période
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0 # Scale up immédiat
policies:
- type: Percent
value: 100 # Doubler si nécessaire
periodSeconds: 15
- type: Pods
value: 4 # Ou ajouter max 4 pods
periodSeconds: 15
selectPolicy: Max # Prendre la politique la plus agressive
ParamètreDescriptionDéfaut
stabilizationWindowSecondsTemps d’attente avant d’appliquer le scaling300s (down), 0s (up)
policies[].typePods (nombre absolu) ou Percent-
policies[].valueValeur du changement-
policies[].periodSecondsPériode d’évaluation-
selectPolicyMax, Min, ou DisabledMax
behavior:
scaleDown:
stabilizationWindowSeconds: 600 # 10 minutes
policies:
- type: Pods
value: 1 # 1 pod max par minute
periodSeconds: 60

Plutôt que d’installer des outils sur votre machine, générez la charge depuis un Pod dans le cluster :

Fenêtre de terminal
# Lancer un Pod de charge avec wget en boucle
kubectl run load-generator --image=busybox:1.36 --rm -it -- /bin/sh -c \
"while true; do wget -q -O- http://nginx-service; done"

Dans un autre terminal, observez le HPA :

Fenêtre de terminal
kubectl get hpa -w
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
# nginx-hpa Deployment/nginx-deployment 12%/50% 1 10 1
# nginx-hpa Deployment/nginx-deployment 78%/50% 1 10 1
# nginx-hpa Deployment/nginx-deployment 78%/50% 1 10 2
# nginx-hpa Deployment/nginx-deployment 45%/50% 1 10 2

Arrêtez la charge avec Ctrl+C et observez :

Fenêtre de terminal
kubectl get hpa -w
# Après plusieurs minutes...
# nginx-hpa Deployment/nginx-deployment 5%/50% 1 10 2
# nginx-hpa Deployment/nginx-deployment 5%/50% 1 10 1
Fenêtre de terminal
# Vue rapide
kubectl get hpa
# Détails complets avec conditions et événements
kubectl describe hpa nginx-hpa
# YAML avec status actuel
kubectl get hpa nginx-hpa -o yaml
# Vérifier les métriques des Pods
kubectl top pods -l app=nginx
# Vérifier le Metrics Server
kubectl top nodes

kubectl describe hpa affiche des conditions qui expliquent l’état du HPA :

Fenêtre de terminal
kubectl describe hpa nginx-hpa
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ReadyForNewScale recommended size matches current size
ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count
ScalingLimited False DesiredWithinRange the desired count is within the acceptable range
ConditionSignification
AbleToScale: TrueLe HPA peut modifier les réplicas
ScalingActive: TrueLes métriques sont disponibles et valides
ScalingLimited: TrueBloqué par minReplicas ou maxReplicas
SymptômeCause probableSolution
TARGETS: <unknown>/50%Pas de requests définiesAjouter resources.requests au Deployment
TARGETS: <unknown>/50%Metrics Server absentInstaller le Metrics Server
TARGETS: <unknown>/50%Pods pas encore ReadyAttendre que les Pods démarrent
ScalingActive: FalseMétrique introuvableVérifier le nom de la métrique
HPA ne scale pas upCharge insuffisanteAugmenter la charge de test
HPA ne scale pas downStabilization windowAttendre 5+ minutes
ScalingLimited: TruemaxReplicas atteintAugmenter maxReplicas
Fenêtre de terminal
# Voir les événements du HPA
kubectl describe hpa nginx-hpa | grep -A 10 "Events:"
# Vérifier que la cible existe
kubectl get deployment nginx-deployment
# Vérifier les métriques brutes
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/default/pods" | jq .

Pour les situations où vous devez aller vite :

Fenêtre de terminal
# Créer un HPA basé sur CPU
kubectl autoscale deployment nginx-deployment \
--cpu-percent=50 \
--min=1 \
--max=10
# Vérifier
kubectl get hpa nginx-deployment
Fenêtre de terminal
kubectl autoscale deployment nginx-deployment \
--cpu-percent=50 --min=1 --max=10 \
--dry-run=client -o yaml > hpa.yaml
  1. Lire un HPA existant

    Fenêtre de terminal
    kubectl get hpa
    kubectl describe hpa <nom>
  2. Créer un HPA CPU rapidement

    Fenêtre de terminal
    kubectl autoscale deployment <nom> --cpu-percent=50 --min=1 --max=10
  3. Comprendre le lien requests → HPA

    Sans requests, le HPA affiche <unknown> et ne fonctionne pas.

  4. Vérifier les métriques

    Fenêtre de terminal
    kubectl top pods
    kubectl top nodes
  5. Diagnostiquer TARGETS <unknown>

    • Metrics Server installé ?
    • requests définies dans le Deployment ?
    • Pods en état Running ?
Fenêtre de terminal
# Créer rapidement
kubectl autoscale deployment myapp --cpu-percent=50 --min=2 --max=10
# Voir l'état
kubectl get hpa
kubectl describe hpa myapp
# Voir les métriques
kubectl top pods
kubectl top pods -l app=myapp
# Modifier à chaud
kubectl patch hpa myapp -p '{"spec":{"maxReplicas":20}}'
# Supprimer
kubectl delete hpa myapp
Warning FailedComputeMetricsReplicas unable to get metrics for resource cpu:
no metrics returned from resource metrics API

Cause : Le Metrics Server ne retourne pas de métriques pour ce Pod.

Solution :

Fenêtre de terminal
# Vérifier le Metrics Server
kubectl get deployment -n kube-system metrics-server
kubectl logs -n kube-system deployment/metrics-server
# Vérifier que les Pods ont des requests
kubectl get deployment nginx-deployment -o yaml | grep -A5 resources

Causes possibles :

  1. La charge est insuffisante (utilisation < 50% × tolérance)
  2. minReplicas: 1 empêche de descendre plus bas
  3. ScalingLimited: True — vérifier maxReplicas

Cause : La charge varie autour du seuil et provoque des scale up/down répétés.

Solution : Augmenter la fenêtre de stabilisation :

behavior:
scaleDown:
stabilizationWindowSeconds: 600
scaleUp:
stabilizationWindowSeconds: 60
  1. Le HPA ajuste le nombre de réplicas, pas la taille des Pods (c’est le VPA)
  2. Les requests sont obligatoires pour averageUtilization — sans elles, <unknown>
  3. Le Metrics Server est requis pour les métriques CPU/mémoire standard
  4. Le scale down est volontairement lent (5 min par défaut) pour éviter les oscillations
  5. behavior permet de contrôler finement la vitesse de scaling
  6. kubectl describe hpa montre les conditions et événements pour débugger
  7. kubectl autoscale crée rapidement un HPA CPU (utile pour la CKAD)
  8. Pour les métriques custom/external, il faut un adaptateur (Prometheus Adapter, KEDA)

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn