Attach and Mount Chain
A new claim is not a mounted disk, so what happens between the two? Up to four gRPC calls run in order: CreateVolume makes the disk, ControllerPublishVolume, where attach is required, attaches it to the Node, NodeStageVolume, if the driver stages, formats it if still blank and mounts it once at a global staging path, and NodePublishVolume mounts that into the Pod directory, usually by bind. When its last Pod goes, the other three undo in reverse and the disk stays.
Play the animation 5 steps, animated, best on a wide screen
Attach and Mount Chain, step by step
-
CreateVolume runs first, on the controller side, for a dynamically provisioned claim. The provisioner asks the driver to carve a real disk out of the cloud backend. When it returns, a disk called vol-1 exists somewhere in the provider, but it is not attached to any Node yet and nothing can read a byte of it.
Play from step 1 -
ControllerPublishVolume runs next, if the driver requires attach. The attach and detach controller writes a VolumeAttachment for the Node the Pod is on, and the external-attacher turns it into this call. Here that is a cloud API call, and vol-1 shows up on the Node as a raw block device, /dev/nvme1n1, still unformatted.
Play from step 2 -
Once the VolumeAttachment reads attached, Kubelet sends NodeStageVolume, the first of two Node calls, on a driver that stages. The node plugin formats the device if still blank and mounts it once, at a staging path Kubelet just made. One mount per Node however many Pods use it is why stage and publish are split.
Play from step 3 -
NodePublishVolume is the last call, once per Pod. It usually bind-mounts the staged filesystem into this Pod private directory rather than mounting the disk again, and the runtime binds that into the container as /data. Kubelet may then apply the Pod fsGroup, unless the driver did. Only then does Pod A start and begin writing.
Play from step 4 -
Delete Pod A and the calls unwind in reverse. NodeUnpublishVolume removes its bind mount. With no other Pod on the Node using it, NodeUnstageVolume unmounts the staging path and Kubelet deletes it. On a healthy Node only then does ControllerUnpublishVolume detach the disk. The disk survives: deleting it is up to the reclaim policy.
Play from step 5