CSI overview — the Container Storage Interface standard and its lifecycle
What you'll learn
- Describe the CSI standard and its gRPC-based interface
- Distinguish the controller plugin from the node plugin
- Trace the CSI operation lifecycle (Provision, Attach, Mount, Format, Snapshot)
- Explain why CSI replaced the in-tree storage plugins
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
The Container Storage Interface (CSI) is the standard that lets any storage vendor implement a Kubernetes driver without modifying Kubernetes itself. This lesson walks the CSI architecture, the gRPC interface, and the lifecycle operations.
What CSI is
CSI is a specification for a gRPC-based interface between
Kubernetes and storage drivers. Before CSI, storage
drivers were compiled into Kubernetes (in-tree plugins:
kubernetes.io/aws-ebs, kubernetes.io/gce-pd, etc.).
With CSI, drivers are out-of-tree: they run as separate
Pods in the cluster, communicating with Kubernetes via
gRPC.
flowchart TB
A[kubelet] -->|gRPC| B[CSI node plugin]
C[kube-controller-manager] -->|gRPC| D[CSI controller plugin]
B --> E[Storage backend]
D --> E
The benefits of CSI over in-tree:
- Independent driver evolution: vendors release drivers on their own schedule, not Kubernetes’s.
- No Kubernetes recompilation: drivers are not part of the Kubernetes binary.
- Standard interface: any vendor can implement CSI; any Kubernetes cluster can use any CSI driver.
The gRPC interface
CSI uses gRPC (Google Remote Procedure Call) for communication. The CSI specification defines three services:
- Identity Service: returns the driver’s name, version, and capabilities.
- Controller Service: cluster-wide operations (CreateVolume, DeleteVolume, ControllerPublishVolume, CreateSnapshot).
- Node Service: per-node operations (NodeStageVolume, NodePublishVolume).
service Controller {
rpc CreateVolume(CreateVolumeRequest) returns (CreateVolumeResponse);
rpc DeleteVolume(DeleteVolumeRequest) returns (DeleteVolumeResponse);
rpc ControllerPublishVolume(ControllerPublishVolumeRequest) returns (ControllerPublishVolumeResponse);
rpc ControllerUnpublishVolume(ControllerUnpublishVolumeRequest) returns (ControllerUnpublishVolumeResponse);
rpc ValidateVolumeCapabilities(ValidateVolumeCapabilitiesRequest) returns (ValidateVolumeCapabilitiesResponse);
rpc ListVolumes(ListVolumesRequest) returns (ListVolumesResponse);
rpc GetCapacity(GetCapacityRequest) returns (GetCapacityResponse);
rpc CreateSnapshot(CreateSnapshotRequest) returns (CreateSnapshotResponse);
rpc DeleteSnapshot(DeleteSnapshotRequest) returns (DeleteSnapshotResponse);
rpc ListSnapshots(ListSnapshotsRequest) returns (ListSnapshotsResponse);
rpc ControllerExpandVolume(ControllerExpandVolumeRequest) returns (ControllerExpandVolumeResponse);
rpc ControllerGetVolume(ControllerGetVolumeRequest) returns (ControllerGetVolumeResponse);
}
service Node {
rpc NodeStageVolume(NodeStageVolumeRequest) returns (NodeStageVolumeResponse);
rpc NodeUnstageVolume(NodeUnstageVolumeRequest) returns (NodeUnstageVolumeResponse);
rpc NodePublishVolume(NodePublishVolumeRequest) returns (NodePublishVolumeResponse);
rpc NodeUnpublishVolume(NodeUnpublishVolumeRequest) returns (NodeUnpublishVolumeResponse);
rpc NodeGetVolumeStats(NodeGetVolumeStatsRequest) returns (NodeGetVolumeStatsResponse);
rpc NodeExpandVolume(NodeExpandVolumeRequest) returns (NodeExpandVolumeResponse);
rpc NodeGetCapabilities(NodeGetCapabilitiesRequest) returns (NodeGetCapabilitiesResponse);
rpc NodeGetInfo(NodeGetInfoRequest) returns (NodeGetInfoResponse);
}
Each RPC takes a request and returns a response. Errors are returned with gRPC status codes; the kubelet and the controller manager interpret the codes.
The controller plugin
The controller plugin runs the Controller Service. It is
implemented as a Deployment or StatefulSet, typically in
kube-system:
# The controller plugin for EBS CSI
kubectl -n kube-system get deploy ebs-csi-controller
The controller plugin is a singleton (one active replica, with standby replicas for HA). It runs the cluster-wide operations: create, delete, attach, snapshot, expand.
The node plugin
The node plugin runs the Node Service. It is implemented as a DaemonSet, one Pod per node:
# The node plugin for EBS CSI
kubectl -n kube-system get ds ebs-csi-node
The node plugin runs the per-node operations: stage, publish, unstage, unpublish, expand.
The lifecycle
A volume’s CSI lifecycle:
sequenceDiagram
participant U as User
participant API as API server
participant CM as Controller manager
participant CP as CSI controller plugin
participant BE as Storage backend
participant K as kubelet
participant NP as CSI node plugin
Note over U,API: Provisioning
U->>API: submit PVC
API->>CM: PVC needs PV
CM->>CP: CreateVolume (name, capacity, params)
CP->>BE: create backend storage
BE-->>CP: volumeHandle
CP-->>CM: PV created
Note over K,NP: Attaching and mounting
K->>NP: NodeStageVolume (volumeHandle, stagingPath)
NP->>BE: format and mount to stagingPath
K->>NP: NodePublishVolume (stagingPath, targetPath)
NP-->>K: bind-mount to Pod
Note over U,API: Deletion (reversed)
U->>API: delete PVC
API->>CM: PV to be reclaimed
K->>NP: NodeUnpublishVolume
K->>NP: NodeUnstageVolume
CM->>CP: DeleteVolume
CP->>BE: delete backend storage
The phases:
- Provisioning: CSI controller creates the volume (CreateVolume).
- Attaching: CSI controller attaches the volume to the node (ControllerPublishVolume, for cloud-block).
- Staging: CSI node plugin formats (if needed) and mounts to the staging path (NodeStageVolume).
- Publishing: CSI node plugin bind-mounts to the Pod (NodePublishVolume).
- Deletion (reversed): unpublish, unstage, detach, delete.
Quiz
Knowledge check · 4 questions
Q1. What is the primary benefit of CSI over the legacy in-tree storage plugins?
Q2. The CSI controller plugin and the CSI node plugin are separate because they have different scopes (cluster-wide vs per-node).
Q3. Your team is evaluating a new CSI driver for a storage backend. Walk through the validation steps.
Vendor provides a CSI driver for a new storage backend. The team needs to validate that the driver is functional, supports the required operations, and integrates with Kubernetes.
Q4. Explain why the CSI controller plugin and the CSI node plugin are separate, and what each is responsible for.
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Every storage driver is CSI in Kubernetes 1.34. The in-tree plugins are removed.
- The controller plugin is a SLO dependency. Its latency and reliability affect every PVC on its StorageClass.
- The node plugin runs on every node. A node plugin failure blocks volume mounts on the affected node.
- CSI drivers are validated via the conformance suite. Adopters run the suite; production validation tests every operation the workload uses.
- gRPC is the wire protocol. Errors are gRPC status codes; kubelet and controller manager interpret them.