Contactez-nous

Vertical Pod Autoscaler (VPA) : Ajuster les requêtes/limites des Pods

Explorez le Vertical Pod Autoscaler (VPA) pour ajuster automatiquement les requêtes et limites CPU/mémoire de vos Pods Kubernetes et optimiser leur dimensionnement.

Le scaling vertical : optimiser les ressources de chaque Pod

Contrairement à l'Horizontal Pod Autoscaler (HPA) qui ajuste le nombre de Pods, le Vertical Pod Autoscaler (VPA) se concentre sur l'ajustement des ressources allouées à chaque Pod individuel. Son objectif principal est d'optimiser le dimensionnement des Pods en modifiant automatiquement leurs requêtes (requests) et potentiellement leurs limites (limits) de CPU et de mémoire en fonction de leur consommation historique.

Le VPA vise à résoudre le problème du 'right-sizing' : déterminer les bonnes valeurs de `requests` et `limits` est souvent difficile et basé sur des estimations initiales. Le VPA observe la consommation réelle des Pods sur le temps et fournit des recommandations, voire applique directement des valeurs plus adaptées. Cela peut aider à améliorer l'efficacité de l'utilisation des ressources (éviter le gaspillage dû à des requêtes trop élevées) et la stabilité (éviter les OOMKills dus à des limites trop basses).

Cependant, il est crucial de comprendre que, dans ses modes actifs, le VPA applique généralement ses mises à jour en recréant les Pods. Cela signifie qu'il est moins utilisé pour un scaling dynamique et continu en réponse à la charge (comme le HPA) et davantage comme un outil pour trouver et maintenir des valeurs de ressources optimales sur le long terme, car les redémarrages induits peuvent causer de courtes interruptions de service pour le Pod concerné.

Architecture et fonctionnement du VPA

