infra / kubernetes
Scaling automatique avec HPA
Explication
Ce que vous allez apprendre
- Comprendre la différence entre le scaling manuel (
kubectl scale) et le scaling automatique - Configurer un HPA qui observe le pourcentage de CPU utilisé par rapport aux
requests - Comprendre pourquoi
requests.cpuest un prérequis absolu au fonctionnement du HPA - Reconnaître et calmer un comportement d'oscillation grâce au champ
behavior - Identifier le rôle de
metrics-server, dépendance indispensable au HPA et àkubectl top
Dans quel contexte ?
Un site e-commerce reçoit un pic de trafic chaque soir à 20h, quand les visiteurs rentrent du travail. L'équipe a fixé 3 replicas en permanence pour tenir ce pic, alors que la charge réelle en journée ne justifierait qu'un seul Pod : le cluster gaspille des ressources 20 heures sur 24. À l'inverse, un jour de soldes exceptionnel, le trafic double sans prévenir et les 3 replicas fixes ne suffisent plus, provoquant des temps de réponse dégradés. Le Horizontal Pod Autoscaler résout précisément ce double problème : il ajuste automatiquement le nombre de replicas à la hausse comme à la baisse, sans intervention humaine.
Du scaling manuel à l'automatique
D'abord, rappelle-toi : jusqu'ici, ajuster le nombre de Pods d'un Deployment se faisait à la main, avec kubectl scale.
La limite de cette approche manuelle
C'est acceptable pour un ajustement ponctuel, mais totalement impraticable si le trafic de ton application varie fortement au fil de la journée : personne ne va surveiller un tableau de bord 24h/24.
La solution : automatiser cette décision
Le Horizontal Pod Autoscaler (HPA) fait exactement ça : il observe une métrique en continu et ajuste le nombre de replicas tout seul, à la hausse comme à la baisse.
Le point le plus important à comprendre
Le HPA ne raisonne pas en "CPU utilisée en millicores", mais en pourcentage par rapport aux requests déclarées sur le conteneur.
| Concept | Rôle |
|---|---|
requests.cpu | Base de calcul du pourcentage observé par le HPA |
targetCPUUtilizationPercentage | Seuil déclenchant l'ajout ou le retrait de replicas |
metrics-server | Composant qui collecte les métriques CPU/mémoire du cluster |
behavior | Règles qui limitent la vitesse de scale-up et scale-down |
Prérequis
Le HPA suppose acquise la leçon sur les Pods et leurs requests/limits : sans requests.cpu définie, il n'a tout simplement aucune base de calcul et refuse de fonctionner correctement.
Un prérequis absolu, pas une option
Si tu n'as pas défini de requests.cpu sur ton Deployment, le HPA n'a tout simplement rien sur quoi baser son calcul, et il ne peut pas fonctionner. C'est le même réflexe déjà vu en leçon sur les Pods : toujours définir requests/limits.
Un risque à éviter : l'oscillation
Une fois le HPA actif, un système qui scale trop vite dans les deux sens devient instable : il ajoute des Pods, puis les retire aussitôt, en boucle, ce qui gaspille des ressources.
Piège fréquent
Sans metrics-server installé dans le cluster, ni kubectl top ni le HPA ne fonctionnent, même avec un YAML parfaitement écrit — le HPA reste bloqué avec une métrique affichée <unknown>, sans message d'erreur évident à première vue.
Comment calmer ce comportement
Le champ behavior permet de calmer cette oscillation, notamment en imposant une fenêtre de stabilisation avant de réduire le nombre de replicas, pour laisser le temps aux métriques de se stabiliser réellement.
Une brique technique à ne pas oublier
Enfin, le HPA dépend d'un composant supplémentaire installé dans le cluster, metrics-server, qui collecte et expose les métriques CPU/mémoire. Sans lui, ni le HPA ni kubectl top ne fonctionnent, quelle que soit la justesse de ta configuration YAML.
La prochaine leçon reste dans la fiabilité, mais change d'angle : comment Kubernetes sait-il qu'une application va vraiment mal, avec les health probes.
Commandes & code
Horizontal Pod Autoscaler (HPA)
Le HPA ajuste automatiquement le nombre de replicas d'un Deployment selon des métriques observées (CPU, mémoire, custom).
# Prérequis : le Deployment doit définir "resources.requests" (le HPA calcule un %)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
spec:
replicas: 2
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: myorg/api:1.4.2
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # scale up si CPU moyen > 70% des requests
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # évite le "flapping" (scale down trop réactif)
policies:
- type: Percent
value: 25
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Pods
value: 4
periodSeconds: 60# metrics-server est requis pour que le HPA fonctionne (fournit les métriques CPU/mémoire)
kubectl apply -f hpa.yaml
kubectl get hpa
kubectl describe hpa api-hpa
kubectl top pods # nécessite aussi metrics-server
# Générer de la charge pour observer le scaling en direct (test uniquement)
kubectl run load-gen --image=busybox -it --rm -- \
/bin/sh -c "while true; do wget -q -O- http://api-service; done"Résumé
- Le HPA exige des
resources.requestsdéfinies : sans eux, aucun pourcentage n'est calculable. behavior.scaleDown.stabilizationWindowSecondsévite les oscillations de scaling.metrics-serverdoit être installé dans le cluster pour alimenter le HPA en données.- Le HPA agit sur le NOMBRE de Pods ; le VPA (Vertical Pod Autoscaler) ajuste requests/limits.
Exercices pratiques
Mission : absorber le pic de 20h sans gaspiller la nuit
Objectif : Configurer un HPA fonctionnel pour un Deployment, et diagnostiquer pourquoi il reste bloqué sur une métrique inconnue.
Contexte
Le site e-commerce fixe actuellement 3 replicas en permanence pour tenir le pic de 20h, gaspillant des ressources le reste de la journée. Tu configures un HPA pour automatiser ce scaling. Après l'avoir appliqué, kubectl get hpa affiche une colonne TARGETS bloquée sur <unknown>/70%, sans jamais évoluer.