
Horizontal Pod Autoscaler (HPA) : Scaler les Pods en fonction des métriques (CPU, mémoire, custom)
Apprenez à configurer l'Horizontal Pod Autoscaler (HPA) pour scaler automatiquement vos applications Kubernetes selon l'utilisation CPU, mémoire ou métriques custom.
Le scaling horizontal : ajuster le nombre de Pods à la demande
L'Horizontal Pod Autoscaler (HPA) est le mécanisme d'auto-scaling le plus fondamental et le plus largement utilisé dans Kubernetes. Son objectif est simple mais puissant : ajuster automatiquement le nombre de réplicas (Pods) pour une charge de travail donnée (typiquement un Deployment, ReplicaSet ou StatefulSet) afin de correspondre à la charge actuelle, mesurée via diverses métriques.
Plutôt que de fixer un nombre statique de réplicas, ce qui conduit inévitablement à un sur-provisionnement (gaspillage de ressources pendant les périodes creuses) ou un sous-provisionnement (dégradation des performances pendant les pics de charge), le HPA permet à vos applications de devenir élastiques. Il augmente le nombre de Pods lorsque la charge augmente et le diminue lorsque la charge baisse, assurant ainsi une utilisation optimale des ressources et une meilleure réactivité.
Le HPA prend ses décisions en surveillant des métriques spécifiques et en les comparant à une cible que vous définissez. Si la métrique actuelle dépasse la cible, le HPA augmente le nombre de réplicas ; si elle est inférieure, il le diminue, tout en respectant les limites minimales et maximales que vous avez configurées.
Fonctionnement interne de l'HPA
Le HPA est implémenté comme une boucle de contrôle gérée par un contrôleur dédié (`kube-controller-manager`). Ce contrôleur interroge périodiquement (par défaut toutes les 15 secondes) les sources de métriques pour obtenir la valeur actuelle de la métrique surveillée pour les Pods ciblés par le HPA.
Il compare ensuite cette valeur actuelle à la valeur cible définie dans la configuration du HPA. En se basant sur ce ratio, il calcule le nombre de réplicas désiré en utilisant une formule approximative : desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]. Par exemple, si vous ciblez 50% d'utilisation CPU, que vous avez 3 réplicas et que l'utilisation moyenne actuelle est de 75%, le HPA calculera ceil[3 * (75 / 50)] = ceil[3 * 1.5] = ceil[4.5] = 5 réplicas désirés.
Une fois le nombre désiré calculé, le HPA met à jour le champ `spec.replicas` de l'objet cible (ex: Deployment) via la sous-ressource `scale`. Le contrôleur du Deployment prend alors le relais pour créer ou supprimer les Pods nécessaires afin d'atteindre le nombre de réplicas demandé par le HPA. Ce processus se répète continuellement pour adapter la capacité à la charge.
Pour fonctionner, le HPA a besoin d'accéder aux métriques. Pour les métriques de base comme le CPU et la mémoire, il s'appuie sur l'API Metrics Server (un composant à déployer séparément dans le cluster). Pour des métriques plus avancées, il utilise les API Custom Metrics ou External Metrics, qui nécessitent des adaptateurs spécifiques (comme le Prometheus Adapter).
Types de métriques supportées par le HPA
Le HPA peut baser ses décisions de scaling sur plusieurs types de métriques :
- Ressources CPU et Mémoire : C'est le cas le plus courant. Vous pouvez cibler une utilisation moyenne du CPU ou de la mémoire sur l'ensemble des Pods gérés par le HPA. La cible est généralement exprimée en pourcentage de la requête (request) définie pour le conteneur. Par exemple, cibler
80%d'utilisation CPU signifie que le HPA essaiera de maintenir l'utilisation moyenne du CPU à 80% de la valeur spécifiée dansrequests.cpupour les conteneurs. Il est donc impératif d'avoir défini des requêtes CPU/mémoire sur vos conteneurs pour utiliser ce type de scaling. Le scaling basé sur la mémoire est possible mais souvent moins recommandé comme déclencheur principal car la mémoire est incompressible et un scale-down peut être plus risqué si les Pods restants manquent de mémoire. - Custom Metrics (Métriques Personnalisées) : Ces métriques proviennent généralement de vos applications ou de systèmes internes au cluster. Elles peuvent être de deux types :
- Pod Metrics : Métriques directement associées aux Pods (ex: `requests_per_second`, `queue_length`). Le HPA cible une valeur moyenne par Pod.
- Object Metrics : Métriques associées à un autre objet Kubernetes dans le même namespace (ex: longueur d'une file d'attente représentée par un objet custom, latence d'un Service Ingress). Le HPA cible une valeur absolue pour l'objet.
- External Metrics (Métriques Externes) : Ces métriques proviennent de systèmes extérieurs à Kubernetes (ex: longueur d'une file SQS sur AWS, nombre d'utilisateurs actifs dans une base de données externe, latence mesurée par un outil APM externe). Le HPA cible une valeur absolue ou une moyenne par Pod. Nécessite une API External Metrics (souvent fournie par des adaptateurs spécifiques au service externe).
Il est possible de définir plusieurs métriques dans un seul HPA. Dans ce cas, le HPA calcule le nombre de réplicas désiré pour chaque métrique indépendamment, puis sélectionne le nombre le plus élevé parmi tous les calculs. Cela permet de scaler si l'une ou l'autre des conditions est remplie (par exemple, scaler si le CPU dépasse 80% OU si le nombre de requêtes par seconde dépasse 100).
Configuration d'un HPA : exemple pratique
Le HPA est configuré via un objet Kubernetes `HorizontalPodAutoscaler`. Voici un exemple typique qui scale un Deployment nommé `php-apache` en fonction de l'utilisation moyenne du CPU, en maintenant entre 1 et 10 réplicas :
apiVersion: autoscaling/v2 # Utilisez v2 pour plus d'options, v1 pour CPU seulement
kind: HorizontalPodAutoscaler
metadata:
name: php-apache-hpa
namespace: default
spec:
# Référence à l'objet à scaler (Deployment, ReplicaSet, StatefulSet)
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
# Nombre minimum et maximum de réplicas
minReplicas: 1
maxReplicas: 10
# Liste des métriques à surveiller
metrics:
- type: Resource # Métrique de ressource standard (CPU ou Memory)
resource:
name: cpu
# Cible une utilisation moyenne
target:
type: Utilization # Peut aussi être AverageValue pour CPU/Memory
averageUtilization: 50 # Cible 50% de l'utilisation CPU demandée (requests.cpu)
# - type: Resource # Exemple pour la mémoire (moins courant)
# resource:
# name: memory
# target:
# type: Utilization
# averageUtilization: 70
# - type: Pods # Exemple de Custom Metric (Pods)
# pods:
# metric:
# name: requests_per_second # Nom de la métrique exposée par les Pods
# target:
# type: AverageValue
# averageValue: 100 # Cible 100 requêtes/sec en moyenne par Pod
# - type: External # Exemple d'External Metric
# external:
# metric:
# name: sqs_queue_length
# selector: # Pour identifier la ressource externe
# matchLabels:
# queue: "my-app-queue"
# region: "eu-west-1"
# target:
# type: AverageValue
# averageValue: 30 # Cible 30 messages par Pod actif (scaling basé sur la backlog)
Points clés de la configuration :
scaleTargetRef: Lien vers l'objet dont le nombre de réplicas doit être géré.minReplicas/maxReplicas: Bornes inférieure et supérieure du nombre de Pods.metrics: Liste des métriques surveillées. Chaque élément définit letype(Resource, Pods, Object, External), la source de la métrique (resource.name,pods.metric.name, etc.) et latarget(type: Utilization | AverageValue | Valueet la valeur cible).
Considérations importantes et bonnes pratiques
Pour utiliser efficacement le HPA :
- Définir les Requests : Comme mentionné, pour le scaling basé sur l'utilisation (%), les `requests` de CPU et/ou mémoire doivent être définies sur les conteneurs cibles. Sans elles, le HPA ne peut pas calculer le pourcentage d'utilisation.
- Stabilisation (Cooldown) : Le HPA intègre des délais de stabilisation pour éviter le 'thrashing' (scaler rapidement vers le haut puis vers le bas). Par défaut (configurable via les flags du controller-manager ou dans `spec.behavior` sur HPA v2), il attend 3 minutes après un scale-up avant d'envisager un autre scale-up, et 5 minutes après un scale-down avant d'envisager un autre scale-down. Pendant cette période, il enregistre les recommandations mais n'agit pas immédiatement.
- Latence des métriques : Il y a toujours un délai entre l'augmentation de la charge, la collecte des métriques, le calcul par le HPA et le démarrage effectif des nouveaux Pods (qui peut inclure le téléchargement d'images). Le HPA réagit à la charge passée, il n'est pas prédictif. Prévoyez une marge dans vos cibles.
- Choisir les bonnes métriques : Sélectionnez des métriques qui sont de bons indicateurs de la charge ou de la performance de votre application. Le CPU est souvent un bon point de départ. Les métriques custom comme le nombre de requêtes par seconde ou la taille d'une file d'attente peuvent être plus représentatives pour certaines applications.
- Interaction avec VPA et Cluster Autoscaler : Le HPA fonctionne bien avec le Cluster Autoscaler (CA). Si le HPA décide de scaler vers le haut et qu'il n'y a pas assez de ressources sur les noeuds existants, les nouveaux Pods resteront 'Pending', ce qui signalera au CA qu'il doit ajouter des noeuds. L'interaction avec le Vertical Pod Autoscaler (VPA) est plus complexe ; il est généralement déconseillé d'utiliser HPA et VPA simultanément sur les mêmes métriques (CPU/mémoire) sans une configuration avancée (VPA en mode 'Recommendation' uniquement), car ils pourraient interférer.
En conclusion, l'Horizontal Pod Autoscaler est un outil puissant et flexible pour automatiser la mise à l'échelle horizontale de vos applications dans Kubernetes, vous permettant d'atteindre une meilleure élasticité, une meilleure disponibilité et une optimisation des coûts.