Guide pratique pour le réglage de l'autoscaler horizontal de pods Kubernetes (HPA)

Réglez l'HPA Kubernetes avec les demandes de ressources, les métriques, le comportement de mise à l'échelle, les fenêtres de stabilisation et les commandes de validation.

Guide pratique pour le réglage de l'autoscaler horizontal de pods Kubernetes (HPA)

L'autoscaler horizontal de pods Kubernetes (HPA) peut maintenir la réactivité de votre application lors des pics de trafic, mais seulement si les métriques et les limites reflètent le comportement de l'application. Un HPA mal réglé peut passer à l'échelle trop tard, réduire trop rapidement, ou ne jamais passer à l'échelle car les demandes de ressources sont manquantes.

Ce guide vous montre comment régler l'HPA Kubernetes avec le CPU, la mémoire, les métriques personnalisées, les métriques externes et les contrôles de comportement de mise à l'échelle.

Comprendre l'autoscaler horizontal de pods (HPA)

L'HPA ajuste automatiquement le nombre de pods dans votre application à la hausse ou à la baisse pour correspondre à la demande actuelle. Il surveille en continu les métriques spécifiées et les compare aux valeurs cibles. Si la métrique observée dépasse la cible, HPA déclenche un événement de mise à l'échelle à la hausse ; si elle tombe en dessous, il déclenche une mise à l'échelle à la baisse. Cet ajustement dynamique garantit que votre application dispose de suffisamment de ressources pour fonctionner de manière optimale sans sur-provisionnement.

HPA peut passer à l'échelle en fonction de :

  • Métriques de ressources : Principalement l'utilisation du CPU et de la mémoire (disponibles via l'API metrics.k8s.io, généralement servie par le serveur de métriques Kubernetes).
  • 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 comme prometheus-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 file d'attente Google Cloud Pub/Sub, longueur de file d'attente AWS SQS). Celles-ci nécessitent également un serveur API de métriques personnalisées capable de récupérer des métriques externes.

Prérequis pour un réglage efficace de l'HPA

Avant de plonger dans les configurations HPA, assurez-vous que ces éléments fondamentaux sont en place :

1. Définir des demandes et limites de ressources précises

C'est peut-être le prérequis le plus crucial. L'HPA dépend fortement des demandes de CPU et de mémoire correctement définies pour calculer les pourcentages d'utilisation. Si un pod n'a pas de demandes de CPU définies, HPA ne peut pas calculer son utilisation du CPU, rendant la mise à l'échelle basée sur le CPU impossible.

  • Demandes : Définissez les ressources minimales garanties pour vos conteneurs. HPA utilise ces valeurs pour déterminer l'utilisation cible par pod.
  • Limites : Définissez les ressources maximales qu'un conteneur peut consommer. Les limites empêchent un seul pod de consommer des ressources excessives et d'impacter les 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 serveur de métriques Kubernetes

Pour que HPA utilise les métriques d'utilisation du CPU et de la mémoire, le serveur de métriques Kubernetes 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 les 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 API de métriques personnalisées.

Configuration de l'HPA : Paramètres de base

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, Deployment) que HPA va mettre à l'échelle. Spécifiez son apiVersion, kind et name.
  • minReplicas : Le nombre minimum de pods que HPA réduira. Il est recommandé de le définir à au moins 1 ou 2 pour la haute disponibilité, même sous charge nulle.
  • maxReplicas : Le nombre maximum de pods que HPA augmentera. Cela sert de protection contre une mise à l'échelle incontrôlée et limite les coûts.
  • metrics : Un tableau définissant les métriques que HPA doit surveiller.
    • type : Peut être Resource, Pods, Object ou External.
    • resource.name : Pour le type Resource, spécifie cpu ou memory.
    • target.type : Pour le type Resource, Utilization (pourcentage de la ressource demandée) ou AverageValue (valeur absolue).
    • averageUtilization : Pour le type Utilization, le pourcentage cible. HPA calcule le nombre de pods souhaité en fonction de utilisation_actuelle / utilisation_cible * nombre_de_pods_actuel.

Réglage de l'HPA pour la réactivité et la stabilité

Au-delà de la configuration de base, HPA offre des options de réglage 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 CPU et 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 du CPU/mémoire à laquelle votre application commence à dégrader ses performances. Définissez votre cible HPA en dessous de ce seuil, généralement dans la plage de 60 à 80 % pour le CPU.
  • Équilibre : Visez une cible qui laisse suffisamment de marge pour les pics inattendus mais qui n'est pas si basse que vous êtes constamment en sur-provisionnement.

2. Comportement de mise à l'échelle (champ behavior)

Introduit dans HPA autoscaling/v2, le champ behavior offre un contrôle fin sur les événements de mise à l'échelle à la hausse et à la baisse, empêchant le « thrashing » (cycles rapides de mise à l'échelle à la hausse et à la baisse).

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 remonter à l'échelle
      policies:
      - type: Pods
        value: 4
        periodSeconds: 15 # Ajouter max 4 pods toutes les 15 secondes
      - type: Percent
        value: 100
        periodSeconds: 15 # Ou doubler les pods actuels toutes les 15 secondes (selon la moins restrictive)
    scaleDown:
      stabilizationWindowSeconds: 300 # Attendre 5 minutes avant de réduire
      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 changement de réduction autorisé

