Un guide pratique pour l'optimisation de l'autoscaler horizontal de pods (HPA) de Kubernetes
Kubernetes a révolutionné la façon dont les applications sont déployées, gérées et mises à l'échelle. Au cœur de ses capacités de mise à l'échelle se trouve l'Horizontal Pod Autoscaler (HPA), un mécanisme puissant qui ajuste automatiquement le nombre de répliques de pods dans un déploiement, un contrôleur de réplication, un replicaset ou un statefulset, en fonction de l'utilisation du CPU observée ou d'autres métriques sélectionnées. Bien que le HPA offre d'immenses avantages pour gérer des charges fluctuantes, son véritable potentiel est libéré par une configuration et une optimisation minutieuses.
Ce guide explore les aspects pratiques de la configuration et de l'optimisation de l'Horizontal Pod Autoscaler de Kubernetes. Nous couvrirons les concepts fondamentaux, les paramètres essentiels, les stratégies d'optimisation avancées et les meilleures pratiques pour garantir que vos applications peuvent s'adapter efficacement à la demande, maintenir leurs performances sous diverses charges et optimiser les coûts d'infrastructure. À la fin de cet article, vous aurez une solide compréhension de la manière de tirer pleinement parti du HPA.
Comprendre l'Horizontal Pod Autoscaler (HPA)
Le HPA ajuste automatiquement le nombre de pods de votre application à la hausse ou à la baisse pour correspondre à la demande actuelle. Il surveille en permanence les métriques spécifiées et les compare aux valeurs cibles. Si la métrique observée dépasse la cible, le HPA déclenche un événement de montée en charge (scale-up) ; si elle tombe en dessous, il déclenche une réduction de charge (scale-down). Cet ajustement dynamique garantit que votre application dispose de suffisamment de ressources pour fonctionner de manière optimale sans sur-provisionnement.
Le HPA peut s'adapter en fonction de :
- Métriques de ressources : Principalement l'utilisation du CPU et l'utilisation de la mémoire (disponibles via l'API
metrics.k8s.io, généralement servie par le Kubernetes Metrics Server). - Métriques personnalisées : Métriques spécifiques à l'application exposées via l'API
custom.metrics.k8s.io(par exemple, requêtes par seconde, profondeur de file d'attente, connexions actives). Celles-ci nécessitent généralement un adaptateur commeprometheus-adapter. - Métriques externes : Métriques provenant de sources extérieures au cluster exposées via l'API
external.metrics.k8s.io(par exemple, taille de la file d'attente Google Cloud Pub/Sub, longueur de la file d'attente AWS SQS). Celles-ci nécessitent également un serveur d'API de métriques personnalisées capable de récupérer des métriques externes.
Prérequis pour une optimisation HPA efficace
Avant de plonger dans les configurations HPA, assurez-vous que ces éléments fondamentaux sont en place :
1. Définir des requêtes et des limites de ressources précises
C'est peut-être le prérequis le plus crucial. Le HPA repose fortement sur des requêtes de CPU et de mémoire correctement définies pour calculer les pourcentages d'utilisation. Si un pod n'a pas de requêtes CPU définies, le HPA ne peut pas calculer son utilisation CPU, rendant la mise à l'échelle basée sur le CPU impossible.
- Requêtes : Définissent les ressources minimales garanties pour vos conteneurs. Le HPA utilise ces valeurs pour déterminer l'utilisation cible par pod.
- Limites : Définissent les ressources maximales qu'un conteneur peut consommer. Les limites empêchent un seul pod de consommer des ressources excessives et d'impacter d'autres pods sur le même nœud.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: my-image:latest
resources:
requests:
cpu: "200m" # 20% d'un cœur CPU
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
2. Installer le Kubernetes Metrics Server
Pour que le HPA utilise les métriques d'utilisation du CPU et de la mémoire, le Kubernetes Metrics Server doit être installé dans votre cluster. Il collecte les métriques de ressources des Kubelets et les expose via l'API metrics.k8s.io.
3. Observabilité de l'application
Pour les métriques personnalisées ou externes, votre application doit exposer des métriques pertinentes (par exemple, via un point de terminaison Prometheus) et vous aurez besoin d'un moyen de collecter et d'exposer ces métriques à l'API Kubernetes, généralement en utilisant un adaptateur Prometheus ou un serveur d'API de métriques personnalisées.
Configuration du HPA : Paramètres essentiels
Examinons la structure de base d'un manifeste HPA :
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Paramètres clés :
scaleTargetRef: Définit la ressource cible (par exemple, un Deployment) que le HPA mettra à l'échelle. Spécifiez sonapiVersion, sonkindet sonname.minReplicas: Le nombre minimum de pods jusqu'où le HPA réduira la charge. Il est recommandé de le définir à au moins 1 ou 2 pour une haute disponibilité, même sous une charge nulle.maxReplicas: Le nombre maximum de pods jusqu'où le HPA augmentera la charge. Cela agit comme une protection contre une mise à l'échelle incontrôlée et limite les coûts.metrics: Un tableau définissant les métriques que le HPA doit surveiller.type: Peut êtreResource,Pods,ObjectouExternal.resource.name: Pour le typeResource, spécifiecpuoumemory.target.type: Pour le typeResource,Utilization(pourcentage de la ressource demandée) ouAverageValue(valeur absolue).averageUtilization: Pour le typeUtilization, le pourcentage cible. Le HPA calcule le nombre de pods souhaité en fonction deutilisation_actuelle / utilisation_cible * nombre_de_pods_actuel.
Optimisation du HPA pour la réactivité et la stabilité
Au-delà de la configuration de base, le HPA offre des options d'optimisation avancées, en particulier avec autoscaling/v2 (ou v2beta2 dans les versions plus anciennes), pour gérer le comportement de mise à l'échelle de manière plus granulaire.
1. Cibles de CPU et de mémoire (averageUtilization / averageValue)
Définir la bonne utilisation cible est crucial. Une cible plus basse signifie une mise à l'échelle plus précoce (plus réactive, potentiellement plus coûteuse), tandis qu'une cible plus élevée signifie une mise à l'échelle plus tardive (moins réactive, potentiellement moins chère mais risquant une dégradation des performances).
- Comment déterminer les cibles optimales : Les tests de charge et le profilage sont vos meilleurs alliés. Augmentez progressivement la charge sur votre application tout en surveillant l'utilisation des ressources et les métriques de performance (latence, taux d'erreur). Identifiez l'utilisation CPU/mémoire à laquelle votre application commence à dégrader ses performances. Définissez votre cible HPA en dessous de ce seuil, généralement entre 60 et 80 % pour le CPU.
- Équilibre : Visez une cible qui laisse une marge suffisante pour les pics inattendus, mais qui n'est pas si basse que vous soyez constamment sur-provisionné.
2. Comportement de mise à l'échelle (behavior field)
Introduit dans HPA autoscaling/v2, le champ behavior offre un contrôle précis sur les événements de montée et de réduction de charge, empêchant le "battement" (cycles rapides de montée et de réduction de charge).
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
stabilizationWindowSeconds: 60 # Attendre 60s avant de relancer une montée en charge
policies:
- type: Pods
value: 4
periodSeconds: 15 # Ajouter max 4 pods toutes les 15 secondes
- type: Percent
value: 100
periodSeconds: 15 # Ou doubler le nombre de pods actuels toutes les 15 secondes (le moins restrictif des deux)
scaleDown:
stabilizationWindowSeconds: 300 # Attendre 5 minutes avant de réduire la charge
policies:
- type: Percent
value: 50
periodSeconds: 60 # Supprimer max 50% des pods toutes les 60 secondes
selectPolicy: Max # Choisir la politique qui permet le "plus grand nombre" (le moins agressif) de pods
Configuration scaleUp :
stabilizationWindowSeconds: Cela empêche les cycles rapides de montée et de réduction de charge (flapping). Le HPA prend en compte les métriques de cette fenêtre lors de la montée en charge, garantissant qu'il ne monte en charge que si la métrique plus élevée persiste. Une valeur typique est de 30 à 60 secondes.policies: Définit comment les pods sont ajoutés lors d'un événement de montée en charge. Vous pouvez définir plusieurs politiques, et le HPA utilisera celle qui permet le plus grand nombre de pods (la montée en charge la plus agressive).type: Pods: Augmente la charge d'un nombre fixe de pods.valuespécifie le nombre de pods à ajouter.periodSecondsdéfinit la fenêtre de temps sur laquelle cette politique s'applique.type: Percent: Augmente la charge d'un pourcentage du nombre actuel de pods.valueest le pourcentage.
Configuration scaleDown :
stabilizationWindowSeconds: Plus critique pourscaleDown, cela spécifie combien de temps le HPA doit observer les métriques en dessous de la cible avant d'envisager une réduction de charge. Une fenêtre plus longue (par exemple, 300-600 secondes) empêche une réduction de charge prématurée pendant les accalmies temporaires, évitant les "démarrages à froid" et les baisses de performance. C'est un réglage crucial pour des environnements stables.policies: Similaire àscaleUp, définit comment les pods sont supprimés. Le HPA utilise la politique qui entraîne le plus petit nombre de pods (la réduction de charge la plus agressive) siselectPolicyestMin, ou la politique qui entraîne le plus grand nombre de pods siselectPolicyestMax.type: Pods: Supprime un nombre fixe de pods.type: Percent: Supprime un pourcentage des pods actuels.
-
selectPolicy: Détermine quelle politique appliquer lorsque plusieurs politiquesscaleDownsont définies.Minest la valeur par défaut et généralement recommandée pour une réduction d'échelle plus conservatrice ;Maxsélectionnerait la politique qui entraîne le plus grand nombre de pods (la réduction d'échelle la moins agressive). -
Attention : Soyez prudent avec les politiques
scaleDownagressives ou lesstabilizationWindowSecondscourts pourscaleDown. Si votre application a des temps d'initialisation longs ou gère des connexions avec état, une réduction rapide peut entraîner des interruptions de service ou une latence accrue pour les utilisateurs.
Métriques et stratégies HPA avancées
Bien que le CPU et la mémoire soient courants, de nombreuses applications s'adaptent mieux aux métriques personnalisées ou externes qui reflètent leur charge de travail réelle.
1. Métriques personnalisées
Utilisez des métriques personnalisées lorsque le CPU/la mémoire n'est pas un indicateur direct de la charge ou du goulot d'étranglement de performance de votre application. Exemples : requêtes HTTP par seconde (QPS), connexions actives, longueur de file d'attente de messages, backlog de tâches batch.
Pour utiliser des métriques personnalisées :
1. Votre application doit exposer ces métriques (par exemple, via un exportateur Prometheus).
2. Déployez un adaptateur de métriques personnalisées (par exemple, prometheus-adapter) capable de récupérer ces métriques et de les exposer via l'API custom.metrics.k8s.io.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa-qps
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 15
metrics:
- type: Pods # Ou Object si la métrique est pour le déploiement dans son ensemble
pods:
metric:
name: http_requests_per_second # Le nom de la métrique exposée par votre application/adaptateur
target:
type: AverageValue
averageValue: "10k" # Cible 10 000 requêtes par seconde par pod
2. Métriques externes
Les métriques externes sont utiles lorsque la charge de travail de votre application est pilotée par un système externe ne fonctionnant pas directement sur Kubernetes. Exemples : profondeur de file d'attente AWS SQS, décalage de sujet Kafka, backlog d'abonnement Pub/Sub.
Pour utiliser des métriques externes :
1. Vous avez besoin d'un serveur d'API de métriques personnalisées capable de récupérer des métriques de votre système externe (par exemple, un adaptateur spécifique pour AWS CloudWatch ou GCP Monitoring).
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-worker-hpa-sqs
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-worker
minReplicas: 1
maxReplicas: 20
metrics:
- type: External
external:
metric:
name: aws_sqs_queue_messages_visible # Nom de la métrique de votre source externe
selector:
matchLabels:
queue: my-queue-name
target:
type: AverageValue
averageValue: "100" # Cible 100 messages visibles dans la file d'attente par pod
3. Métriques multiples
Le HPA peut être configuré pour surveiller plusieurs métriques simultanément. Lorsque plusieurs métriques sont spécifiées, le HPA calcule le nombre de répliques souhaité pour chaque métrique indépendamment, puis sélectionne le plus élevé de ces nombres de répliques souhaités. Cela garantit que l'application s'adapte suffisamment à toutes les dimensions de charge observées.
# ... (boilerplate HPA)
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "10k"
Surveillance et validation
Une optimisation HPA efficace est un processus itératif qui nécessite une surveillance et une validation continues :
- Observer les événements HPA : Utilisez
kubectl describe hpa <nom-hpa>pour voir l'état, les événements et les décisions de mise à l'échelle du HPA. Cela fournit des informations précieuses sur les raisons pour lesquelles le HPA a augmenté ou diminué la charge. - Surveiller les métriques et les répliques : Utilisez votre pile d'observabilité (par exemple, Prometheus, Grafana) pour visualiser l'utilisation des ressources de votre application (CPU, mémoire), les métriques personnalisées/externes et le nombre réel de répliques de pods au fil du temps. Corrélez-les avec les changements de charge entrante.
- Tests de charge : Simulez les charges attendues et maximales pour valider la réactivité du HPA et vous assurer que votre application fonctionne comme prévu sous contrainte. Ajustez les paramètres HPA en fonction de ces tests.
Bonnes pratiques pour l'optimisation HPA
- Commencez par des requêtes/limites de ressources bien définies : Elles constituent la base d'un HPA précis basé sur les ressources. Sans elles, le HPA ne peut pas fonctionner efficacement pour le CPU/la mémoire.
- Définissez des
minReplicasetmaxReplicasréalistes :minReplicasfournit une base pour la disponibilité, tandis quemaxReplicasagit comme un filet de sécurité contre les coûts incontrôlés et l'épuisement des ressources. - Ajustez progressivement l'utilisation cible : Commencez avec une cible CPU légèrement conservatrice (par exemple, 60-70 %) et itérez. Ne visez pas 100 % d'utilisation, car cela ne laisse aucune marge pour la latence ou les pics de traitement.
- Tirez parti de
stabilizationWindowSeconds: Essentiel pour prévenir les oscillations rapides de mise à l'échelle. Utilisez une fenêtre plus longue pourscaleDown(par exemple, 5-10 minutes) que pourscaleUp(par exemple, 1-2 minutes) pour assurer la stabilité. - Privilégiez les métriques spécifiques à l'application : Si le CPU ou la mémoire ne corrèle pas directement avec les goulots d'étranglement de performance de votre application, utilisez des métriques personnalisées ou externes pour une mise à l'échelle plus précise et efficace.
- Surveiller, tester, itérer : L'optimisation HPA n'est pas une configuration unique. Le comportement de l'application, les schémas de trafic et l'infrastructure sous-jacente peuvent changer. Revoyez régulièrement les performances du HPA et ajustez les paramètres si nécessaire.
- Comprenez les caractéristiques de mise à l'échelle de votre application : S'adapte-t-elle linéairement aux requêtes ? A-t-elle de longs temps de démarrage ? Est-elle avec état ? Ces caractéristiques influencent votre stratégie HPA.
Conclusion
L'Horizontal Pod Autoscaler de Kubernetes est un composant essentiel pour construire des applications résilientes, rentables et performantes dans un environnement Kubernetes. En comprenant ses mécanismes fondamentaux, en définissant des requêtes de ressources précises et en ajustant soigneusement ses paramètres de comportement de mise à l'échelle, vous pouvez garantir que vos applications s'adaptent automatiquement aux charges variables avec précision.
Une optimisation HPA efficace est un voyage continu de mesure, d'observation et d'ajustement. Adoptez le processus itératif, exploitez les métriques avancées si nécessaire et surveillez continuellement les performances de votre application pour libérer tout le potentiel de la mise à l'échelle dynamique au sein de Kubernetes.