Introduction
Les budgets de perturbation des pods Kubernetes (PDB, de l'anglais Pod Disruption Budgets) définissent le nombre minimal de pods qui doivent rester disponibles lors de perturbations volontaires telles que les drainages de nœuds, les mises à niveau de cluster ou les opérations de maintenance. Automatiser la gestion des PDB dans les pipelines CI/CD garantit que les politiques de disponibilité sont appliquées de manière cohérente dans tous les environnements, réduisant ainsi les erreurs humaines et évitant les interruptions accidentelles. Ce guide propose une approche pratique, étape par étape, pour intégrer l'automatisation des PDB dans votre flux de livraison, depuis l'inventaire initial de l'environnement jusqu'à la reprise après échec.
Nous nous adressons aux praticiens : développeurs, ingénieurs DevOps et équipes techniques qui exploitent des clusters Kubernetes en production. À la fin de cet article, vous saurez comment :
- Découvrir les PDB existants et leur statut
- Modifier en toute sécurité les PDB à l'aide de manifestes déclaratifs
- Intégrer les modifications de PDB dans les pipelines CI/CD avec validation automatisée
- Diagnostiquer les problèmes courants liés aux PDB
- Mettre en œuvre des stratégies de restauration lorsque les choses tournent mal
L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés plutôt que des secrets, vérifier les résultats et documenter les chemins de récupération.
Inventaire des versions et de l'environnement
Avant d'automatiser les PDB, établissez une image claire de votre cluster et de vos outils. Les PDB sont pris en charge dans Kubernetes v1.21+ (stable), mais le comportement peut varier légèrement selon la version. Vérifiez la version de votre cluster avec :
kubectl version --short
La sortie attendue inclut les versions client et serveur. Par exemple :
Client Version: v1.27.3
Server Version: v1.27.3
Ensuite, faites l'inventaire des PDB existants dans tous les espaces de noms :
kubectl get pdb --all-namespaces
Cette commande liste tous les PDB du cluster, en indiquant l'espace de noms, le nom, le minimum disponible/maximum indisponible, les perturbations autorisées et l'âge. Exemple de sortie :
NAMESPACE NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
default app-pdb N/A 1 1 2d
kube-system coredns-pdb 1 N/A 0 30d
Aucun PDB ? Vous devrez les créer dans le cadre de votre automatisation. Notez également quels contrôleurs gèrent vos charges de travail, car les PDB reposent sur des sélecteurs d'étiquettes correspondant aux pods. Pour cet article, nous supposons une application typique basée sur un déploiement appelée webapp dans l'espace de noms default.
Vérifiez les étiquettes actuelles des pods pour vous assurer que votre sélecteur PDB correspondra :
kubectl get pods -l app=webapp --show-labels
La sortie attendue montre des étiquettes comme app=webapp. Si les étiquettes sont incohérentes, corrigez-les avant de continuer.
Gardez votre environnement de test local petit. Utilisez un outil comme minikube ou kind pour expérimenter en toute sécurité avant de toucher à la production. Appliquez un manifeste à la fois et vérifiez avec kubectl port-forward ou un service local avant de passer aux équilibreurs de charge cloud ou aux contrôleurs d'entrée.
Chemin de configuration sécurisé
Les PDB sont définis à l'aide de manifestes YAML. Un PDB de base pour un déploiement avec trois réplicas, exigeant qu'au moins deux pods soient disponibles, ressemble à ceci :
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: webapp-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: webapp
Enregistrez ceci sous webapp-pdb.yaml. Avant d'appliquer, examinez toujours l'état en direct :
kubectl get deployment webapp -o wide
kubectl get pods -l app=webapp
Cela confirme que le déploiement existe et que les pods sont en cours d'exécution. Appliquez ensuite le PDB :
kubectl apply -f webapp-pdb.yaml
Vérifiez que le PDB a été créé correctement :
kubectl get pdb webapp-pdb -o yaml
Consultez la section status. Elle devrait afficher currentHealthy et desiredHealthy. Par exemple :
status:
currentHealthy: 3
desiredHealthy: 2
disruptionsAllowed: 1
expectedPods: 3
currentHealthy doit être supérieur ou égal à desiredHealthy pour que les perturbations soient autorisées. Si disruptionsAllowed est égal à 0, le PDB bloque toutes les perturbations volontaires ; enquêtez immédiatement.
Dans un environnement versionné, stockez ce manifeste dans Git et utilisez CI/CD pour appliquer les modifications. Par exemple, dans un workflow GitHub Actions, vous pourriez avoir un job qui exécute kubectl apply à chaque push sur la branche principale. Utilisez toujours un compte de service dédié avec le moindre privilège (uniquement les autorisations de création/mise à jour de PDB) et stockez les informations d'identification du cluster dans des secrets.
Extrait CI/CD conceptuel :
- name: Apply PDB
run: |
kubectl apply -f deploy/webapp-pdb.yaml
kubectl rollout status deployment/webapp --timeout=60s
Ne codez pas en dur les valeurs sensibles. Utilisez des variables d'environnement ou des références de secrets.
Vérification et diagnostic
Après avoir appliqué un PDB, vérifiez qu'il fonctionne comme prévu. Simulez une perturbation volontaire à l'aide de kubectl drain sur un nœud (dans un cluster de test uniquement) :
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
Observez le processus d'éviction :
kubectl get pods -l app=webapp -w
Les pods doivent être évincés un par un, mais au moins minAvailable pods restent en cours d'exécution. Si la commande drain se bloque, le PDB bloque les évictions car il ne peut pas garantir la disponibilité. Vérifiez le statut du PDB :
kubectl describe pdb webapp-pdb
Recherchez des événements comme Evicting pod webapp-xxxxx ou Cannot evict pod as it would violate the pod's disruption budget. Ce dernier indique une inadéquation de configuration ; par exemple, minAvailable peut être défini trop haut ou le sélecteur ne correspond à aucun pod.
Commandes de diagnostic courantes :
kubectl get pdb- liste tous les PDB et leurs perturbations autoriséeskubectl describe pdb <name>- statut détaillé et événementskubectl get events --field-selector involvedObject.name=<pdb-name>- événements récents liés au PDBkubectl logs <pod-name> --previous- vérifier les journaux de l'application si les pods sont en boucle de crash
Utilisez kubectl rollout status deployment/webapp pour confirmer que le déploiement est sain après tout changement. Si le déploiement est bloqué, inspectez avec kubectl rollout history deployment/webapp et kubectl rollout undo deployment/webapp si nécessaire.
Pour la vérification locale, utilisez kubectl port-forward pour exposer le service et tester le trafic :
kubectl port-forward svc/webapp 8080:80
Ensuite, exécutez curl http://localhost:8080 depuis un autre terminal. La réponse attendue est le point de terminaison de santé de votre application.
Modes de défaillance et récupération
L'automatisation des PDB peut échouer de plusieurs façons. Examinons les scénarios courants et comment récupérer.
Scénario 1 : Le PDB bloque toutes les évictions en raison d'un sélecteur incorrect
Symptôme : kubectl drain se bloque, kubectl describe pdb affiche disruptionsAllowed: 0 même si les pods sont sains.
Diagnostic : Vérifiez kubectl get pdb -o yaml et assurez-vous que le sélecteur correspond aux étiquettes réelles des pods. Utilisez kubectl get pods --show-labels.
Récupération : Corrigez le sélecteur dans le manifeste, appliquez-le et réessayez. Si un déblocage immédiat est nécessaire (par exemple, maintenance critique), supprimez temporairement le PDB :
kubectl delete pdb webapp-pdb
Réappliquez ensuite le PDB corrigé après la maintenance.
Scénario 2 : PDB manquant lors d'une mise à niveau de cluster
Symptôme : Lors d'une mise à niveau de nœud, tous les pods d'un service sont évincés simultanément, provoquant une panne.
Diagnostic : Après coup, kubectl get pdb ne montre aucun PDB pour la charge de travail. Examinez l'historique Git pour voir si le manifeste PDB a été accidentellement supprimé.
Récupération : Réappliquez immédiatement le PDB depuis le contrôle de version. Ensuite, augmentez le nombre de réplicas du déploiement et vérifiez la santé. Empêchez la récurrence en ajoutant une vérification CI : si un espace de noms a des charges de travail, assurez-vous qu'un PDB existe.
Scénario 3 : minAvailable défini plus haut que le nombre de réplicas
Symptôme : kubectl apply réussit mais kubectl describe pdb affiche currentHealthy inférieur à desiredHealthy, et disruptionsAllowed reste à 0. De plus, les déploiements ne peuvent pas réduire leur échelle.
Diagnostic : Comparez minAvailable dans la spécification du PDB avec le nombre réel de réplicas dans le déploiement.
Récupération : Soit augmentez le nombre de réplicas pour satisfaire minAvailable, soit réduisez minAvailable à une valeur raisonnable (par exemple, replicas - 1). Appliquez le changement et vérifiez que currentHealthy >= desiredHealthy.
Stratégies de restauration
Comme les PDB sont des objets Kubernetes, la restauration est simple :
- Identifiez le dernier bon manifeste PDB connu dans l'historique Git.
- Appliquez-le avec
kubectl apply -f <dernier-bon-manifeste>.yaml. - Vérifiez le statut.
Pour l'automatisation, envisagez de stocker les manifestes PDB avec des balises de version dans un dépôt Git. En CI/CD, utilisez une stratégie de déploiement qui peut revenir à une balise précédente en cas d'échec. Par exemple, dans une configuration GitOps avec Argo CD ou Flux, les modifications de PDB font partie de la configuration de l'application ; revenir à un commit précédent dans le dépôt Git rétablit automatiquement le PDB.
Si un PDB a été supprimé par erreur, recréez-le immédiatement depuis le contrôle de source. Ne comptez pas sur une reconstruction manuelle.
Intégration aux pipelines CI/CD
Une fois que vous avez testé manuellement les modifications de PDB, intégrez-les à votre pipeline. L'objectif est de garantir que toute modification des manifestes PDB passe par une validation automatisée avant d'atteindre la production.
Étapes du pipeline
- Lint et validation : Utilisez
kubectl apply --dry-run=clientouserverpour valider les manifestes sans les appliquer. Par exemple :
kubectl apply -f webapp-pdb.yaml --dry-run=client
Sortie attendue : poddisruptionbudget.policy/webapp-pdb created (dry run)
- Analyse statique : Utilisez des outils comme
kubevaloukubeconformpour valider la structure YAML par rapport aux schémas Kubernetes. Exécutez-les en CI.
- Appliquer au staging : Déployez le PDB dans le cluster de staging et exécutez des tests d'intégration qui simulent des perturbations.
- Vérifier le statut du PDB : Après l'application, exécutez un script qui vérifie :
kubectl get pdb webapp-pdb -o jsonpath='{.status.disruptionsAllowed}'
Assurez-vous qu'il renvoie un nombre non nul (si les perturbations doivent être autorisées).
- Approuver et appliquer en production : Utilisez une porte d'approbation manuelle ou une livraison progressive.
Exemple de pipeline (GitHub Actions)
Voici un workflow condensé pour appliquer les modifications de PDB à un cluster Kubernetes à l'aide de GitHub Actions. Il utilise azure/k8s-set-context pour définir le contexte du cluster et kubectl pour appliquer les manifestes.
name: PDB Deployment
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: azure/k8s-set-context@v3
with:
kubeconfig: ${{ secrets.KUBE_CONFIG }}
- name: Validate PDB manifest
run: |
kubectl apply -f deploy/webapp-pdb.yaml --dry-run=client
- name: Apply PDB
run: |
kubectl apply -f deploy/webapp-pdb.yaml
- name: Wait for PDB to be active
run: |
kubectl wait --for=condition=ready pdb/webapp-pdb --timeout=60s
- name: Verify disruptions allowed
run: |
ALLOWED=$(kubectl get pdb webapp-pdb -o jsonpath='{.status.disruptionsAllowed}')
if [ "$ALLOWED" -lt 1 ]; then echo "PDB not allowing disruptions"; exit 1; fi
Test en CI/CD
Simulez une perturbation volontaire dans votre environnement de staging après avoir appliqué le PDB. Vous pouvez utiliser kubectl drain sur un nœud de staging (ou un minikube dédié) et vérifier que les pods restent disponibles. Automatisez cela dans un job de test séparé si possible. Par exemple, dans un cluster kind, vous pouvez exécuter :
kubectl drain kind-worker --ignore-daemonsets --delete-emptydir-data
Vérifiez ensuite la disponibilité de l'application à l'aide d'un simple curl ou d'une sonde.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle avant et après tout changement de PDB pour garantir la sécurité opérationnelle.
| Étape | Commande/Action | Résultat attendu | Notes |
|---|---|---|---|
| 1. Inventorier les PDB actuels | kubectl get pdb --all-namespaces | Liste des PDB existants avec statut | Capturer la référence |
| 2. Vérifier la version du cluster | kubectl version --short | Version du serveur >= 1.21 | PDB stable depuis 1.21 |
| 3. Vérifier les étiquettes des charges de travail | kubectl get pods -l app=webapp --show-labels | Les pods ont les étiquettes attendues | S'assurer que le sélecteur correspond |
| 4. Créer/Mettre à jour le manifeste PDB | Utiliser un fichier YAML avec minAvailable ou maxUnavailable | Manifeste validé avec kubectl apply --dry-run | Stocker dans Git |
| 5. Appliquer le PDB | kubectl apply -f webapp-pdb.yaml | PDB créé/mis à jour | Utiliser CI/CD pour l'automatisation |
| 6. Vérifier le statut du PDB | kubectl describe pdb webapp-pdb | disruptionsAllowed > 0 | Si 0, enquêter |
| 7. Tester la perturbation (staging) | kubectl drain <node> | Pods évincés mais minAvailable reste | Uniquement en environnement de test |
| 8. Valider la santé de l'application | kubectl rollout status deployment/webapp | Déploiement réussi | Utiliser port-forward pour test local |
| 9. Documenter la récupération | Stocker les commandes de restauration dans le runbook | S'assurer que l'équipe sait comment revenir en arrière | Manifestes PDB dans Git |
| 10. Surveiller | Configurer des alertes sur le statut du PDB | Alerter si disruptionsAllowed devient 0 de manière inattendue | Utiliser les métriques Prometheus si disponibles |
Gardez cette liste de contrôle accessible dans le runbook de votre équipe et mettez-la à jour à mesure que les procédures évoluent.
Conclusion
Automatiser les budgets de perturbation des pods Kubernetes dans CI/CD ne consiste pas seulement à appliquer des fichiers YAML ; cela exige une approche disciplinée de l'observation, de la configuration sécurisée, de la vérification et de la récupération. En inventoriant votre environnement, en utilisant des manifestes sous contrôle de version, en intégrant la validation dans les pipelines et en vous préparant aux modes de défaillance, vous garantissez que vos applications maintiennent leur disponibilité pendant les perturbations volontaires sans intervention manuelle.
Commencez petit : implémentez un PDB pour une charge de travail critique, testez-le soigneusement en staging et intégrez-le à votre pipeline CI/CD. Au fur et à mesure que vous gagnez en confiance, étendez-le à d'autres services. N'oubliez pas de garder le rayon d'impact petit, d'utiliser le moindre privilège et d'avoir toujours un plan de restauration. La sécurité opérationnelle que vous gagnez dépasse de loin l'effort de mise en place.
Prochaines étapes : choisissez une charge de travail à faible risque, créez un PDB avec un minAvailable ou maxUnavailable approprié, appliquez-le via votre pipeline et simulez un drainage pour vérifier le comportement. Documentez vos conclusions et partagez-les avec votre équipe pour construire une culture de la fiabilité.