## Introduction

Les clusters Kubernetes exécutent souvent des charges de travail aux besoins en ressources variables. Définir des demandes et des limites de ressources trop basses provoque une limitation (throttling) ou une éviction ; les définir trop élevées gaspille la capacité et augmente les coûts cloud. Le Vertical Pod Autoscaler (VPA) ajuste automatiquement les demandes et limites de CPU et de mémoire des pods en fonction de l'utilisation observée. Contrairement au Horizontal Pod Autoscaler (HPA), qui modifie le nombre de réplicas, le VPA modifie la spécification du pod pour dimensionner correctement les ressources. Ce guide se concentre sur les commandes kubectl essentielles pour exploiter efficacement le VPA, avec des exemples pratiques, des modèles de configuration sûrs et des étapes de dépannage.

Le VPA n'est pas activé par défaut dans la plupart des clusters. Il est généralement installé sous forme d'un ensemble de contrôleurs et d'un webhook d'admission mutable depuis le dépôt Kubernetes autoscaler. Vous interagissez avec le VPA via sa définition de ressource personnalisée (CRD) : `VerticalPodAutoscaler`. À l'aide des commandes kubectl de base, vous pouvez inspecter les recommandations, surveiller les mises à jour et diagnostiquer les problèmes. Cet article fournit une référence pratique pour les opérations quotidiennes.

## Inventaire de la version et de l'environnement

Avant d'utiliser les commandes VPA, établissez l'état de votre environnement de cluster. Vous devez connaître :

- La version du cluster Kubernetes. Le VPA prend en charge Kubernetes 1.8 et plus, mais les versions récentes sont fortement recommandées pour la stabilité et les corrections de bogues.
- La version du VPA installée. Vous pouvez la trouver en vérifiant les balises d'image du contrôleur ou le manifeste de déploiement du VPA.
- Si le VPA fonctionne en mode « recommandation uniquement » ou s'il applique activement les mises à jour. Ceci est contrôlé par le champ `updateMode` dans chaque objet VPA.
- Les espaces de noms où les objets VPA existent. Utilisez `kubectl get vpa -A` pour lister tous les VPA dans tous les espaces de noms.

Tout d'abord, vérifiez la connectivité du cluster et la version de kubectl :

```bash
kubectl version --short
```

La sortie attendue inclut les versions client et serveur, par exemple :

```text
Client Version: v1.27.3
Kustomize Version: v5.0.1
Server Version: v1.27.3
```

Ensuite, vérifiez si les CRD VPA sont installées :

```bash
kubectl get crd | grep verticalpodautoscalers
```

Si le VPA est installé, vous devriez voir la CRD `verticalpodautoscalers.autoscaling.k8s.io`. Sinon, installez le VPA avant de continuer.

Identifiez les pods du contrôleur VPA (généralement exécutés dans `kube-system`) :

```bash
kubectl get pods -n kube-system | grep vpa
```

Exemple de sortie :

```text
vpa-admission-controller-6d5c8f6c9b-abcde   1/1     Running   0          10d
vpa-recommender-6d5c8f6c9b-fghij           1/1     Running   0          10d
vpa-updater-6d5c8f6c9b-klmno               1/1     Running   0          10d
```

Les trois composants sont :

