Skip to main content
RunBook Academy

KubernetesLI · StorageClassesStorageClasses

Provisioners and CSI drivers — what calls the storage backend

Advanced⏱ ~16 minkubectl

What you'll learn

  • Describe what a provisioner does and how it interacts with the backend
  • Distinguish the controller plugin from the node plugin
  • Verify a provisioner is healthy and functioning
  • Identify the failure modes of a misbehaving provisioner

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

Not yet marked complete on this device.

The provisioner is the field that connects a StorageClass to a CSI driver. The CSI driver is the software that talks to the storage backend. This lesson walks the provisioner, the controller and node plugins, and how to verify the provisioner is healthy.

What a provisioner does

The provisioner (a CSI driver) implements the operations that create, attach, mount, format, snapshot, expand, and delete volumes:

  • CreateVolume: the provisioner creates a volume on the backend.
  • DeleteVolume: the provisioner deletes the volume.
  • ControllerPublishVolume / ControllerUnpublishVolume: attach/detach the volume to/from a node (for cloud block storage).
  • NodeStageVolume / NodePublishVolume: stage and publish the volume on a node.
  • CreateSnapshot / DeleteSnapshot: snapshot operations.
  • ExpandVolume: expand the volume.

The provisioner is implemented as one or more Pods in the cluster:

flowchart LR
    A[StorageClass] --> B[CSI controller plugin<br/>Deployment / StatefulSet]
    B --> C[Storage backend: EBS, Ceph, NFS, etc.]
    D[CSI node plugin<br/>DaemonSet] --> E[Node operations]
    B <--> D

The controller plugin

The controller plugin runs the cluster-wide operations: CreateVolume, DeleteVolume, CreateSnapshot, ExpandVolume. It runs as a Deployment or StatefulSet, typically in the kube-system namespace.

# Substitute your own value before running:
CSI=ebs-csi

# List the controller plugin Pods
kubectl -n kube-system get pods -l "app=$CSI,role=controller"

The controller plugin is a singleton (one active replica, with standby replicas for HA). A failure of the controller plugin blocks PVCs that reference its StorageClasses.

The node plugin

The node plugin runs the per-node operations: NodeStageVolume, NodePublishVolume, NodeUnstageVolume, NodeUnpublishVolume. It runs as a DaemonSet, one Pod per node.

# Substitute your own value before running:
CSI=ebs-csi

# List the node plugin Pods
kubectl -n kube-system get pods -l "app=$CSI,role=node"

A failure of the node plugin on one node blocks volume mounts on that node. A failure on all nodes blocks all volume mounts.

Common provisioners

ProvisionerBackendNotes
ebs.csi.aws.comAWS EBSMost common cloud block.
ebs.csi.eks.amazonaws.comAWS EBS (EKS addon)EKS-managed variant.
pd.csi.storage.gke.ioGCP Persistent DiskGKE-managed.
disk.csi.azure.comAzure DiskAKS-managed.
cephfs.csi.ceph.comCephFSDistributed filesystem.
rbd.csi.ceph.comCeph RBDDistributed block.
nfs.csi.k8s.ioNFSNetwork filesystem.
csi.longhorn.ioLonghornCloud-native block.
rook-ceph.rbd.csi.ceph.comRook-CephRook-managed Ceph.

Each provisioner has its own parameters, performance characteristics, and operational considerations.

Verifying provisioner health

# Substitute your own values before running:
CSI=ebs-csi
NODE=node-1

# 1. The controller plugin is running
kubectl -n kube-system get pods -l "app=$CSI,role=controller"
# READY   STATUS
# 1/1     Running

# 2. The node plugin is running on every node
kubectl -n kube-system get pods -l "app=$CSI,role=node" -o wide
# READY   STATUS   NODE
# 1/1     Running  node-1
# 1/1     Running  node-2
# 1/1     Running  node-3

# 3. The CSIDriver object exists
kubectl get csinode "$NODE" -o yaml
# drivers:
# - name: ebs.csi.aws.com
#   nodeID: i-0123456789abcdef0

# 4. The CSI driver is registered with the API server
kubectl get csidriver
# NAME                    ATTACHREQUIRED   MAXSTORAGE_PERNODE
# ebs.csi.aws.com         true             0

# 5. Test with a PVC
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes: ["ReadWriteOnce"]
  storageClassName: "<storageclass>"
  resources:
    requests:
      storage: 1Gi
EOF

# 6. Check the PVC's status
kubectl get pvc test-pvc -w
# STATUS should transition from Pending to Bound

Failure modes

The common provisioner failure modes:

  • Controller plugin down: new PVCs Pending. Existing PVCs continue to function (the controller plugin is not on the data path).
  • Node plugin down on one node: volume mounts on that node fail. Other nodes are unaffected.
  • Node plugin down on all nodes: all volume mounts fail. PVCs are still bound but Pods cannot mount.
  • Provisioner throttled by backend: PVCs Pending (e.g., AWS API throttling). The provisioner logs show the throttling.
  • Provisioner RBAC misconfigured: PVCs Pending with “permission denied” in the logs.
  • Provisioner parameters invalid: PVCs Pending with the provisioner’s validation error in the logs.

Quiz

Knowledge check · 4 questions

  1. Q1. The EBS CSI controller plugin Pod is down. New PVCs on the EBS StorageClass are submitted. What happens?

  2. Q2. The CSI node plugin must run on every node for volume mounts to succeed.

  3. Q3. Your team observes that new PVCs on the EBS StorageClass are Pending for 5 minutes. Walk through the diagnostic.

    PVCs Pending for 5 minutes. The EBS CSI controller plugin Pod is running. The node plugins are running on every node. Existing PVCs continue to function.

  4. Q4. Explain the difference between the CSI controller plugin and the CSI node plugin and what happens when each fails.

Passing score: 75%. Answers are checked in this browser.

Production discipline

  • The provisioner is a SLO dependency. Its latency and reliability affect every PVC on its StorageClass.
  • Verify the controller plugin is running. A controller failure blocks new PVCs.
  • Verify the node plugin runs on every node. A node plugin failure blocks mounts on the affected node.
  • Monitor provisioner metrics. CreateVolume latency, error rate, throttling. The provisioner’s health is observable.
  • Test the provisioner with a PVC. A regular validation that creates a test PVC and verifies it binds within the expected time.