A Pending Pod exists in the API but runs nowhere. No container has started, so there are no logs; the only witness is the scheduler.
kubectl describe pod market-worker | tail -5
kubectl get pod market-worker -o jsonpath='{.status.conditions[?(@.type=="PodScheduled")].message}'Warning FailedScheduling default-scheduler 0/1 nodes are available: 1 Insufficient cpu. ...The message counts the nodes and gives one reason per group of nodes. The reasons come in five families.
The five families
| Message says | Family | Fix from |
|---|---|---|
Insufficient cpu / Insufficient memory | resources | lower the requests, or add a node (Chapter 6) |
didn't match Pod's node affinity/selector | placement | label a node, or loosen the selector (Chapter 9) |
had untolerated taint {key: value} | taints | add a toleration, or remove the taint (Chapter 9) |
pod has unbound immediate PersistentVolumeClaims | storage | create or fix the PVC (Chapter 8) |
were unschedulable | cordon | kubectl uncordon (Chapter 9) |
A sixth case looks like Pending but is not: a Deployment that wants Pods and has none at all, not even Pending. Those Pods were refused before they existed. The ReplicaSet's Events hold the reason, usually a ResourceQuota, a LimitRange or a missing ServiceAccount.
kubectl describe rs -l app=market-worker | tail -3
kubectl events --for deploy/market-workerFixing it
Requests, selectors and tolerations are part of the Pod spec, so a bare Pod has to be deleted and recreated; a Deployment just needs its template edited and rolls the fix out. The other side of each pair is cluster state: kubectl label node, kubectl taint, kubectl uncordon, a new PVC.