Curious Pandas

Why won't it schedule?

A pod stuck in Pending has a reason, and it's never printed where you're looking. Find it, read it, and fix the request rather than the cluster.

14 min+35 XP for finishing

You ask for three replicas. Two start. The third sits in Pending and stays there. Nothing crashed and nothing is red. kubectl get pods shows the word Pending and nothing else.

Pending means the pod exists but no node has been chosen for it. The scheduler keeps trying, and each time it fails it records why as an event on the pod. You only see events if you ask for them.

Requests, not usage

The scheduler places pods by what they request, not by what they actually use. Every container can declare requests.cpu and requests.memory. The scheduler adds up the requests already placed on each node and won’t go past the node’s capacity. From the Kubernetes docs:

although actual memory or CPU resource usage on nodes is very low, the scheduler still refuses to place a Pod on a node if the capacity check fails.

That surprises people the first time. A node can sit at 3% CPU and still be “full”, because everything on it asked for a lot. It’s deliberate: a request is a reservation for your peak, not a guess at your average.

Find it, read it, fix it

This cluster has two nodes with 2 CPUs (2000m) each. Someone deployed big with three replicas, each requesting 1500m. Work out why one won’t start, then fix it without scaling down.

Three big pandas, two small nodest = 0s

Click any pod to describe it.

Cluster
Waiting for a node
Running & ReadyStartingPendingCrashing / can't pull

Here’s what the scheduler did each time it tried the third pod:

Visual guideWhy the third pod waits
Why the third pod waitsA pending pod requests 1500m of CPU. The scheduler adds up what pods already on each node requested: both nodes have 2000m and 1500m already promised, leaving 500m, so neither fits. It records the reason as a FailedScheduling event on the pod and tries again later.pending podrequests 1500mscheduleradds up requestsworker-11500m of 2000m takenworker-21500m of 2000m takenFailedSchedulingan event on the podno node yetfits?fits?writesWhy the third pod waitsA pending pod requests 1500m of CPU. The scheduler adds up what pods already on each node requested: both nodes have 2000m and 1500m already promised, leaving 500m, so neither fits. It records the reason as a FailedScheduling event on the pod and tries again later.pending podrequests 1500mscheduleradds up requestsworker-11500m of 2000m takenworker-21500m of 2000m takenFailedSchedulingan event on the podno node yetfits?fits?writes
  1. A pod asks for 1500m. Until a node is chosen it stays Pending - nothing crashed, nothing is red.
  2. The scheduler adds up what the pods on each node requested. Not what they use.
  3. Each node has 2000m and has already promised 1500m. 500m is left on each, so neither fits.
  4. So it writes the reason as an event on the pod and tries again later. kubectl describe pod is where you read it.
Check yourself+10 XP

A node shows 4% CPU usage in your monitoring, but new pods won't schedule there because of Insufficient cpu. How can both be true?

Check yourself+10 XP

Where does the reason a pod is Pending show up?

Do it for real · your machine+50 XP bonus

Everything above ran in your browser. Now do it on a real cluster withthe tilt platform. You need Docker, kind and Tilt, about 15 GB of free disk and 8 GB of spare RAM. Setup guide · Can my machine run it?

There’s no dedicated tilt lab for this one; the minimal platform is enough. Ask for more CPU than any laptop has:

kubectl create deployment big --image=nginx --replicas=2
kubectl set resources deployment big --requests=cpu=100   # 100 whole CPUs
kubectl get pods                     # Pending
kubectl describe pod -l app=big | tail -5
kubectl describe node | grep -A6 "Allocated resources"
kubectl delete deployment big
Self-reported. We can't see your machine, and we don't want to. This is a bonus, never required.

Sources

Finished reading?

Missions and quizzes above earn their own XP. This marks the lesson done.