Skip to content

Build the failure that delayed binding prevents

Claim — with Immediate binding you can strand a volume in one topology domain while the only pod that wants it must run in another, and the cluster will not fix it. With WaitForFirstConsumer the same construction cannot be built.

Topology — pair, continued from delayed binding. Two nodes is the minimum for this and it is exactly enough: one domain each.

Do

  1. Label the two nodes as distinct domains:
kubectl label node <cp> topology.kubernetes.io/zone=alpha
kubectl label node <worker> topology.kubernetes.io/zone=beta
  1. Add allowedTopologies to the Immediate class, pinning it to alpha:
allowedTopologies:
- matchLabelExpressions:
  - key: topology.kubernetes.io/zone
    values: [alpha]
  1. Create a PVC against it — it binds immediately, in alpha.
  2. Now create a pod for that PVC with nodeSelector: {topology.kubernetes.io/zone: beta}. Record what the pod does and what the scheduler says.
  3. Repeat the whole construction against the WaitForFirstConsumer class and show the strand cannot occur.

Observe

kubectl get pv <name> -o jsonpath='{.spec.nodeAffinity}' | jq
kubectl describe pod <pod> | sed -n '/Events/,$p'
kubectl -n kube-system logs -l component=kube-scheduler --tail=200 | grep -i 'volume\|node affinity'

Expect — the pod is unschedulable, and the scheduler's reason names the volume's node affinity rather than the nodeSelector. The volume was placed before anyone asked where the pod would run; nothing later can move it. Under WaitForFirstConsumer the placement decision is made once, with both constraints in hand.

Write down — one paragraph describing this failure to someone who has not done this phase. The checklist asks for it, and it is a common production incident.

Teardown — leave it up. Remove the zone labels and the pinned class so the Pending drill starts from a plain cluster.