Contactez-nous

Pod en état `Pending` : causes courantes (ressources, noeud indisponible)

Diagnostiquez et résolvez pourquoi vos Pods Kubernetes restent bloqués en état Pending. Explorez les causes : manque de ressources, noeuds indisponibles, contraintes.

Comprendre l'état `Pending` d'un Pod

L'un des premiers obstacles que vous pourriez rencontrer en déployant des applications sur Kubernetes est de voir un Pod rester indéfiniment dans l'état `Pending`. Cet état signifie simplement que le Pod a été accepté par le cluster Kubernetes, mais qu'il n'a pas encore pu être programmé (schedulé) sur un Noeud (Node) approprié, ou qu'un ou plusieurs de ses conteneurs n'ont pas encore pu être démarrés pour d'autres raisons préliminaires (comme le montage de volumes).

Bien que potentiellement frustrant, l'état `Pending` est un indicateur clair qu'une condition nécessaire à l'exécution du Pod n'est pas remplie. Heureusement, Kubernetes fournit des outils pour diagnostiquer la cause exacte. La commande `kubectl describe pod ` est votre alliée principale dans cette situation, car elle révèle souvent la raison du blocage dans sa section `Events`.

Ce sous-chapitre explore les raisons les plus fréquentes pour lesquelles un Pod peut se retrouver bloqué en état `Pending`, en se concentrant notamment sur les problèmes liés aux ressources et à la disponibilité des noeuds, et vous montre comment identifier et résoudre ces problèmes.

Cause n°1 : Ressources insuffisantes (CPU/Mémoire)

La cause la plus fréquente d'un Pod en état `Pending` est le manque de ressources disponibles sur les Noeuds du cluster. Lorsque vous définissez un Pod, vous pouvez (et devriez) spécifier des requêtes de ressources (`requests`) pour le CPU et la mémoire dont chaque conteneur a besoin. Le planificateur Kubernetes (kube-scheduler) utilise ces requêtes pour trouver un Noeud capable d'allouer ces ressources.

Si aucun Noeud du cluster ne dispose de suffisamment de ressources *non allouées* (CPU ou mémoire) pour satisfaire les requêtes du Pod, celui-ci restera en état `Pending` jusqu'à ce que des ressources se libèrent ou que de nouvelles ressources soient ajoutées (par exemple, en ajoutant un Noeud).

Pour diagnostiquer ce problème, utilisez `kubectl describe pod `. Recherchez dans la section `Events` des messages similaires à :

Warning FailedScheduling 2m kube-scheduler 0/3 nodes are available: 3 Insufficient cpu.
Warning FailedScheduling 1m kube-scheduler 0/3 nodes are available: 1 Insufficient memory, 2 Insufficient cpu.

Ces messages indiquent clairement que les Noeuds disponibles n'ont pas assez de CPU ou de mémoire libre pour accueillir le Pod. Les solutions possibles incluent :

  • Ajouter de nouveaux Noeuds au cluster.
  • Augmenter les ressources (CPU/mémoire) des Noeuds existants.
  • Réduire les requêtes de ressources (`spec.containers[].resources.requests`) du Pod si elles sont surestimées.
  • Arrêter d'autres Pods moins prioritaires pour libérer des ressources.
  • Optimiser l'utilisation des ressources par vos applications.
  • Vérifier les `LimitRanges` et `ResourceQuotas` définis dans le namespace, qui pourraient également restreindre l'allocation.

Cause n°2 : Contraintes de planification non satisfaites

Kubernetes offre plusieurs mécanismes pour contraindre le placement des Pods sur des Noeuds spécifiques : `nodeSelector`, `nodeAffinity`, `podAffinity` et `podAntiAffinity`. Ces règles permettent d'exprimer des préférences ou des exigences pour la planification (par exemple, "ce Pod doit tourner sur un Noeud avec un GPU" ou "ces deux Pods ne doivent pas tourner sur le même Noeud").

Si les contraintes définies pour un Pod sont trop restrictives ou si aucun Noeud ne correspond actuellement aux critères spécifiés, le Pod restera en `Pending`. Par exemple, si vous utilisez un `nodeSelector` qui exige un label `disktype=ssd` et qu'aucun Noeud n'a ce label, le Pod ne sera jamais planifié.

Encore une fois, `kubectl describe pod ` vous aidera. Les événements typiques ressemblent à ceci :

Warning FailedScheduling 3m kube-scheduler 0/4 nodes are available: 4 node(s) didn't match node selector.
Warning FailedScheduling 2m kube-scheduler 0/4 nodes are available: 3 node(s) didn't match pod affinity rules, 1 node(s) had untolerated taint {key: value}.
Warning FailedScheduling 1m kube-scheduler 0/4 nodes are available: 2 node(s) didn't match pod anti-affinity rules.

Pour résoudre ce problème :

  • Vérifiez attentivement les règles `nodeSelector`, `affinity` et `anti-affinity` dans la définition du Pod (`spec.affinity`, `spec.nodeSelector`).
  • Assurez-vous que les Noeuds ciblés possèdent bien les labels requis (`kubectl get nodes --show-labels`).
  • Si nécessaire, ajustez les règles pour les rendre moins restrictives ou ajoutez/modifiez les labels sur les Noeuds appropriés.

Cause n°3 : Taints et Tolérances (Taints and Tolerations)

Les Taints sont des marqueurs appliqués aux Noeuds pour indiquer qu'ils ne devraient pas accepter de Pods qui ne les "tolèrent" pas explicitement. C'est un mécanisme utilisé pour dédier des Noeuds à des tâches spécifiques (par exemple, des Noeuds avec du matériel spécial) ou pour isoler des charges de travail. Un Noeud peut avoir un Taint comme `special=true:NoSchedule`.

