VolumeAttachment

What records that a disk is attached to a Node, and who writes it? Not Kubelet: for a CSI driver that requires attach, the attach-detach controller writes a VolumeAttachment, and the external-attacher calls ControllerPublishVolume and sets status.attached true. Only then does Kubelet get it mounted. Deleting the object detaches, on a healthy Node once the Pod is gone and Kubelet has unmounted, and the object counts toward the Node attach limit until gone.

Play the animation 6 steps, animated, best on a wide screen

VolumeAttachment diagram: The VolumeAttachment object

VolumeAttachment, step by step

  1. It is not Kubelet that decides a CSI volume needs attaching. The attach and detach controller in kube-controller-manager sees a Pod bound to a Node with a volume not attached there and takes the job on, if the driver requires attach. With attachRequired false no VolumeAttachment is written.

    Play from step 1
  2. The controller writes csi-7f3a, its name a hash of volume handle, driver and Node. Its spec names that driver, vol-1 and Node-1, and status.attached reads false because nothing has set it yet. It is the one cluster record that vol-1 belongs on Node-1. Nothing physical has happened yet.

    Play from step 2
  3. The external-attacher for the driver the spec names picks this one up, adds its finalizer and calls ControllerPublishVolume, which attaches vol-1 to Node-1 in the storage backend. The device is physically on the Node now, and Kubelet still will not touch it, because the object still says false.

    Play from step 3
  4. When the backend confirms the attach, the attacher writes status.attached true back onto the same VolumeAttachment. That one field is the signal everything downstream waits for. The object did not move and nothing was recreated: its status changed in place.

    Play from step 4
  5. Kubelet has been blocked all along. It waits for vol-1 to be listed as attached in the Node status, which the controller writes only after status.attached turns true, then checks that same field on the object before it has vol-1 mounted for the Pod at /data. The Pod starts: the object gated the mount.

    Play from step 5
  6. Deleting the object is what tears the attach down. On a healthy Node, once the Pod is gone and Kubelet reports vol-1 unmounted, the controller deletes it. The attacher sees the deletion mark, calls ControllerUnpublishVolume, and once vol-1 is detached it lifts its finalizer and the object goes.

    Play from step 6

Sources