
Un pod en Pending est un pod accepté par l’API server dont un ou plusieurs
conteneurs n’ont pas encore été créés. Dans la pratique, cela correspond
très souvent à un problème de scheduling (aucun nœud acceptable trouvé),
mais la phase Pending peut aussi couvrir d’autres étapes préalables au
démarrage effectif. Ce guide vous donne une méthodologie en 4 étapes
pour identifier la cause et débloquer la situation.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre pourquoi un pod reste en Pending et ce que fait le scheduler
- Identifier les 7 causes principales d’un pod Pending
- Appliquer une méthodologie de diagnostic reproductible en 4 étapes
- Utiliser
kubectl describe podetkubectl get eventspour trouver la cause réelle - Reproduire et résoudre un pod Pending sur un cluster de test
Prérequis
Section intitulée « Prérequis »- Un cluster Kubernetes fonctionnel (v1.28+)
kubectlconfiguré et connecté au cluster- Des droits de lecture sur les pods, nœuds et événements
- Connaissances de base sur les Pods et le scheduling
Qu’est-ce qu’un pod Pending ?
Section intitulée « Qu’est-ce qu’un pod Pending ? »Pending est une phase officielle du cycle de vie d’un Pod. Elle signifie
que le Pod a été accepté par l’API server, mais qu’un ou plusieurs conteneurs
n’ont pas encore été créés. Cela inclut le temps de scheduling (trouver un
nœud) et le temps de préparation (téléchargement des images, par exemple).
Dans ce guide, nous nous concentrons sur le cas le plus fréquent : le pod
reste bloqué parce que le scheduler ne trouve pas de nœud acceptable.
Le rôle du scheduler
Section intitulée « Le rôle du scheduler »Le scheduler Kubernetes (kube-scheduler) évalue chaque pod en attente et
cherche un nœud qui satisfait toutes les contraintes :
| Contrainte | Ce que le scheduler vérifie |
|---|---|
| Ressources | Le nœud a-t-il assez de CPU et mémoire disponibles (requests) ? |
| Taints/Tolerations | Le pod tolère-t-il les taints du nœud ? |
| Node Selector | Le nœud a-t-il les labels demandés ? |
| Node Affinity | Le nœud correspond-il aux règles d’affinité ? |
| Pod Affinity/Anti-Affinity | Le placement est-il compatible avec les autres pods ? |
| PVC | Le volume demandé est-il disponible dans la même zone ? |
| Topology constraints | Les contraintes de répartition topologique sont-elles respectées ? |
Si aucun nœud ne passe tous les filtres, le pod reste Pending et un
événement FailedScheduling est émis.
Les 7 causes principales
Section intitulée « Les 7 causes principales »Voici les causes les plus fréquentes, classées par ordre de probabilité :
| # | Cause | Symptôme typique | Où chercher |
|---|---|---|---|
| 1 | Ressources insuffisantes | Insufficient cpu ou Insufficient memory | kubectl describe pod → Events |
| 2 | Taint sans toleration | had untolerated taint | kubectl describe pod → Events |
| 3 | Node selector / node affinity impossible | didn't match Pod's node affinity/selector | kubectl describe pod → Events |
| 4 | PVC non lié (unbound PVC) | pod has unbound immediate PersistentVolumeClaims | kubectl describe pod + kubectl get pvc |
| 5 | Pod anti-affinity / topology spread trop stricts | contrainte de placement non satisfaisable | kubectl describe pod → Events |
| 6 | Quota ou admission bloquants | exceeded quota ou refus de création | événements / retour API |
| 7 | Priorité / préemption insuffisante | le scheduler ne peut pas libérer de place utile | kubectl describe pod → Events |
Méthodologie de diagnostic en 4 étapes
Section intitulée « Méthodologie de diagnostic en 4 étapes »-
Identifier les pods Pending
Listez les pods et repérez ceux dont le STATUS est
Pending:Fenêtre de terminal kubectl get pods -A --field-selector=status.phase=PendingSi la commande ne retourne rien mais qu’un pod semble bloqué, vérifiez aussi les événements récents :
Fenêtre de terminal kubectl get events -A --field-selector reason=FailedScheduling --sort-by='.lastTimestamp'Notez le nom du pod, son namespace et depuis combien de temps il est en Pending.
-
Lire les événements du pod
La commande essentielle pour un pod Pending est
kubectl describe pod, section Events :Fenêtre de terminal kubectl describe pod <pod> -n <namespace>Le message de l’événement
FailedSchedulingvous dit exactement pourquoi le scheduler n’a trouvé aucun nœud. Exemples :0/3 nodes are available: 1 node(s) had untolerated taint{node-role.kubernetes.io/control-plane: }, 2 Insufficient memory.Ce message signifie : 3 nœuds évalués, 1 écarté pour taint control-plane, 2 écartés pour manque de mémoire.
0/3 nodes are available: 3 node(s) didn't match Pod's nodeaffinity/selector.Celui-ci signifie : aucun nœud n’a les labels demandés par le
nodeSelectorou lanodeAffinity. -
Croiser avec l’état des nœuds et des ressources
Selon le message d’erreur, vérifiez :
Pour les ressources insuffisantes :
Fenêtre de terminal # Voir la capacité et l'utilisation de chaque nœudkubectl top nodes# Détail des allocations sur un nœudkubectl describe node <node-name> | grep -A10 "Allocated resources"Pour les taints :
Fenêtre de terminal # Voir les taints de chaque nœudkubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taintsPour les labels (nodeSelector/nodeAffinity) :
Fenêtre de terminal # Voir les labels des nœudskubectl get nodes --show-labels# Vérifier un label spécifiquekubectl get nodes -l <label-key>=<label-value>Pour les PVC :
Fenêtre de terminal # Voir l'état des PVC du namespacekubectl get pvc -n <namespace>Un PVC en
Pendingempêche le pod de démarrer — il faut d’abord résoudre le PVC.Pour les quotas :
Fenêtre de terminal # Voir les quotas du namespacekubectl describe resourcequota -n <namespace> -
Corriger et vérifier
Selon la cause identifiée :
Cause Action corrective Ressources insuffisantes Réduire les requestsdu pod, ou ajouter des nœuds au clusterTaint sans toleration Ajouter la tolerationdans le manifeste, ou retirer la taint du nœudNode Selector incorrect Corriger le nodeSelectorou ajouter le label au nœudPVC non lié Créer le PV manquant, vérifier la StorageClass, ou corriger la zone Anti-affinity / topology spread Assouplir les règles ( preferredDuringSchedulingau lieu derequired)Quota / admission Augmenter le quota, ou réduire l’utilisation existante Priorité insuffisante Augmenter la PriorityClassdu pod, ou libérer de la capacitéAprès correction, vérifiez que le pod quitte l’état Pending :
Fenêtre de terminal kubectl get pods -n <namespace> -wLe pod doit passer de
Pending→ContainerCreating→Running.
Exemples pratiques : reproduire un pod Pending
Section intitulée « Exemples pratiques : reproduire un pod Pending »Cas 1 : ressources insuffisantes
Section intitulée « Cas 1 : ressources insuffisantes »Créez un pod qui demande plus de CPU que ce que le cluster peut fournir :
kubectl apply -f- <<'EOF'apiVersion: v1kind: Podmetadata: name: pending-resources namespace: defaultspec: containers: - name: app image: nginx:1.27 resources: requests: cpu: "100" memory: "1Gi"EOFLe pod demande 100 CPU — aucun nœud ne peut satisfaire cette demande.
Diagnostic :
kubectl describe pod pending-resources | tail -10Vous verrez un événement FailedScheduling avec le message
Insufficient cpu.
Solution : réduire les requests.cpu à une valeur réaliste (par exemple
100m pour 0,1 CPU).
Cas 2 : nodeSelector sans correspondance
Section intitulée « Cas 2 : nodeSelector sans correspondance »kubectl apply -f- <<'EOF'apiVersion: v1kind: Podmetadata: name: pending-selector namespace: defaultspec: nodeSelector: disk: ssd-nvme containers: - name: app image: nginx:1.27EOFSi aucun nœud n’a le label disk=ssd-nvme, le pod restera Pending.
Diagnostic :
kubectl describe pod pending-selector | tail -10kubectl get nodes --show-labels | grep ssd-nvmeSolution : ajouter le label au nœud, ou supprimer le nodeSelector :
kubectl label node <node-name> disk=ssd-nvmeCas 3 : taint non tolérée
Section intitulée « Cas 3 : taint non tolérée »kubectl apply -f- <<'EOF'apiVersion: v1kind: Podmetadata: name: pending-taint namespace: defaultspec: containers: - name: app image: nginx:1.27EOFSi tous les nœuds workers ont une taint et que le pod n’a pas la toleration correspondante, il restera Pending.
Reproduisons la situation :
# Ajouter une taint à tous les nœuds workerskubectl taint nodes -l '!node-role.kubernetes.io/control-plane' maintenance=true:NoSchedule
# Vérifier que le pod est Pendingkubectl describe pod pending-taint | tail -10Solution : ajouter la toleration dans le manifeste, ou retirer la taint :
# Retirer la taintkubectl taint nodes -l '!node-role.kubernetes.io/control-plane' maintenance=true:NoSchedule-Cas 4 : PVC non lié
Section intitulée « Cas 4 : PVC non lié »kubectl apply -f- <<'EOF'apiVersion: v1kind: PersistentVolumeClaimmetadata: name: pvc-inexistant namespace: defaultspec: accessModes: ["ReadWriteOnce"] storageClassName: "storage-class-inexistante" resources: requests: storage: 10Gi---apiVersion: v1kind: Podmetadata: name: pending-pvc namespace: defaultspec: containers: - name: app image: nginx:1.27 volumeMounts: - name: data mountPath: /data volumes: - name: data persistentVolumeClaim: claimName: pvc-inexistantEOFLe PVC référence une StorageClass qui n’existe pas — il reste en Pending, et le pod aussi.
Diagnostic :
kubectl get pvc pvc-inexistantkubectl describe pod pending-pvc | tail -10Vous verrez pod has unbound immediate PersistentVolumeClaims.
Nettoyage
Section intitulée « Nettoyage »kubectl delete pod pending-resources pending-selector pending-taint pending-pvc --force --grace-period=0 2>/dev/nullkubectl delete pvc pvc-inexistant 2>/dev/nullkubectl taint nodes -l '!node-role.kubernetes.io/control-plane' maintenance=true:NoSchedule- 2>/dev/nullCas particuliers
Section intitulée « Cas particuliers »Pending prolongé après un scale-up
Section intitulée « Pending prolongé après un scale-up »Quand un Deployment augmente son nombre de replicas, le scheduler traite les
pods un par un. Si le cluster est proche de la saturation, les premiers pods
sont placés mais les derniers restent Pending. Les événements montrent
Insufficient cpu ou Insufficient memory.
Si vous utilisez un mécanisme d’autoscaling des nœuds (Cluster Autoscaler, Karpenter…), les pods Pending peuvent déclencher l’ajout de capacité automatiquement. Le délai dépend fortement de l’implémentation et de l’infrastructure sous-jacente.
Pending à cause d’un PodDisruptionBudget
Section intitulée « Pending à cause d’un PodDisruptionBudget »Un PDB ne cause pas directement un pod Pending. Mais lors d’un drain de nœud, si le PDB empêche l’éviction, les pods restent sur le nœud drainé et les nouveaux pods créés pour les remplacer peuvent rester Pending par manque de ressources sur les nœuds restants.
Pending avec topologySpreadConstraints
Section intitulée « Pending avec topologySpreadConstraints »Si vous avez défini des contraintes de répartition topologique
(topologySpreadConstraints) avec whenUnsatisfiable: DoNotSchedule, le
scheduler refuse de placer le pod si la répartition ne peut pas être
respectée. Les événements indiqueront les contraintes non satisfaites.
Dépannage rapide
Section intitulée « Dépannage rapide »| Symptôme | Première action | Commande |
|---|---|---|
Pending + Insufficient cpu/memory | Vérifier les allocations nœuds | kubectl describe node <node> → Allocated resources |
Pending + untolerated taint | Vérifier les taints | kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints |
Pending + didn't match node affinity/selector | Vérifier les labels nœuds | kubectl get nodes --show-labels |
Pending + unbound PersistentVolumeClaims | Vérifier le PVC | kubectl get pvc -n <namespace> |
Pending + exceeded quota | Vérifier le ResourceQuota | kubectl describe resourcequota -n <namespace> |
Pending + aucun event | Scheduler en panne ? | kubectl get pods -n kube-system -l component=kube-scheduler |
| Pod disparaît au lieu de rester Pending | Vérifier si un webhook le supprime | kubectl get events -n <namespace> --sort-by='.lastTimestamp' |
À retenir
Section intitulée « À retenir »Pendingsignifie qu’un ou plusieurs conteneurs n’ont pas encore été créés — dans la plupart des cas, c’est parce que le scheduler n’a pas trouvé de nœud acceptablekubectl describe podest la commande clé — la section Events contient le messageFailedSchedulingqui explique exactement ce qui bloqueInsufficient cpu/memoryest la cause la plus fréquente — vérifiez lesrequestsdu pod et lesAllocated resourcesdes nœuds- Les taints bloquent silencieusement : un nœud peut avoir de la capacité mais refuser le pod s’il n’a pas la bonne toleration
- Un PVC non lié bloque le pod — résolvez d’abord le PVC (StorageClass absente, pas de PV disponible, mauvaise zone)
- Sur un cluster avec PodPriority, un pod peut rester Pending si sa priorité est trop faible pour déclencher une préemption utile
- Après correction, le pod doit transiter de
Pending→ContainerCreating→Running - Mettez en place une alerte sur les pods Pending prolongé — c’est un symptôme fiable de problème de capacité ou de configuration