Si un Pod n'a pas de `toleration` correspondante dans sa spécification (`spec.tolerations`) pour les Taints présents sur tous les Noeuds potentiellement disponibles (ceux qui auraient assez de ressources et correspondraient aux sélecteurs/affinités), il ne pourra pas y être planifié et restera `Pending`.

Le message d'événement dans `kubectl describe pod ` sera explicite :

Warning FailedScheduling 5m kube-scheduler 0/5 nodes are available: 5 node(s) had taints that the pod didn't tolerate.

Les solutions consistent à :

  • Ajouter les `tolerations` nécessaires à la spécification du Pod pour qu'il puisse être planifié sur les Noeuds Taintés.
  • Supprimer le Taint du ou des Noeuds si le Pod est censé pouvoir y être planifié (utiliser `kubectl taint node key=value:Effect-`). Attention, cela peut avoir des effets de bord sur d'autres planifications.

Cause n°4 : Noeud(s) indisponible(s) ou non prêts

Le planificateur Kubernetes ne prend en compte que les Noeuds qui sont dans l'état `Ready`. Si un ou plusieurs Noeuds sont en état `NotReady` ou `Unknown`, ou s'ils souffrent de conditions de pression (`MemoryPressure`, `DiskPressure`, `PIDPressure`), ils peuvent être exclus du processus de planification.

Un Noeud peut devenir `NotReady` pour diverses raisons : le processus `kubelet` sur le Noeud est arrêté ou ne répond pas, des problèmes réseau empêchent la communication avec le control plane, le disque est plein, la mémoire est insuffisante au niveau du système d'exploitation, etc.

Dans ce cas, `kubectl describe pod` peut simplement indiquer qu'aucun Noeud n'est disponible, sans forcément pointer explicitement vers l'état `NotReady` comme raison directe du `FailedScheduling` (même si cela peut apparaître combiné avec d'autres raisons). Il est donc crucial de vérifier l'état des Noeuds :

kubectl get nodes

Recherchez les Noeuds dont le `STATUS` n'est pas `Ready`. Pour investiguer un Noeud spécifique, utilisez :

kubectl describe node 

Examinez les `Conditions` (Ready, MemoryPressure, DiskPressure...) et les `Events` du Noeud pour comprendre la cause de son indisponibilité. La résolution dépendra du problème spécifique identifié sur le Noeud (redémarrer kubelet, libérer de l'espace disque, résoudre les problèmes réseau, etc.).

Cause n°5 : Problèmes de montage de Volume Persistant

Un Pod peut également rester en `Pending` si Kubernetes ne parvient pas à satisfaire une demande de volume persistant (PersistentVolumeClaim, PVC) définie dans la spécification du Pod. Avant de pouvoir planifier le Pod sur un Noeud, Kubernetes doit s'assurer que le volume demandé peut être provisionné et attaché.

Plusieurs raisons peuvent empêcher cela :

  • Aucun PersistentVolume (PV) existant ne correspond aux exigences de la PVC (taille, `accessModes`, `storageClassName`).
  • La `StorageClass` spécifiée dans la PVC n'existe pas ou est mal configurée.
  • Le provisionneur de stockage dynamique associé à la `StorageClass` rencontre une erreur (problème avec le fournisseur de cloud, quota de stockage atteint, etc.).
  • La PVC est déjà liée à un PV, mais ce PV n'est pas disponible ou ne peut pas être monté sur les Noeuds potentiels (par exemple, en raison de restrictions d'AccessModes comme `ReadWriteOnce` dans un environnement multi-noeuds).

`kubectl describe pod ` peut afficher des événements liés au montage de volumes :

Warning FailedAttachVolume 4m attachdetach-controller AttachVolume.Attach failed for volume "pvc-xxxxx" : rpc error: code = NotFound desc = Volume not found
Warning FailedMount 3m kubelet, node-1 MountVolume.SetUp failed for volume "pvc-yyyyy" : persistentvolumeclaim "my-data-pvc" not found

Pour diagnostiquer :

  • Vérifiez l'état de la PVC : `kubectl get pvc ` (elle doit être `Bound`).
  • Décrivez la PVC : `kubectl describe pvc `. Regardez les événements pour des erreurs de provisionnement ou de liaison.
  • Vérifiez l'existence et la configuration de la `StorageClass` : `kubectl get sc`.
  • Examinez les PV disponibles : `kubectl get pv`.
  • Consultez les logs du provisionneur de stockage si applicable.

Stratégie de diagnostic pour l'état `Pending`

Face à un Pod en état `Pending`, la première étape est systématiquement d'utiliser `kubectl describe pod `. La section `Events` au bas de la sortie est la source d'information la plus directe et vous oriente généralement vers la cause principale.

Analysez les messages `FailedScheduling`. S'ils mentionnent des ressources (`Insufficient cpu/memory`), des contraintes (`didn't match node selector/affinity/taints`), le problème vient probablement de là. Si aucun message `FailedScheduling` n'est clair ou si des erreurs de montage de volume apparaissent, investiguez du côté des PVCs et PVs.

Parallèlement, vérifiez toujours l'état général des Noeuds avec `kubectl get nodes`. Un Noeud `NotReady` peut être la cause sous-jacente même si les événements du Pod ne le mentionnent pas explicitement. En combinant ces informations, vous pourrez identifier la cause racine et appliquer la correction appropriée pour permettre enfin à votre Pod d'être planifié et de passer à l'état `ContainerCreating` puis `Running`.