- Authors

- Name
- Phillip Pham
- @ddppham
Pod Pending: FailedScheduling lesen und beheben
TL;DR
Pending heißt: der Scheduler hat keinen Node akzeptiert. Der Container ist nicht gestartet. Logs gibt es nicht. Die Zeile, die den Grund nennt, steht in den Events:
kubectl describe pod POD
Ganz unten, FailedScheduling. Der Text ist die Ursache, nicht ein Hinweis. insufficient cpu oder insufficient memory ist Ressourcenmangel. untolerated taint ist ein Taint ohne Toleration. didn't match Pod's node affinity ist Selector oder Affinity. persistentvolumeclaim ist ein Volume, das nicht gebunden ist — dann weiter bei PVC Pending.
Die Meldung und der Fix
| Events-Text | Ursache | Was Sie ändern |
|---|---|---|
| 0/N nodes: insufficient cpu / memory | Requests höher als frei | Request senken oder Node dazunehmen |
| untolerated taint | Node lehnt den Pod ab | Toleration setzen oder anderen Pool wählen |
| didn't match node affinity / selector | Label fehlt | nodeSelector oder Affinity an das Label anpassen |
| pod has unbound immediate PersistentVolumeClaims | PVC nicht Bound | StorageClass, siehe PVC-Artikel |
| exceeded quota | ResourceQuota im Namespace voll | Quota oder Requests anpassen |
0/3 nodes are available zählt mit. Steht dahinter dreimal derselbe Grund, ist es ein Cluster-Thema. Steht dahinter ein Mix, erfüllt kein einzelner Node alle Bedingungen gleichzeitig.
Requests, nicht Limits, halten den Pod fest
Der Scheduler rechnet mit requests. Limits interessieren ihn nicht. Ein Pod mit requests.cpu: 2 und einem Node, auf dem nur 500m frei sind, bleibt Pending, auch wenn der Prozess später kaum CPU braucht. kubectl describe node NODE zeigt Allocated resources. Dort sehen Sie, was schon reserviert ist, nicht was wirklich verbraucht wird.
Wer nach einem OOMKilled Request und Limit gemeinsam verdoppelt, füllt die Reservierung. Der nächste Pod findet keinen Platz, obwohl kubectl top noch Luft zeigt. Für den Start reicht ein Request in der Nähe des Normalverbrauchs. Das Limit darf darüber liegen.
Ein leerer Request ist auch ein Problem, nur später: der Scheduler packt den Pod überall hin, und unter Last verdrängt ihn das Kubelet. Für alles, was in Produktion läuft, Request setzen.
Taints und Pools
Control-Plane-Nodes tragen node-role.kubernetes.io/control-plane:NoSchedule. Ein Pod ohne Toleration kommt dort nicht hin. Dasselbe gilt für Pools mit workload=gpu oder dedicated=batch, wenn der Betreiber sie so markiert hat.
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
kubectl get pod POD -o jsonpath='{.spec.tolerations}{"\n"}{.spec.nodeSelector}{"\n"}'
Die Toleration muss Key, Effect und bei Equal auch den Value treffen. Exists ohne Value gilt für jeden Value dieses Keys. Ein Tippfehler im Key ist still: der Pod bleibt Pending, der Node sieht gesund aus.
Quota im Namespace
exceeded quota kommt nicht vom Node, sondern vom Namespace. kubectl describe quota -n NAMESPACE zeigt used gegen hard. CPU, Memory, Pod-Anzahl und oft requests.storage stehen getrennt. Ein neues Replica kann an pods: 10 scheitern, während CPU noch frei ist.
Was Pending nicht ist
Steigt der Status auf ContainerCreating und bleibt dort, ist der Pod geschedult. Dann sind Image, Volume-Mount oder ein Init-Container das Thema, nicht der Scheduler. Stirbt er nach dem Start, ist es CrashLoopBackOff. Pending endet in dem Moment, in dem ein Node zugewiesen ist. kubectl get pod POD -o wide hat dann einen Wert in der Spalte NODE.
Quellen
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
Exit Code 137: OOMKilled auf Kubernetes beheben
Exit Code 137 auf Kubernetes: Wann es OOMKilled ist und wann die Liveness-Probe. Memory-Limit setzen, bevor der cgroup den Prozess mit SIGKILL beendet.
kubectl connection refused 6443 beheben
kubectl connection refused auf Port 6443: der API-Server antwortet nicht. kubeconfig, Kontext, Firewall, API-Prozess. Der Pod-Status kommt erst danach.
Error from server Forbidden: RBAC-Recht
kubectl Forbidden: Error from server (Forbidden) nennt User, Verb und Ressource. kubectl auth can-i zeigt das Recht, bevor jemand cluster-admin vergibt.
ContainerCreating hängt: Volume, Sandbox, CNI
ContainerCreating hängt: der Pod hat einen Node, der Container startet nicht. FailedMount, Pod-Sandbox und CNI stehen in den Events, nicht in den Logs.
CreateContainerConfigError: Secret und ConfigMap
CreateContainerConfigError: fehlendes Secret, falscher Key oder Namespace. Der Container startet nicht, logs --previous bleibt leer. Das Event nennt das Objekt.
Kubernetes DNS fehlgeschlagen: CoreDNS, ndots
Kubernetes DNS fehlgeschlagen: CoreDNS-Pods, das Service-ClusterIP und ndots:5. Wann ein Name im Cluster auflöst und wann die NetworkPolicy UDP 53 schluckt.
Exit Code 1: die erste Zeile im Previous-Log
Exit Code 1 auf Kubernetes: die Anwendung beendet sich selbst. kubectl logs --previous zeigt die Zeile. Speicher, Image-Pull und SIGKILL sind andere Codes.
Exit Code 143: SIGTERM und Graceful Shutdown
Exit Code 143 ist SIGTERM: 128 plus 15. Beim Rollout ist das normal. Im Loop fehlt ein Handler oder die Grace-Period ist kürzer als der Stopp der Anwendung.