Pending n’est pas un diagnostic, c’est une phase. Elle signifie : le cluster a accepté le Pod, et au moins un conteneur n’a pas encore démarré. Ça couvre deux mondes qui n’ont rien à voir. Le premier réflexe n’est pas de « rajouter des nœuds ».
kubectl describe pod <nom>Les Events en bas tranchent.
FailedScheduling / 0/n nodes are available : le scheduler n’a placé personne. Le Pod n’a pas de nœud. À partir de là, on lit la raison, pas le YAML au hasard :
Insufficient cpu ou Insufficient memory : les requests ne tiennent nulle part. On compare kubectl describe node (Allocatable moins les requests déjà posées) à ce que le Pod demande. Souvent le chiffre est absurde — 4 CPU pour un sidecar — pas le cluster trop petit.node(s) had taint / untolerated taint : un taint NoSchedule refuse le Pod. Contrôle-plane, nœuds GPU, pool spot : c’est voulu, tant que le workload n’a pas la toleration.node(s) didn't match Pod's node affinity / node selector : le Pod exige un label que plus aucun nœud n’a.persistentvolumeclaim ... not bound : le volume n’existe pas encore. Le Pod attend le PVC, le PVC attend le provisioner. Ce n’est plus un problème de CPU.exceeded quota : le ResourceQuota du namespace est plein.Pas de FailedScheduling, ContainerCreating ou ErrImagePull / ImagePullBackOff : le Pod a un nœud. Pending ici, c’est le runtime qui n’a pas fini — image introuvable, secret de registry manquant, disque du nœud, CNI qui n’a pas câblé. Continuer à chercher un taint est du temps perdu.
describe du Pod, Events.kubectl get nodes -o wide, puis describe du nœud le plus plausible, et le PVC s’il y en a un.imagePullSecrets, réseau du nœud vers le registry.Une liste de vingt commandes. Une démarche : phase, puis Events, puis la classe de cause. Et la phrase de maturité : Pending n’est pas CrashLoopBackOff. Si le Pod a déjà tourné et redémarre, vous n’êtes plus ici.
« Tous les nœuds ont l’air libres au CPU, et ça reste Pending. »
Alors ce n’est probablement pas le CPU utilisé. Le scheduler ne voit que les requests déjà réservées. Un nœud à 5 % d’usage réel peut être plein si tout le monde a demandé 1 CPU pour dormir. kubectl describe node | grep -A5 Allocated dit le vrai remplissage. C’est aussi le moment où l’on parle de LimitRange qui injecte des requests par défaut que personne n’a lues dans le manifeste.