
Pour intervenir sur un nœud Kubernetes sans couper le service, suivez
toujours le même workflow : cordon → drain → intervention → uncordon.
Ce guide détaille chaque étape, explique comment les PodDisruptionBudgets
protègent vos applications pendant l’opération, et couvre les cas
particuliers (DaemonSets, pods orphelins, volumes locaux).
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Appliquer le workflow complet de maintenance d’un nœud Kubernetes
- Comprendre la différence entre cordon (bloquer le scheduling) et drain (évacuer les pods)
- Configurer un PodDisruptionBudget pour protéger vos applications pendant le drain
- Gérer les cas particuliers : DaemonSets, pods sans contrôleur, données locales (emptyDir)
- Vérifier que le service est restauré après la maintenance
Prérequis
Section intitulée « Prérequis »- Un cluster Kubernetes fonctionnel (v1.28+)
kubectlconfiguré avec des droits suffisants pour gérer les nœuds (cordon, drain, uncordon)- Des droits pour créer des PodDisruptionBudgets
- Avoir suivi le guide Observer la santé du cluster
- Connaissances de base sur les Deployments et les Services
Pourquoi un workflow de maintenance ?
Section intitulée « Pourquoi un workflow de maintenance ? »Sur un serveur classique, on peut se permettre de rebooter directement. Sur Kubernetes, un nœud héberge potentiellement des dizaines de pods qui servent du trafic en production. Un redémarrage brutal provoque :
- Des coupures de service si les pods n’ont pas de réplicas sur d’autres nœuds
- Des pertes de données si les pods utilisent des volumes locaux (emptyDir)
- Des alertes inutiles dans le monitoring
Le workflow cordon → drain → uncordon résout ces trois problèmes en
évacuant proprement les pods avant l’intervention.
Vue d’ensemble du workflow
Section intitulée « Vue d’ensemble du workflow »| Étape | Commande | Ce qui se passe |
|---|---|---|
| 1. Bloquer le scheduling | kubectl cordon <noeud> | Le nœud est marqué SchedulingDisabled — plus aucun nouveau pod n’y sera planifié |
| 2. Évacuer les pods | kubectl drain <noeud> | Les pods sont évincés via l’API d’éviction, en respectant les PDB |
| 3. Intervenir | (reboot, mise à jour, réparation) | Le nœud est vide, vous pouvez intervenir en sécurité |
| 4. Remettre en service | kubectl uncordon <noeud> | Le nœud redevient Ready et accepte de nouveaux pods |
Étape 1 : bloquer le scheduling avec cordon
Section intitulée « Étape 1 : bloquer le scheduling avec cordon »La commande kubectl cordon marque le nœud comme SchedulingDisabled. Les
pods déjà présents continuent de tourner, mais le scheduler ne placera plus
de nouveaux pods sur ce nœud. Les DaemonSets sont une exception : leurs
pods ignorent l’état SchedulingDisabled et continuent de fonctionner
normalement sur le nœud.
kubectl cordon <nom-du-noeud>Vérification :
kubectl get nodesNAME STATUS ROLES AGE VERSIONks-cp1 Ready control-plane 42h v1.34.3ks-worker1 Ready,SchedulingDisabled <none> 42h v1.34.3ks-worker2 Ready <none> 42h v1.34.3Le nœud ks-worker1 affiche SchedulingDisabled dans la colonne STATUS.
Comprendre les PodDisruptionBudgets (PDB) avant le drain
Section intitulée « Comprendre les PodDisruptionBudgets (PDB) avant le drain »Avant de drainer un nœud, vérifiez les PodDisruptionBudgets en place. Un PDB définit le nombre minimum de pods d’une application qui doivent rester disponibles pendant une disruption volontaire (comme un drain).
Qu’est-ce qu’un PDB ?
Section intitulée « Qu’est-ce qu’un PDB ? »Un PDB protège une application en disant à Kubernetes : “ne supprime pas
plus de X pods à la fois”. Pendant un kubectl drain, l’API d’éviction
respecte ces budgets et bloque le drain si l’éviction violerait le PDB.
Exemple : un Deployment avec 3 réplicas et un PDB minAvailable: 2
signifie que le drain ne pourra évacuer qu’un seul pod de cette
application à la fois. Les deux autres doivent rester disponibles.
Créer un PDB
Section intitulée « Créer un PDB »apiVersion: policy/v1kind: PodDisruptionBudgetmetadata: name: mon-app-pdb namespace: defaultspec: minAvailable: 2 selector: matchLabels: app: mon-appLes deux options principales :
| Champ | Signification | Exemple |
|---|---|---|
minAvailable | Nombre minimum (ou %) de pods qui doivent rester disponibles | 2 ou "50%" |
maxUnavailable | Nombre maximum (ou %) de pods qui peuvent être indisponibles | 1 ou "25%" |
Vérifier les PDB existants
Section intitulée « Vérifier les PDB existants »kubectl get pdb -ANAMESPACE NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGEdefault mon-app-pdb 2 N/A 1 5mLa colonne ALLOWED DISRUPTIONS indique combien de pods peuvent encore
être évincés sans violer le budget. Si elle affiche 0, le drain sera
bloqué pour cette application.
Étape 2 : évacuer les pods avec drain
Section intitulée « Étape 2 : évacuer les pods avec drain »La commande kubectl drain combine deux actions :
cordonle nœud (si pas déjà fait)- Évacue tous les pods via l’API d’éviction (qui respecte les PDB)
Commande de base
Section intitulée « Commande de base »kubectl drain <nom-du-noeud> --ignore-daemonsets --delete-emptydir-dataLes deux flags les plus courants :
| Flag | Pourquoi |
|---|---|
--ignore-daemonsets | Les pods DaemonSet ne peuvent pas être déplacés (ils existent sur chaque nœud par définition). Sans ce flag, drain refuse de continuer. |
--delete-emptydir-data | Autorise la suppression de pods qui utilisent emptyDir (volumes locaux éphémères). À utiliser uniquement si vous acceptez la perte de ces données. |
Options utiles
Section intitulée « Options utiles »| Flag | Usage |
|---|---|
--timeout=300s | Durée maximale d’attente (défaut : infini) |
--grace-period=30 | Durée de terminaison gracieuse par pod |
--force | Supprime les pods sans contrôleur (orphelins) |
--dry-run=client | Simule le drain sans rien exécuter |
--pod-selector=app=X | Ne draine que les pods correspondant au sélecteur |
Simuler le drain avant de l’exécuter
Section intitulée « Simuler le drain avant de l’exécuter »Commencez toujours par un dry-run pour voir ce qui sera impacté :
kubectl drain <nom-du-noeud> --ignore-daemonsets --delete-emptydir-data --dry-run=clientCette commande liste les pods qui seraient évacués sans rien modifier.
Exécuter le drain
Section intitulée « Exécuter le drain »kubectl drain <nom-du-noeud> --ignore-daemonsets --delete-emptydir-dataRésultat attendu :
node/ks-worker1 cordonedevicting pod default/mon-app-xyz-abcevicting pod kube-system/coredns-5d78c9869d-abcpod/mon-app-xyz-abc evictedpod/coredns-5d78c9869d-abc evictednode/ks-worker1 drainedKubernetes replanifie automatiquement les pods évincés sur les nœuds restants (si les ressources le permettent).
Cas particuliers du drain
Section intitulée « Cas particuliers du drain »Pods sans contrôleur (orphelins) : si un pod n’est géré par aucun
Deployment, ReplicaSet, StatefulSet, DaemonSet ou Job, drain refuse de le
supprimer car il ne sera pas recréé. Utilisez --force en dernier recours
(le pod sera définitivement supprimé).
Pods StatefulSet : ils sont supprimés un à un (pas en parallèle) et recréés dans l’ordre par le contrôleur StatefulSet. Vérifiez que les PVC (PersistentVolumeClaims) sont accessibles depuis les autres nœuds.
Pods avec emptyDir : les données dans emptyDir sont perdues quand le
pod est évincé. Si ces données sont importantes, sauvegardez-les avant le
drain ou migrez vers un PersistentVolume.
Pods avec stockage local attaché au nœud (hostPath, local PV) : ces
pods sont liés à un nœud précis. Après éviction, le scheduler ne pourra
pas les replanifier sur un autre nœud (le volume n’y est pas accessible).
Pour ces workloads, prévoyez soit un retour sur le même nœud après
maintenance, soit une migration vers un PersistentVolume réseau (NFS,
Ceph, cloud provider).
Étape 3 : intervenir sur le nœud
Section intitulée « Étape 3 : intervenir sur le nœud »Le nœud est maintenant vide (sauf les DaemonSets). Vous pouvez :
- Redémarrer le nœud (
sudo reboot) - Mettre à jour le système (
apt upgrade,dnf update) - Mettre à jour le kubelet et les composants Kubernetes
- Réparer un problème matériel ou de disque
- Changer la configuration du kubelet
Pendant l’intervention, vérifiez que les pods évincés sont bien replanifiés sur les autres nœuds :
kubectl get pods -A -o wide | grep -v RunningSi des pods sont en Pending, c’est que les nœuds restants manquent de
ressources.
Étape 4 : remettre le nœud en service avec uncordon
Section intitulée « Étape 4 : remettre le nœud en service avec uncordon »Après l’intervention, remettez le nœud en service :
kubectl uncordon <nom-du-noeud>Vérification :
kubectl get nodesLe nœud doit afficher Ready (sans SchedulingDisabled).
Exemple pratique complet
Section intitulée « Exemple pratique complet »Voici le workflow complet pour une maintenance du nœud ks-worker1 :
-
Vérifier l’état initial du cluster
Fenêtre de terminal kubectl get nodeskubectl get pods -A -o wide --field-selector spec.nodeName=ks-worker1Notez les pods présents sur le nœud pour vérifier ensuite qu’ils ont bien été replanifiés.
-
Vérifier les PDB existants
Fenêtre de terminal kubectl get pdb -ASi
ALLOWED DISRUPTIONSest à0pour une application, le drain sera bloqué. Assurez-vous que les réplicas sont suffisants. -
Simuler le drain
Fenêtre de terminal kubectl drain ks-worker1 --ignore-daemonsets --delete-emptydir-data --dry-run=clientVérifiez la liste des pods qui seront évincés. Si un pod sans contrôleur apparaît, décidez s’il est acceptable de le perdre (ajoutez
--forcesi oui). -
Exécuter le drain
Fenêtre de terminal kubectl drain ks-worker1 --ignore-daemonsets --delete-emptydir-dataAttendez que tous les pods soient évincés. Si le drain bloque, vérifiez les PDB et les ressources sur les autres nœuds.
-
Vérifier que les pods sont replanifiés
Fenêtre de terminal kubectl get pods -A -o wide | grep -v RunningTous les pods doivent être
Runningsur d’autres nœuds (sauf ceux en cours de démarrage). -
Intervenir sur le nœud
Effectuez la maintenance prévue (reboot, mise à jour, réparation).
-
Remettre le nœud en service
Fenêtre de terminal kubectl uncordon ks-worker1 -
Vérifier le retour à la normale
Fenêtre de terminal kubectl get nodeskubectl top nodesLe nœud doit être
Readyet les ressources CPU/mémoire doivent revenir à des niveaux normaux au fur et à mesure que le scheduler lui assigne de nouveaux pods.
Disruptions volontaires et involontaires
Section intitulée « Disruptions volontaires et involontaires »Kubernetes distingue deux types de disruptions :
| Type | Exemples | Protégé par les PDB ? |
|---|---|---|
| Volontaire | kubectl drain, suppression d’un Deployment, mise à jour rolling | Oui |
| Involontaire | Panne matérielle, kernel panic, nœud qui disparaît du réseau | Non (mais comptabilisé dans le budget) |
Les PDB ne protègent que contre les disruptions volontaires. Une panne
matérielle évincera les pods sans consulter les PDB. Cependant, les
disruptions involontaires comptent quand même dans le budget
disponible : si un pod tombe à cause d’une panne, ALLOWED DISRUPTIONS
diminue, ce qui peut bloquer un drain ultérieur. C’est pourquoi il est
important de combiner PDB avec des réplicas suffisants et de l’anti-affinité
pour répartir les pods sur plusieurs nœuds.
Dépannage rapide
Section intitulée « Dépannage rapide »| Symptôme | Cause probable | Solution |
|---|---|---|
drain bloqué indéfiniment | PDB avec ALLOWED DISRUPTIONS: 0 | Vérifier les réplicas et les ressources sur les autres nœuds |
cannot delete Pods not managed by... | Pod orphelin (sans contrôleur) | Ajouter --force si le pod peut être perdu |
cannot delete DaemonSet-managed Pods | DaemonSet détecté | Ajouter --ignore-daemonsets |
cannot delete Pods with local storage | Pod avec emptyDir | Ajouter --delete-emptydir-data (les données seront perdues) |
Pods en Pending après drain | Pas assez de ressources sur les autres nœuds | Ajouter un nœud ou réduire les requests |
Nœud reste SchedulingDisabled après uncordon | uncordon pas exécuté ou erreur | Relancer kubectl uncordon <noeud> |
| PVC inaccessible après éviction | Volume local (hostPath/local PV) | Replanifier le pod sur le même nœud ou migrer vers un PV réseau |
À retenir
Section intitulée « À retenir »- Le workflow est toujours le même :
cordon→drain→ intervention →uncordon. Ne sautez jamais le drain pour gagner du temps kubectl drainutilise l’API d’éviction qui respecte les PodDisruptionBudgets — c’est ce qui protège vos applications--ignore-daemonsetsest souvent nécessaire, cardrainrefuse d’évacuer les pods DaemonSet.--delete-emptydir-datane doit être utilisé que si vous acceptez explicitement la perte des données stockées dansemptyDir- Faites toujours un
--dry-run=clientavant le drain réel pour voir quels pods seront impactés - Les pods évincés ne reviennent pas automatiquement sur le nœud après
uncordon— seuls les nouveaux pods ou ceux en Pending y seront planifiés - Un PDB avec
minAvailable: 1sur un Deployment à 1 réplica bloquera le drain indéfiniment — assurez-vous que vos applications critiques ont au moins 2 réplicas - Vérifiez les ressources sur les autres nœuds avant de drainer : si les pods ne peuvent pas être replanifiés, ils resteront en Pending