kubernetes/kubernetes
Volume plugins
The volume system spans both the apiserver (PV/PVC objects), the controller-manager (binding, expand, attach/detach), and the kubelet (mount/unmount). The shared library is pkg/volume/, which carries plugin interfaces, the in-tree plugins that still exist, and the CSI client.
The big picture
graph TD
User -->|kubectl apply| API[kube-apiserver]
API -->|PVC created| Binder[PV controller<br/>pkg/controller/volume/persistentvolume]
Binder -->|match label/StorageClass| PV[PersistentVolume]
PV --> Provision{Storage class<br/>provisioner}
Provision -->|in-tree or CSI external provisioner| Driver[Volume driver]
User -->|kubectl run with PVC| Pod
Pod --> Sched[Scheduler<br/>volumebinding plugin]
Sched -->|reserve PVC topology| Pod2[Pod scheduled]
Pod2 -->|spec.nodeName| Kubelet
Kubelet --> AttachDetach[Attach/Detach controller]
AttachDetach -->|VolumeAttachment| Driver
Kubelet -->|MountVolume| VolMgr[Volume manager]
VolMgr -->|Stage + Publish| DriverIn-tree plugins
The plugin interface is pkg/volume/plugin.go::VolumePlugin. Concrete in-tree plugins still in the tree:
| Plugin | Purpose | Status |
|---|---|---|
configmap |
Project a ConfigMap into a Pod | Always-in-tree |
secret |
Project a Secret | Always-in-tree |
downwardapi |
Project Pod metadata | Always-in-tree |
projected |
Compose ConfigMap/Secret/SAToken/DownwardAPI/PodCertificate/ClusterTrustBundle into one volume | Always-in-tree |
emptyDir |
Pod-lifetime scratch directory | Always-in-tree |
hostPath |
Mount a host directory | Always-in-tree |
local |
Node-local PV with topology constraints | Always-in-tree |
image |
Use a container image as a read-only volume | Always-in-tree |
git_repo |
Deprecated | |
nfs, iscsi, fc |
Protocol-level mounts | Still in-tree (no CSI driver shipped here) |
flexvolume |
Generic out-of-tree driver via shell hooks | Deprecated; use CSI |
csi |
Bridge to a CSI driver | Always-in-tree |
The legacy cloud-provider plugins (aws_ebs, gce_pd, azure_dd, vsphere_volume, cinder, azure_file) have been CSI-migrated: kubelet rewrites the in-tree spec into a CSI spec at mount time, transparently routing through the corresponding CSI driver. The translation lives in staging/src/k8s.io/csi-translation-lib/.
CSI client
pkg/volume/csi/ is the bridge to out-of-tree CSI drivers. The kubelet talks gRPC to two sockets per driver:
- Node service — for
NodeStageVolume,NodePublishVolume,NodeUnpublishVolume,NodeUnstageVolume,NodeGetVolumeStats,NodeExpandVolume. - Identity service — for
GetPluginInfo,Probe,GetPluginCapabilities.
The controller-manager talks to a third socket on a centrally-deployed pod for the Controller service (CreateVolume, DeleteVolume, ControllerPublishVolume, ControllerUnpublishVolume).
CSI drivers register themselves via the kubelet's plugin registry (/var/lib/kubelet/plugins_registry/<driver>/csi.sock). The plugin manager (pkg/kubelet/pluginmanager/) discovers and registers them.
CSI migration
pkg/volume/csimigration/ handles the staged hand-off:
- Kubelet detects whether the corresponding CSI driver is installed (
CSIDriverAPI resource). - If yes, all operations on the in-tree spec are translated and forwarded to the CSI driver.
- If no, fallback to the in-tree implementation (which may still exist for backward compatibility).
The InTreePluginXxxUnregister feature gates progressively turn off the legacy code path entirely.
Controller-side flows
pkg/controller/volume/ hosts five sub-controllers:
| Controller | Purpose |
|---|---|
persistentvolume/ |
Match PVCs to PVs; provision new PVs via the StorageClass's provisioner |
attachdetach/ |
Issue ControllerPublish / ControllerUnpublish (creates/deletes VolumeAttachment) |
expand/ |
Drive offline volume expansion |
ephemeral/ |
Generic ephemeral volumes (PVCs scoped to a Pod's lifecycle) |
pvprotection/, pvcprotection/ |
Block delete while in use via finalizers |
Pod-side flow (kubelet)
See components/kubelet/volumes.md for the kubelet's reconciler.
Volume topology
A volume can declare topology constraints via PersistentVolume.Spec.NodeAffinity (in-tree local PVs) or CSIDriver.Spec.Spec.RequiresRepublish plus Topology advertised by the driver. The scheduler's volumebinding plugin pre-binds a PVC to a PV that the candidate node can reach, holding a reservation through Reserve / PreBind so two pods don't race for the same PV.
Key source files
| File | Purpose |
|---|---|
pkg/volume/plugins.go |
The plugin registry |
pkg/volume/plugin.go |
VolumePlugin interface |
pkg/volume/csi/csi_plugin.go |
CSI plugin entry point |
pkg/volume/csimigration/plugin_manager.go |
In-tree → CSI translation orchestration |
staging/src/k8s.io/csi-translation-lib/translation_lib.go |
Per-driver translators |
pkg/controller/volume/persistentvolume/pv_controller.go |
PV controller |
pkg/controller/volume/attachdetach/attach_detach_controller.go |
Attach/Detach controller |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.