Configuration scaleUp :

  • stabilizationWindowSeconds : Cela lisse les recommandations de mise à l'échelle sur une fenêtre de temps récente. La mise à l'échelle à la hausse utilise généralement une fenêtre courte pour que l'application puisse réagir rapidement.
  • policies : Définit comment les pods sont ajoutés lors d'un événement de mise à l'échelle à la hausse. Vous pouvez définir plusieurs politiques, et HPA utilisera celle qui permet le plus grand nombre de pods (mise à l'échelle la plus agressive).
    • type: Pods : Augmente d'un nombre fixe de pods. value spécifie le nombre de pods à ajouter. periodSeconds définit la fenêtre de temps sur laquelle cette politique s'applique.
    • type: Percent : Augmente d'un pourcentage du nombre actuel de pods. value est le pourcentage.

Configuration scaleDown :

  • stabilizationWindowSeconds : Plus critique pour scaleDown, cela spécifie combien de temps HPA doit observer des métriques en dessous de la cible avant d'envisager une réduction. Une fenêtre plus longue (par exemple, 300-600 secondes) empêche une réduction prématurée lors d'accalmies temporaires, évitant les « démarrages à froid » et les baisses de performance. C'est un paramètre crucial pour les environnements stables.

  • policies : Similaire à scaleUp, définit comment les pods sont supprimés. HPA utilise la politique qui entraîne le plus petit nombre de pods (réduction la plus agressive) si selectPolicy est Min, ou la politique qui entraîne le plus grand nombre de pods si selectPolicy est Max.

    • type: Pods : Supprime un nombre fixe de pods.
    • type: Percent : Supprime un pourcentage des pods actuels.
  • selectPolicy : Détermine quelle politique appliquer lorsque plusieurs politiques scaleDown sont définies. Max est la valeur par défaut et sélectionne la politique qui permet le plus grand changement d'échelle. Utilisez Min lorsque vous souhaitez une réduction plus conservatrice.

  • Avertissement : Soyez prudent avec les politiques scaleDown agressives ou les stabilizationWindowSeconds courtes pour scaleDown. 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 passent mieux à l'échelle avec des 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/mémoire n'est pas un indicateur direct de la charge de votre application ou du goulot d'étranglement des performances. Exemples : requêtes HTTP par seconde (QPS), connexions actives, longueur de file d'attente de messages, backlog de travaux par lots.

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) qui peut récupérer ces métriques et 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 qui ne s'exécute pas directement sur Kubernetes. Exemples : profondeur de file d'attente AWS SQS, retard de sujet Kafka, backlog d'abonnement Pub/Sub.

Pour utiliser des métriques externes :

  1. Vous avez besoin d'un serveur API de métriques personnalisées capable de récupérer les 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

HPA peut être configuré pour surveiller plusieurs métriques simultanément. Lorsque plusieurs métriques sont spécifiées, HPA calcule le nombre de réplicas souhaité pour chaque métrique indépendamment, puis sélectionne le plus élevé de ces nombres de réplicas souhaités. Cela garantit que l'application passe à l'échelle suffisamment pour toutes les dimensions de charge observées.

# ... (code standard 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

Un réglage efficace de l'HPA est un processus itératif qui nécessite une surveillance et une validation continues :

  • Observez 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 de HPA. Cela fournit des informations précieuses sur les raisons pour lesquelles HPA a augmenté ou réduit.
  • Surveillez les métriques et les réplicas : 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éplicas de pods au fil du temps. Corrélez ces éléments avec les changements de charge entrante.
  • Tests de charge : Simulez les charges attendues et de pointe pour valider la réactivité de HPA et garantir que votre application fonctionne comme prévu sous stress. Ajustez les paramètres HPA en fonction de ces tests.

Meilleures pratiques pour le réglage de l'HPA

  • Commencez avec des demandes/limites de ressources bien définies : Elles sont le fondement d'un HPA précis basé sur les ressources. Sans elles, HPA ne peut pas fonctionner efficacement pour le CPU/mémoire.
  • Définissez des minReplicas et maxReplicas réalistes : minReplicas fournit une base pour la disponibilité, tandis que maxReplicas sert de filet de sécurité contre les coûts incontrôlés et l'épuisement des ressources.
  • Ajustez progressivement l'utilisation cible : Commencez par une cible CPU légèrement conservatrice (par exemple, 60-70 %) et itérez. Ne visez pas une utilisation à 100 %, car cela ne laisse aucune marge pour la latence ou les pics de traitement.
  • Tirez parti de stabilizationWindowSeconds : Essentiel pour éviter les oscillations rapides de mise à l'échelle. Utilisez une fenêtre plus longue pour scaleDown (par exemple, 5-10 minutes) que pour scaleUp (par exemple, 1-2 minutes) pour garantir la stabilité.
  • Priorisez les métriques spécifiques à l'application : Si le CPU ou la mémoire n'est pas directement corrélé aux goulots d'étranglement des performances de votre application, utilisez des métriques personnalisées ou externes pour une mise à l'échelle plus précise et efficace.
  • Surveillez, testez, itérez : Le réglage de l'HPA n'est pas une configuration unique. Le comportement de l'application, les modèles de trafic et l'infrastructure sous-jacente peuvent changer. Examinez régulièrement les performances de HPA et ajustez les paramètres si nécessaire.
  • Comprenez les caractéristiques de mise à l'échelle de votre application : Est-ce qu'elle passe à l'échelle linéairement avec les requêtes ? A-t-elle des temps de démarrage longs ? Est-elle avec état ? Ces caractéristiques influencent votre stratégie HPA.

Dernier point à retenir

Considérez le réglage de l'HPA comme une boucle de rétroaction. Commencez avec des demandes de ressources précises, définissez des minReplicas et maxReplicas réalistes, choisissez une métrique qui suit la demande réelle, et validez le comportement de mise à l'échelle à la hausse et à la baisse avec des tests de charge avant que le trafic de production n'en dépende.