- **Recommender** (recommande) : surveille l'utilisation des ressources des pods et calcule les demandes et limites recommandées.
- **Updater** (metteur à jour) : évince les pods dont les ressources doivent être mises à jour (lorsque `updateMode` le permet).
- **Admission Controller** (contrôleur d'admission) : modifie les spécifications des pods au moment de la création pour appliquer les recommandations VPA (si activé).

Comprendre cette architecture aide à interpréter les sorties de commandes et à diagnostiquer les échecs.

## Chemin de configuration sécurisé

Lors de la configuration du VPA, commencez avec une portée étroite et évitez toute perturbation immédiate des pods. L'approche la plus sûre consiste à commencer avec `updateMode: Off` pour observer les recommandations sans mises à jour automatiques. Après validation, passez en mode `Recreate` pour des mises à jour contrôlées. Les étapes suivantes décrivent le cycle de vie complet.

### Étape 1 : Créer un objet VPA pour une charge de travail spécifique

Créez un fichier YAML `myapp-vpa.yaml` avec le contenu suivant (ajustez le sélecteur et le nom pour votre application) :

```yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: myapp-vpa
  namespace: default
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: myapp
  updatePolicy:
    updateMode: "Off"   # commencer par Off pour obtenir uniquement des recommandations
  resourcePolicy:
    containerPolicies:
      - containerName: '*'
        minAllowed:
          cpu: 100m
          memory: 100Mi
        maxAllowed:
          cpu: 2
          memory: 2Gi
        controlledResources: ["cpu", "memory"]
```

Cet objet cible un déploiement nommé `myapp`. `containerName: '*'` s'applique à tous les conteneurs. `minAllowed` et `maxAllowed` bornent les recommandations. Appliquez-le :

```bash
kubectl apply -f myapp-vpa.yaml
```

Vérifiez que l'objet existe :

```bash
kubectl get vpa myapp-vpa
```

### Étape 2 : Inspecter les détails de l'objet VPA

Utilisez `kubectl describe vpa myapp-vpa` pour voir le statut, y compris les recommandations, les demandes de ressources actuelles des pods et les conditions :

```bash
kubectl describe vpa myapp-vpa -n default
```

Exemple d'extrait de la section `Status` :

```text
Status:
  Recommendation:
    Container Recommendations:
      Container Name: myapp-container
      Lower Bound:
        Cpu:     100m
        Memory:  100Mi
      Target:
        Cpu:     250m
        Memory:  200Mi
      Upper Bound:
        Cpu:     500m
        Memory:  400Mi
  Conditions:
    Last Transition Time:  2023-10-01T12:00:00Z
    Message:               Recommendation is provided
    Reason:                RecommendationProvided
    Status:                True
    Type:                  RecommendationProvided
```

Dans cet exemple, le VPA recommande une cible de 250m CPU et 200Mi mémoire, dans les bornes spécifiées. Les ressources actuelles des pods sont également affichées ailleurs dans la sortie ; comparez-les à la recommandation.

### Étape 3 : Passer en mode « Recreate » après validation

Une fois que les recommandations semblent raisonnables, vous pouvez autoriser le VPA à mettre à jour automatiquement les pods. Modifiez l'objet VPA :

```bash
kubectl edit vpa myapp-vpa
```

Changez `updateMode: "Off"` en `updateMode: "Recreate"`. Vous pouvez également utiliser un patch JSON :

```bash
kubectl patch vpa myapp-vpa --type='json' -p='[{"op": "replace", "path": "/spec/updatePolicy/updateMode", "value": "Recreate"}]'
```

Vérifiez la mise à jour :

```bash
kubectl get vpa myapp-vpa -o yaml | grep updateMode
```

La sortie doit afficher `updateMode: Recreate`. En mode Recreate, le VPA évince les pods qui ont besoin de nouvelles ressources. Pour minimiser les perturbations, assurez-vous que votre déploiement a plusieurs réplicas et qu'un PodDisruptionBudget (PDB) est en place.

## Vérification et diagnostics

Une fois le VPA actif, surveillez son comportement et vérifiez que les ressources des pods sont ajustées correctement.

### Vérifier les recommandations VPA

Utilisez `kubectl describe vpa <nom>` pour afficher le résumé actuel des recommandations. Par exemple :

```bash
kubectl describe vpa myapp-vpa | grep -A5 Recommendation
```

Cela montre les ressources cibles recommandées. Comparez-les avec la spécification réelle du pod en vérifiant le déploiement :

```bash
kubectl get deployment myapp -o yaml | grep -A4 resources
```

Pour un pod en cours d'exécution, obtenez ses ressources réelles :

```bash
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].resources}'
```

Cela imprime les demandes et limites de ressources telles qu'appliquées. Si elles diffèrent du modèle de déploiement, le contrôleur d'admission peut avoir modifié le pod.

### Afficher les événements VPA

Les événements donnent un aperçu des actions VPA, telles que les évictions et mises à jour de pods :

```bash
kubectl get events --field-selector involvedObject.name=myapp-vpa
```

Ou filtrez les événements dans l'espace de noms :

```bash
kubectl get events -n default --sort-by=.metadata.creationTimestamp
```

Recherchez des messages comme `Pod myapp-xyz was evicted to apply new resource recommendations` ou `Updated pod myapp-xyz with recommended resources`.

### Lister tous les objets VPA dans un espace de noms

```bash
kubectl get vpa -n default
```

Exemple de sortie :

```text
NAME        MODE    CPU    MEMORY   PROVIDED   AGE
myapp-vpa   Recreate    250m   200Mi    True       1h
```

### Obtenir le VPA en YAML pour tous les détails

```bash
kubectl get vpa myapp-vpa -o yaml
```

Ceci est utile pour auditer la spécification complète et le statut, y compris les politiques de ressources et les conditions. Recherchez `status.conditions` pour confirmer que le recommender fonctionne.

### Vérifier si le contrôleur d'admission modifie les spécifications des pods

Lorsqu'un pod est créé, le contrôleur d'admission peut modifier ses demandes de ressources en fonction des recommandations VPA. Pour voir les ressources réelles du pod :

```bash
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].resources}'
```

Si la sortie diffère du modèle de déploiement, le VPA modifie activement les pods. Notez que cela ne s'applique que lorsque le contrôleur d'admission est déployé et que le mode de mise à jour VPA est `Recreate` ou `InPlaceOrRecreate` ; en mode `Off`, aucune mutation n'a lieu.

## Modes de défaillance et récupération

Le VPA peut rencontrer des problèmes tels que des recommandations incorrectes, des évictions de pods inattendues ou des conflits avec d'autres outils de gestion des ressources. Savoir détecter et récupérer de ces situations est crucial.

### Modes de défaillance courants et remèdes

1. **Le VPA recommande des ressources trop faibles ou trop élevées en raison de données historiques insuffisantes.**
   - **Détection** : Redémarrages de pods, métriques de limitation CPU ou événements OOMKilled mémoire. Vérifiez les événements de pod : `kubectl describe pod <pod-name> | grep OOMKilled`.
   - **Récupération** : Réglez temporairement `updateMode: Off` et ajustez les bornes `minAllowed`/`maxAllowed` dans `resourcePolicy`. Ou supprimez l'objet VPA pour arrêter toutes les recommandations. Assurez-vous que la charge de travail a suffisamment de réplicas pour servir le trafic pendant le réglage.

2. **Le VPA évince excessivement les pods, provoquant une instabilité de l'application.**
   - **Détection** : Redémarrages fréquents des pods et événements VPA montrant des évictions. Surveillez `kubectl get events | grep Evicted`.
   - **Récupération** : Réglez `updateMode: Initial` pour appliquer les recommandations uniquement à la création du pod, ou `Off` pour arrêter les mises à jour. Réglez `minReplicas` dans un PodDisruptionBudget ou assurez-vous que l'application peut gérer les mises à jour progressives avec grâce. Envisagez d'augmenter les réplicas pendant la période de réglage.

3. **Le contrôleur d'admission remplace les demandes de ressources explicites des pods, entraînant un comportement inattendu.**
   - **Détection** : Les ressources de la spécification du pod diffèrent de la spécification du déploiement. Utilisez `kubectl get pod <pod> -o yaml` et comparez avec `kubectl get deployment <deploy> -o yaml`.
   - **Récupération** : Supprimez le VPA pour cette charge de travail, ou excluez des conteneurs spécifiques en utilisant `containerPolicies` avec `mode: "Off"`. Réappliquez les demandes de ressources souhaitées au déploiement.

4. **Les composants VPA ne fonctionnent pas (par exemple, le pod recommender en boucle de crash), entraînant aucune recommandation.**
   - **Détection** : `kubectl get pods -n kube-system | grep vpa` montre des pods non fonctionnels ; vérifiez les journaux pour les erreurs.
   - **Récupération** : Redémarrez le pod défaillant ou redéployez le VPA. Vérifiez les journaux pour la cause racine, comme des autorisations insuffisantes ou des drapeaux mal configurés.

### Étapes de restauration

Pour annuler les modifications VPA :

1. Supprimez l'objet VPA pour la charge de travail :
   ```bash
   kubectl delete vpa myapp-vpa
   ```
   Cela arrête les recommandations et les mises à jour automatiques. Les pods existants conservent leurs valeurs de ressources actuelles, mais les nouveaux pods utiliseront le modèle de déploiement sans mutation VPA.

2. Restaurez les demandes de ressources d'origine dans le déploiement si elles ont été modifiées par le VPA. Modifiez le déploiement :
   ```bash
   kubectl edit deployment myapp
   ```
   Définissez manuellement les ressources sur des valeurs connues comme bonnes, ou appliquez un manifeste précédemment sauvegardé.

3. Vérifiez que les ressources des pods reviennent aux valeurs attendues en vérifiant une spécification de pod :
   ```bash
   kubectl get pod <new-pod> -o jsonpath='{.spec.containers[0].resources}'
   ```

### Vérifier les journaux des composants VPA pour le dépannage

Pour les problèmes du recommender :

```bash
kubectl logs -n kube-system deployment/vpa-recommender --tail=50
```

Pour les problèmes du contrôleur d'admission :

```bash
kubectl logs -n kube-system deployment/vpa-admission-controller --tail=50
```

Pour les problèmes de l'updater :

```bash
kubectl logs -n kube-system deployment/vpa-updater --tail=50
```

Recherchez des messages d'erreur liés aux appels API, à la collecte de métriques ou aux échecs d'éviction de pods.

## Pièges courants et comment les éviter

Au-delà des défaillances manifestes, plusieurs pièges subtils peuvent nuire à l'efficacité du VPA.

1. **Ignorer les bornes inférieures et supérieures.** Sans définir `minAllowed` et `maxAllowed`, le VPA peut recommander des ressources très faibles pour les applications inactives, provoquant des échecs de démarrage, ou des ressources très élevées pour les charges de travail en pointe, gaspillant la capacité du cluster. Définissez toujours des bornes basées sur la ligne de base et les pics attendus de votre application. Par exemple, un service web qui utilise généralement 200m CPU mais monte à 1 CPU pendant les pics de trafic devrait avoir `minAllowed: cpu: 100m` et `maxAllowed: cpu: 1.5` pour éviter la limitation pendant les pics.

2. **Utiliser le VPA avec HPA sur la même métrique.** Le VPA et le HPA peuvent entrer en conflit s'ils essaient tous deux de gérer le CPU ou la mémoire. Si le HPA met à l'échelle les réplicas en fonction du CPU et que le VPA ajuste les demandes de CPU, l'interaction peut provoquer des oscillations. La documentation Kubernetes recommande de ne pas utiliser le VPA avec HPA sur le CPU ou la mémoire simultanément. Si vous avez besoin des deux, utilisez le VPA pour la mise à l'échelle verticale et le HPA pour une métrique différente (par exemple, des métriques personnalisées) ou utilisez Kubernetes Event-driven Autoscaling (KEDA) pour la mise à l'échelle événementielle. Pour récupérer, désactivez temporairement un contrôleur et observez la stabilité.

3. **Oublier les budgets de perturbation des pods.** En mode `Recreate`, le VPA peut évincer les pods qui ont besoin de plus de ressources. Si votre déploiement a peu de réplicas et aucun PDB, cela peut provoquer des temps d'arrêt. Définissez toujours un PDB pour limiter les perturbations volontaires. Exemple de PDB :

   ```yaml
   apiVersion: policy/v1
   kind: PodDisruptionBudget
   metadata:
     name: myapp-pdb
   spec:
     minAvailable: 2
     selector:
       matchLabels:
         app: myapp
   ```

4. **Appliquer le VPA à des charges de travail avec état sans tests minutieux.** Les StatefulSets ont souvent une identité persistante et une gestion ordonnée des pods. Les évictions VPA peuvent perturber les applications avec état. Testez le VPA dans un environnement de préproduction d'abord, et utilisez `updateMode: Off` initialement. Pour les bases de données, envisagez d'utiliser `updateMode: Initial` afin que les ressources ne soient définies qu'à la création du pod, et replanifiez manuellement les pods pendant les fenêtres de maintenance.

5. **Supposer que les recommandations VPA sont instantanément correctes.** Le VPA utilise des données d'utilisation historiques ; il a besoin de temps pour apprendre. Les nouvelles charges de travail peuvent recevoir des recommandations sous-optimales jusqu'à ce que suffisamment de données s'accumulent (généralement plusieurs jours). Surveillez les recommandations au fil du temps et ajustez les bornes si nécessaire. Une condition VPA saine `RecommendationProvided` avec le statut `True` ne garantit pas que la recommandation est parfaite ; cela signifie seulement que le recommender a fonctionné. Validez toujours avec vos propres métriques.

## Liste de contrôle des opérations

Utilisez la liste de contrôle suivante pour les opérations VPA régulières. Pour chaque élément, un propriétaire est suggéré ; dans une équipe, un ingénieur de plateforme unique ou un SRE d'astreinte doit être responsable, et la liste de contrôle est généralement examinée chaque semaine sauf indication contraire.

| Étape | Commande | Objectif | Propriétaire | Fréquence |
|------|---------|---------|-------|-----------|
| 1 | `kubectl get vpa -A` | Lister tous les VPA dans tous les espaces de noms | Ingénieur de plateforme | Hebdomadaire |
| 2 | `kubectl describe vpa <vpa-name> -n <namespace>` | Voir les recommandations et le statut | Propriétaire d'application | Hebdomadaire |
| 3 | `kubectl get events -n <namespace> \| grep VPA` | Vérifier les événements liés au VPA | SRE d'astreinte | Quotidien |
| 4 | `kubectl get pods -n kube-system \| grep vpa` | Vérifier que les composants VPA fonctionnent | Ingénieur de plateforme | Quotidien |
| 5 | `kubectl logs -n kube-system deployment/vpa-recommender --tail=20` | Vérifier les journaux du recommender pour les erreurs | Ingénieur de plateforme | Hebdomadaire |
| 6 | `kubectl get vpa <vpa-name> -o yaml \| grep updateMode` | Confirmer que le mode de mise à jour est conforme | Propriétaire d'application | Avant tout changement |
| 7 | `kubectl describe pod <pod-name> \| grep -A2 Requests` | Comparer les ressources réelles des pods avec les recommandations | Propriétaire d'application | Hebdomadaire |
| 8 | En cas de problème, définir `updateMode: Off` via patch | Arrêter immédiatement les mises à jour VPA | SRE d'astreinte | Au besoin |

Ajustez la fréquence en fonction de la taille et de la criticité de votre environnement. En production, des vérifications automatisées quotidiennes avec alertes sont recommandées.

## Conclusion

Maîtriser les commandes kubectl de base pour Kubernetes Vertical Pod Autoscaler vous permet de gérer en toute sécurité l'optimisation des ressources dans vos clusters. Commencez par `kubectl get vpa`, `kubectl describe vpa` et la surveillance des événements pour comprendre le comportement du VPA. Adoptez ensuite progressivement les mises à jour automatiques avec une validation minutieuse. Ayez toujours un plan de restauration : supprimer l'objet VPA et restaurer les spécifications de ressources est simple. En suivant le chemin de configuration sécurisé, en évitant les pièges courants et en utilisant les commandes de diagnostic décrites ici, vous pouvez maintenir vos charges de travail correctement dimensionnées et votre cluster efficace.

Pour aller plus loin, consultez la documentation officielle Kubernetes VPA et expérimentez d'abord dans un espace de noms hors production.