Un guide étape par étape pour créer un environnement Kubernetes local sécurisé afin de tester les budgets de perturbation de pods.
Introduction
Les budgets de perturbation de pods (Pod Disruption Budgets, PDB) Kubernetes sont essentiels pour maintenir la disponibilité des applications lors de perturbations volontaires telles que la maintenance des nœuds, les mises à niveau du cluster ou la réduction du nombre de nœuds. Ils permettent de spécifier le nombre minimal de pods qui doivent rester disponibles ou le nombre maximal pouvant être indisponibles pendant ces opérations. Cependant, des PDB mal configurés peuvent provoquer des temps d'arrêt inattendus ou bloquer entièrement la maintenance. Tester les PDB en production est risqué et peut entraîner des interruptions de service. Un laboratoire local offre un environnement sûr et isolé pour expérimenter, comprendre le comportement des PDB et élaborer des configurations fiables avant de les déployer en production.
Ce guide vous explique comment configurer un cluster Kubernetes local à l'aide de minikube, déployer une application d'exemple, créer un PDB et observer ses effets grâce à des simulations de drainage de nœuds. À la fin, vous disposerez d'un flux de travail reproductible pour tester les PDB et d'une solide compréhension de la façon de les configurer correctement pour vos charges de travail.
Inventaire des versions et de l'environnement
Avant de commencer, assurez-vous que votre environnement local répond aux prérequis suivants. Nous utiliserons les dernières versions stables au moment de la rédaction, mais toute version récente devrait fonctionner de manière similaire.
- Système d'exploitation : Tout système pris en charge par minikube (Windows, macOS, Linux).
- Hyperviseur : VirtualBox ou un hyperviseur natif (par exemple, Hyper-V, HyperKit, KVM).
- minikube : v1.30.1 ou version ultérieure.
- kubectl : v1.28 ou version ultérieure.
Vérifiez les installations en exécutant les commandes suivantes :
minikube version
# Exemple de sortie : minikube version: v1.30.1
kubectl version --client
# Exemple de sortie : Client Version: v1.28.2
Démarrez un cluster minikube avec suffisamment de ressources. Cet exemple utilise VirtualBox comme pilote :
minikube start --driver=virtualbox --cpus=2 --memory=4096
Cela crée un cluster à nœud unique. Confirmez que le nœud est prêt :
kubectl get nodes
# Exemple de sortie :
# NAME STATUS ROLES AGE VERSION
# minikube Ready control-plane 30s v1.28.3
Une fois que le nœud est Ready, vous pouvez procéder au déploiement d'une application d'exemple.
Chemin de configuration sécurisé
Nous allons créer un déploiement simple, puis définir un PDB pour le protéger. Cette approche délimitée garantit que nous pouvons isoler les effets et observer clairement comment les PDB influencent les perturbations volontaires.
Étape 1 : Créer un déploiement
Créez un fichier nommé app-deployment.yaml avec le contenu suivant :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
Cela déploie deux répliques d'un pod nginx. Avoir plusieurs répliques est crucial pour démontrer l'effet des PDB sur la disponibilité lors de perturbations.
Appliquez le déploiement :
kubectl apply -f app-deployment.yaml
# Sortie attendue : deployment.apps/nginx-deployment created
Vérifiez que les pods sont en cours d'exécution :
kubectl get pods -l app=nginx
# Exemple de sortie :
# NAME READY STATUS RESTARTS AGE
# nginx-deployment-6c9f8b8b7c-abcde 1/1 Running 0 10s
# nginx-deployment-6c9f8b8b7c-fghij 1/1 Running 0 10s
Étape 2 : Créer un budget de perturbation de pods
Créez maintenant un PDB qui garantit qu'au moins un pod reste disponible en tout temps. Créez un fichier nommé nginx-pdb.yaml :
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: nginx-pdb
spec:
minAvailable: 1
selector:
matchLabels:
app: nginx
Ce PDB spécifie qu'au moins un pod avec l'étiquette app: nginx doit être disponible pendant les perturbations volontaires. Comme nous avons deux répliques, cela permet au plus un pod d'être perturbé à tout moment.
Appliquez le PDB :
kubectl apply -f nginx-pdb.yaml
# Sortie attendue : poddisruptionbudget.policy/nginx-pdb created
Vérifiez l'état du PDB :
kubectl get pdb nginx-pdb
# Exemple de sortie :
# NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
# nginx-pdb 1 N/A 1 5s
Explication de la sortie :
- MIN AVAILABLE : 1 (comme spécifié).
- MAX UNAVAILABLE : N/A car nous avons utilisé
minAvailable. - ALLOWED DISRUPTIONS : 1, ce qui signifie qu'un pod peut être évincé volontairement sans violer le budget. Ceci est calculé en fonction du nombre actuel de pods sains.
Vérification et diagnostics
Pour vérifier que le PDB fonctionne comme prévu, nous allons simuler une perturbation volontaire en drainant le nœud. Le drainage d'un nœud tente d'évincer tous les pods, en respectant les PDB. Si le PDB empêche suffisamment d'évictions, le drainage échouera ou expirera, démontrant ainsi la protection en action.
Étape 1 : Vérifier les pods actuels
Tout d'abord, listez les pods et notez le nœud sur lequel ils s'exécutent :
kubectl get pods -o wide
# Exemple de sortie :
# NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
# nginx-deployment-6c9f8b8b7c-abcde 1/1 Running 0 10m 10.244.0.5 minikube <none> <none>
# nginx-deployment-6c9f8b8b7c-fghij 1/1 Running 0 10m 10.244.0.6 minikube <none> <none>
Les deux pods se trouvent sur le nœud unique minikube.
Étape 2 : Tenter de drainer le nœud
Exécutez la commande de drainage avec les indicateurs appropriés. Comme minikube exécute des daemonsets système, nous utilisons --ignore-daemonsets. Nous ajoutons également --delete-emptydir-data pour permettre la suppression des volumes emptyDir. Pour éviter de bloquer indéfiniment, nous ajoutons un délai d'attente de 10 secondes :
kubectl drain minikube --ignore-daemonsets --delete-emptydir-data --timeout=10s
Comportement attendu : La commande de drainage échouera ou expirera, car l'éviction d'un des deux pods laisserait moins de pods en cours d'exécution que minAvailable=1. La sortie ressemblera à ceci :
node/minikube cordoned
error: unable to drain node "minikube", aborting command...
There are pending nodes to be drained:
minikube
error: cannot delete Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet (use --force to override): default/nginx-deployment-6c9f8b8b7c-abcde
error: cannot delete Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet (use --force to override): default/nginx-deployment-6c9f8b8b7c-fghij
Remarque : Le message d'erreur « cannot delete Pods not managed by... » peut apparaître si les pods ne sont pas gérés par un contrôleur, mais dans notre cas, ils sont gérés par un ReplicaSet, donc cette erreur spécifique peut être trompeuse. Il est plus probable que le drainage évince un pod, et que le ReplicaSet crée un remplaçant. Cependant, comme le nœud est « cordonné », le pod de remplacement ne peut pas être planifié et reste donc à l'état « Pending ». Le drainage tente ensuite d'évincer le deuxième pod, mais cela violerait le PDB puisque le pod de remplacement n'est pas encore « Ready ». Le drainage expire alors. Les messages d'erreur exacts peuvent varier, mais l'essentiel est que le drainage ne se termine pas correctement.
Après le délai d'attente, vérifiez les pods :
kubectl get pods
# Exemple de sortie :
# NAME READY STATUS RESTARTS AGE
# nginx-deployment-6c9f8b8b7c-abcde 1/1 Running 0 15m
# nginx-deployment-6c9f8b8b7c-fghij 1/1 Running 0 15m
# nginx-deployment-6c9f8b8b7c-newpod 0/1 Pending 0 1m
Vous pouvez voir un pod encore Running, un pod Pending (le remplaçant), et peut-être le deuxième pod d'origine encore Running si l'éviction n'a pas été terminée. L'état exact dépend du moment, mais le drainage ne devrait pas réussir.
Étape 3 : Inspecter l'état du PDB
Pour plus de détails, inspectez le PDB en YAML :
kubectl get pdb nginx-pdb -o yaml
Dans la sortie, recherchez la section status :
status:
currentHealthy: 2
desiredHealthy: 1
disruptionsAllowed: 1
expectedPods: 2
observedGeneration: 1
currentHealthy: 2 pods sains actuellement.desiredHealthy: 1 (la valeur deminAvailable).disruptionsAllowed: 1, confirmant qu'au plus un pod peut être perturbé. Comme le drainage a tenté d'évincer plus d'un pod, il a été bloqué.
Étape 4 : Démontrer une perturbation réussie dans les limites du budget
Pour montrer que le PDB autorise les perturbations jusqu'à la limite autorisée, vous pouvez supprimer manuellement un pod :
kubectl delete pod nginx-deployment-6c9f8b8b7c-abcde
# Sortie : pod "nginx-deployment-6c9f8b8b7c-abcde" deleted
Le pod est supprimé, mais le ReplicaSet crée immédiatement un nouveau pod pour maintenir le nombre de répliques souhaité. Vérifiez les pods après quelques secondes :
kubectl get pods
# Exemple de sortie :
# NAME READY STATUS RESTARTS AGE
# nginx-deployment-6c9f8b8b7c-fghij 1/1 Running 0 20m
# nginx-deployment-6c9f8b8b7c-xyzab 1/1 Running 0 5s
Les deux pods sont en cours d'exécution et le nouveau pod est sain. Cette suppression manuelle est autorisée, car elle reste dans la limite disruptionsAllowed de 1 du PDB.
Si vous tentez à nouveau un drainage, il sera toujours bloqué, car le drainage évince les pods un par un. Après la première éviction, le pod de remplacement ne peut pas être planifié en raison du cordon, donc le PDB ne voit qu'un seul pod sain et interdit d'autres évictions.
Modes de défaillance et récupération
Les mauvaises configurations peuvent entraîner des comportements non souhaités. Voici les modes de défaillance courants et les étapes de récupération.
1. PDB avec minAvailable supérieur au nombre de répliques
Si vous définissez minAvailable: 3 pour un déploiement avec seulement 2 répliques, le PDB n'autorisera jamais aucune perturbation volontaire, car le nombre sain souhaité dépasse le nombre total de pods. Le drainage sera entièrement bloqué, comme l'indique la valeur disruptionsAllowed: 0 dans l'état du PDB.
Récupération : Modifiez le PDB pour une valeur valide, par exemple minAvailable: 1 ou maxUnavailable: 1 :
kubectl edit pdb nginx-pdb
Modifiez la valeur de minAvailable, enregistrez et quittez. Le PDB sera mis à jour et disruptionsAllowed devrait devenir approprié.
2. Le sélecteur du PDB ne correspond à aucun pod
Si les étiquettes du sélecteur ne correspondent pas aux étiquettes des pods, le PDB n'aura aucun pod associé. Dans ce cas, l'état du PDB affichera currentHealthy: 0 et desiredHealthy: 1 (ou votre valeur), et disruptionsAllowed sera 0 parce qu'aucun pod n'est protégé, mais le PDB autorise en réalité toute perturbation, car il n'y a aucun pod à protéger. Le drainage réussira, ce qui peut être inattendu si vous pensiez que le PDB protégeait votre charge de travail.
Récupération : Vérifiez l'état du PDB :
kubectl get pdb nginx-pdb -o yaml
Recherchez status.currentHealthy. S'il vaut 0, le sélecteur est probablement incorrect. Corrigez le sélecteur dans le YAML du PDB pour qu'il corresponde aux étiquettes des pods, puis appliquez.
3. Annuler une modification de PDB
Si une modification de PDB cause des problèmes, vous pouvez revenir en arrière en appliquant une version précédente du fichier YAML ou en supprimant entièrement le PDB :
kubectl delete pdb nginx-pdb
# Sortie : poddisruptionbudget.policy "nginx-pdb" deleted
Recréez ensuite avec les paramètres corrects en utilisant kubectl apply -f nginx-pdb.yaml.
4. Drainage de nœud bloqué en raison du PDB
Si une commande de drainage reste bloquée ou si vous devez l'annuler, vous pouvez « décordonner » le nœud pour permettre aux pods d'être à nouveau planifiés :
kubectl uncordon minikube
# Sortie : node/minikube uncordoned
Résolvez ensuite le problème de PDB et réessayez le drainage si nécessaire.
Testez toujours les modifications de PDB dans un laboratoire avant de les appliquer en production.
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour chaque session de laboratoire PDB afin de garantir cohérence et sécurité.
- [ ] Vérifiez les versions de minikube et kubectl ; démarrez le cluster si nécessaire :
minikube start --driver=virtualbox. - [ ] Confirmez que le nœud est
Ready:kubectl get nodes. - [ ] Appliquez un déploiement de test avec un nombre connu de répliques (par ex., 2) à l'aide d'un fichier YAML.
- [ ] Créez un PDB avec une valeur claire de
minAvailableoumaxUnavailable; documentez la valeur choisie. - [ ] Vérifiez l'état du PDB :
kubectl get pdbet vérifiez queALLOWED DISRUPTIONSest conforme aux attentes. - [ ] Tentez un drainage avec les indicateurs :
kubectl drain minikube --ignore-daemonsets --delete-emptydir-data --timeout=10s. - [ ] Observez si le drainage réussit ou est bloqué ; vérifiez les journaux pour en connaître les raisons.
- [ ] Si le drainage est bloqué, vérifiez que les pods sont toujours en cours d'exécution et que la valeur
disruptionsAlloweddu PDB correspond au budget. - [ ] Testez la suppression d'un seul pod :
kubectl delete pod [pod-name]et confirmez qu'elle est autorisée et qu'un pod de remplacement est créé. - [ ] Nettoyez après les tests : supprimez le PDB et le déploiement pour éviter les fuites de ressources :
kubectl delete pdb nginx-pdb; kubectl delete deployment nginx-deployment.
Le respect de cette liste rendra vos tests de PDB reproductibles et fiables.
Conclusion
La mise en place d'un laboratoire local de budget de perturbation de pods Kubernetes offre un moyen pratique de comprendre comment les PDB protègent la disponibilité des applications lors de perturbations volontaires. En suivant ce guide, vous avez créé un cluster minikube, déployé une application, défini un PDB et testé son comportement lors du drainage d'un nœud. Vous avez également appris à diagnostiquer et à récupérer des erreurs de configuration courantes.
Les principaux points à retenir sont les suivants :
- Commencez par une configuration petite et délimitée pour isoler les effets du PDB.
- Vérifiez l'état du PDB avant et après les perturbations à l'aide de
kubectl get pdbetkubectl describe pdb. - Simulez les perturbations en toute sécurité avec
kubectl drainet des délais d'attente. - Sachez comment récupérer des défaillances, notamment en modifiant ou supprimant des PDB et en décordonnant des nœuds.
Ce laboratoire sert de base pour élaborer des stratégies PDB robustes pour la production. Entraînez-vous avec différentes configurations, par exemple en utilisant maxUnavailable au lieu de minAvailable, et testez avec des applications avec état pour approfondir votre compréhension. Validez toujours les modifications de PDB dans un environnement hors production avant de garantir la résilience de l'application lors des maintenances planifiées.