Kubernetes storage · Diagram 2 of 2 · Sequence

Dynamic provisioning, step by step

Time runs top to bottom. The StorageClass here uses volumeBindingMode: WaitForFirstConsumer, so the disk is not created when the PVC appears. It is created only after the scheduler has picked a node for the Pod that uses it.

Dynamic provisioning with WaitForFirstConsumer Sequence showing a PVC waiting in Pending until a Pod is scheduled, after which the CSI provisioner creates a disk and PV in the chosen node's zone, the PV binds to the PVC, and the kubelet mounts it. DYNAMIC PROVISIONING OVER TIME · STORAGECLASS WITH volumeBindingMode: WaitForFirstConsumer 1 CREATE PVC The PVC sits in Pending. No Pod needs it yet, so nothing is created. 2 CREATE POD 3 NEW POD 4 PICK NODE 5 NODE CHOSEN 6 PROVISION 7 CREATE DISK 8 CREATE PV 9 BIND PVC+PV PVC and PV are now Bound. Only now can the Pod start. 10 BIND POD 11 RUN POD 12 MOUNT YOU You kubectl apply API Control plane API server + controllers SCHED Scheduler kube-scheduler CSI CSI Provisioner sidecar + CSI driver NODE Kubelet agent on the node LEGEND You Kubernetes component Request / write Noticed via watch Calls storage API Binding (headline)

What WaitForFirstConsumer does

It tells Kubernetes: don't create or bind a volume until a Pod actually needs it.

  • Steps 1–2: the PVC stays Pending until a Pod that uses it is created. Pending here is normal, not an error.
  • Steps 4–5: the scheduler picks a node for the Pod first. It records the choice on the PVC (the volume.kubernetes.io/selected-node annotation).
  • Step 7: the disk is then created where that node can reach it, for example in the same cloud zone.

Compare: Immediate mode

  • With volumeBindingMode: Immediate (the default), steps 6–9 happen right after step 1, before any Pod exists.
  • Risk: the disk may land in zone A while the Pod can only run in zone B. Then the Pod cannot start.
  • Local PVs (kubernetes.io/no-provisioner) should also use WaitForFirstConsumer. There, nothing is provisioned. Kubernetes waits for scheduling, then picks a hand-made PV on the chosen node.

Fidelity note

  • "Control plane" combines the API server, etcd and the PV controller into one lifeline.
  • Components really watch the API server. The dashed open arrows show "noticed a change", not a direct call.
  • Step 12 "MOUNT" covers attach (the attach/detach controller plus the CSI attacher) and the kubelet's stage/publish mount.
  • Not shown: retries, failures, ResourceQuota, access modes.