Le VPA est généralement composé de trois composants principaux, souvent déployés via des Custom Resource Definitions (CRDs) et des contrôleurs associés (le VPA n'est pas inclus par défaut dans la plupart des distributions Kubernetes et doit être installé séparément) :

  1. VPA Recommender : Ce composant surveille la consommation historique des ressources (CPU et mémoire) des conteneurs des Pods ciblés (en utilisant généralement les données du Metrics Server). Il analyse ces données et calcule des valeurs recommandées pour les `requests` (et parfois `limits`) de CPU et de mémoire. Ces recommandations sont stockées dans l'objet `status` de la ressource personnalisée `VerticalPodAutoscaler`.
  2. VPA Updater : Ce composant vérifie si les Pods en cours d'exécution ont des requêtes/limites qui diffèrent significativement des recommandations du Recommender. Si l'Updater est configuré pour agir (mode `Auto` ou `Recreate`), et qu'une mise à jour est jugée nécessaire, il peut décider d'évincer le Pod. L'éviction provoque la suppression du Pod, qui sera ensuite recréé par son contrôleur parent (Deployment, StatefulSet...).
  3. VPA Admission Controller : C'est un webhook d'admission qui intercepte la création de nouveaux Pods gérés par un VPA. Lorsque le Pod est recréé (après éviction par l'Updater ou lors d'une création initiale), l'Admission Controller modifie la spécification du Pod avant qu'il ne soit sauvegardé dans etcd, en y injectant les valeurs de `requests` (et éventuellement `limits`) recommandées par le Recommender. C'est ainsi que les nouvelles valeurs sont appliquées au Pod recréé.

Modes de fonctionnement du VPA (`updateMode`)

Le comportement du VPA est principalement contrôlé par le champ updatePolicy.updateMode dans la spécification de l'objet `VerticalPodAutoscaler`. Les modes possibles sont :

  • "Off" : C'est le mode le plus sûr et un excellent point de départ. Le VPA Recommender calcule et publie ses recommandations dans le statut de l'objet VPA, mais ni l'Updater ni l'Admission Controller n'agissent. Aucune modification n'est appliquée aux Pods. Ce mode est idéal pour observer les suggestions du VPA et ajuster manuellement les requêtes/limites dans vos manifestes.
  • "Initial" : Dans ce mode, seul l'Admission Controller est actif lors de la création initiale d'un Pod. Il applique les recommandations de `requests` aux nouveaux Pods (ceux créés après l'activation du VPA ou lors d'un déploiement). Il ne modifie pas les Pods déjà en cours d'exécution.
  • "Recreate" : Dans ce mode, l'Updater évince les Pods lorsque leurs ressources diffèrent des recommandations. L'Admission Controller applique ensuite les recommandations lorsque le Pod est recréé. Ce mode implique des redémarrages de Pods et donc des interruptions potentielles. Il est crucial de s'assurer que l'application peut tolérer ces redémarrages (par exemple, avoir plusieurs réplicas derrière un Service).
  • "Auto" : Combine les modes `Initial` et `Recreate`. Il applique les recommandations aux nouveaux Pods et met également à jour les Pods en cours d'exécution en les recréant si nécessaire. C'est le mode le plus automatisé, mais il comporte les mêmes implications de redémarrage que le mode `Recreate`.

Configuration d'un VPA : exemple et options

Le VPA est configuré via une ressource personnalisée `VerticalPodAutoscaler`. Voici un exemple ciblant un Deployment `my-app` en mode `Auto` :

apiVersion: "autoscaling.k8s.io/v1" # Vérifiez la version API correcte pour votre installation VPA
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
  namespace: default
spec:
  # Référence à l'objet dont les Pods doivent être gérés
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: my-app

  # Politique de mise à jour
  updatePolicy:
    updateMode: "Auto" # Options: "Off", "Initial", "Recreate", "Auto"

  # Politique de ressources (contrôle fin sur les ajustements)
  resourcePolicy:
    containerPolicies: # Politique par conteneur (optionnel)
      - containerName: 'my-app-container' # Nom du conteneur spécifique
        minAllowed: # Valeurs minimales autorisées par VPA
          cpu: "100m"
          memory: "100Mi"
        maxAllowed: # Valeurs maximales autorisées par VPA
          cpu: "2"
          memory: "2Gi"
        controlledResources: ["cpu", "memory"] # Quelles ressources sont gérées par VPA (par défaut: cpu, memory)
        # controlledValues: RequestsAndLimits | RequestsOnly (par défaut: RequestsAndLimits, ajuste requests et fixe limits = requests)
        # mode: "Off" # Désactiver VPA pour ce conteneur spécifique

Eléments clés de la configuration :

  • targetRef : Désigne le contrôleur de charge de travail (Deployment, StatefulSet, DaemonSet, ReplicaSet, ReplicationController) dont les Pods sont ciblés.
  • updatePolicy.updateMode : Définit le mode de fonctionnement (Off, Initial, Recreate, Auto) comme décrit précédemment.
  • resourcePolicy (optionnel) : Permet de définir des contraintes plus fines :
    • containerPolicies : Appliquer des règles spécifiques à certains conteneurs du Pod.
    • minAllowed / maxAllowed : Définir des bornes minimales et maximales pour les recommandations de VPA, évitant des valeurs extrêmes.
    • controlledResources : Spécifier si VPA doit gérer le CPU, la mémoire, ou les deux.
    • controlledValues : Détermine si VPA doit ajuster uniquement les `requests` (RequestsOnly) ou les `requests` et les `limits` (RequestsAndLimits - dans ce cas, il fixe généralement la limite égale à la requête recommandée). Le comportement par défaut peut dépendre de l'installation du VPA.

Quand utiliser le VPA et précautions à prendre

Cas d'usage :

  • Mode `Off` : Excellent pour obtenir des recommandations fiables de dimensionnement basées sur l'usage réel, sans perturber les applications. Utile lors des phases de développement, de test, ou pour auditer périodiquement les déploiements existants.
  • Modes `Initial`, `Auto`, `Recreate` : Pour automatiser le dimensionnement dans des environnements où les redémarrages de Pods sont acceptables et où l'optimisation continue des ressources est souhaitée. Particulièrement utile pour les applications dont le profil de consommation change lentement au fil du temps.

Limitations et précautions :

  • Redémarrages : Le principal inconvénient des modes actifs (`Recreate`, `Auto`) est la nécessité de redémarrer les Pods pour appliquer les changements. Assurez-vous que cela est compatible avec les exigences de disponibilité de votre application (utiliser des PodDisruptionBudgets, avoir plusieurs réplicas).
  • Conflit avec HPA : Il est généralement déconseillé d'utiliser le VPA en mode actif (`Initial`, `Recreate`, `Auto`) pour gérer le CPU ou la mémoire en même temps que le HPA gère ces mêmes métriques pour le même ensemble de Pods. Les deux systèmes pourraient se contrecarrer (VPA modifie les requêtes, ce qui change la base de calcul du HPA, qui modifie le nombre de réplicas, ce qui change la consommation moyenne, etc.). Une approche courante est d'utiliser VPA en mode `Off` pour déterminer les bonnes requêtes/limites, puis de configurer HPA en se basant sur ces valeurs fixes. Si vous utilisez les deux, VPA devrait idéalement être en mode `Off`, ou ne gérer qu'une ressource (ex: mémoire) pendant que HPA gère l'autre (ex: CPU ou métrique custom).
  • StatefulSets : Le VPA en mode `Auto`/`Recreate` peut être problématique avec les StatefulSets, car l'éviction d'un Pod peut perturber le quorum ou l'état de l'application distribuée. Une configuration prudente est nécessaire.
  • Réaction aux pics : Le VPA se base sur l'historique. Il peut ne pas réagir assez vite à des pics de charge très soudains et courts. Les limites sont toujours importantes pour contenir ces pics.
  • Installation : Rappelez-vous que le VPA doit généralement être installé manuellement dans le cluster.

En conclusion, le Vertical Pod Autoscaler est un outil précieux pour optimiser le dimensionnement des ressources de vos Pods, surtout lorsqu'il est utilisé en mode recommandation (`Off`). Ses modes actifs offrent une automatisation plus poussée mais nécessitent une attention particulière aux implications des redémarrages et à son interaction potentielle avec l'HPA.