What Are CSI Drivers and How Do They Work in Kubernetes?
CSI (Container Storage Interface) is a standard API that allows Kubernetes to interact with any storage system. CSI drivers run as Pods in the cluster and handle volume provisioning, attaching, mounting, snapshotting, and resizing without requiring changes to Kubernetes core code.
Detailed Answer
Why CSI Exists
Before CSI, storage plugins were compiled directly into the Kubernetes binary (in-tree plugins). Adding support for a new storage system required modifying Kubernetes core code, which was slow and unsustainable. CSI decouples storage from Kubernetes, allowing vendors to develop, release, and update drivers independently.
As of Kubernetes 1.26+, most in-tree volume plugins have been migrated to CSI drivers. The in-tree code now acts as a shim that forwards calls to the corresponding CSI driver.
CSI Architecture
A CSI driver consists of two main components:
Controller Plugin (Deployment)
Runs as a centralized Deployment (usually 1-2 replicas). Handles operations that do not require node access:
- CreateVolume / DeleteVolume: Provision and deprovision storage
- ControllerPublishVolume / ControllerUnpublishVolume: Attach/detach volumes to/from nodes
- CreateSnapshot / DeleteSnapshot: Manage volume snapshots
- ControllerExpandVolume: Resize volumes
Node Plugin (DaemonSet)
Runs on every node. Handles operations that require local access:
- NodeStageVolume: Mount the block device to a staging path
- NodePublishVolume: Bind-mount from staging to the Pod's volume path
- NodeUnpublishVolume / NodeUnstageVolume: Unmount operations
CSI Sidecar Containers
CSI drivers do not communicate with the Kubernetes API directly. Instead, sidecar containers handle the Kubernetes integration:
Controller Pod:
├── csi-driver (vendor code)
├── external-provisioner (watches PVCs, calls CreateVolume)
├── external-attacher (watches VolumeAttachments, calls ControllerPublish)
├── external-resizer (watches PVC size changes, calls ExpandVolume)
└── external-snapshotter (watches VolumeSnapshots, calls CreateSnapshot)
Node Pod:
├── csi-driver (vendor code)
└── node-driver-registrar (registers the driver with kubelet)
Installing a CSI Driver: AWS EBS Example
# Install the AWS EBS CSI driver via Helm
helm repo add aws-ebs-csi-driver https://kubernetes-sigs.github.io/aws-ebs-csi-driver
helm install aws-ebs-csi-driver aws-ebs-csi-driver/aws-ebs-csi-driver \
--namespace kube-system \
--set controller.replicaCount=2 \
--set controller.serviceAccount.create=true \
--set controller.serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789012:role/EBSCSIDriverRole
After installation, verify the components:
# Check controller and node Pods
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver
# Verify the CSIDriver object
kubectl get csidriver ebs.csi.aws.com -o yaml
# Create a StorageClass using the CSI driver
kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
encrypted: "true"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
EOF
Volume Snapshots with CSI
CSI enables native volume snapshots through CRDs:
# 1. Create a VolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: ebs-snapclass
driver: ebs.csi.aws.com
deletionPolicy: Delete
---
# 2. Take a snapshot of an existing PVC
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: db-snapshot
spec:
volumeSnapshotClassName: ebs-snapclass
source:
persistentVolumeClaimName: postgres-data
---
# 3. Restore from snapshot into a new PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data-restored
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: ebs-gp3
dataSource:
name: db-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
Volume Cloning
CSI also supports cloning an existing PVC without creating a snapshot first:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: ebs-gp3
dataSource:
name: postgres-data # Source PVC
kind: PersistentVolumeClaim
Troubleshooting CSI Drivers
# Check CSIDriver registration
kubectl get csidriver
# Check CSINode info (per-node topology)
kubectl get csinodes
# View VolumeAttachment objects
kubectl get volumeattachment
# Check controller logs
kubectl logs -n kube-system deployment/ebs-csi-controller -c csi-provisioner
kubectl logs -n kube-system deployment/ebs-csi-controller -c ebs-plugin
# Check node plugin logs
kubectl logs -n kube-system -l app=ebs-csi-node -c ebs-plugin
# Common issues:
# - IAM permissions missing for cloud storage API calls
# - CSI driver not registered (node-driver-registrar failed)
# - Volume stuck in attaching state (check VolumeAttachment)
Common CSI Drivers
| Driver | Storage | Key Features | |---|---|---| | ebs.csi.aws.com | AWS EBS | Snapshots, encryption, gp3/io2 | | efs.csi.aws.com | AWS EFS | RWX support, access points | | pd.csi.storage.gke.io | GCE PD | Regional PDs, snapshots | | disk.csi.azure.com | Azure Disk | Ultra disk, shared disk | | nfs.csi.k8s.io | NFS | Generic NFS provisioner | | secrets-store.csi.k8s.io | Secret stores | Mount secrets as volumes |
CSI has become the standard for all storage integrations in Kubernetes, and understanding its architecture is essential for managing production storage.
Why Interviewers Ask This
Interviewers test whether you understand the modern storage architecture in Kubernetes and can install, configure, and troubleshoot CSI-based storage solutions.
Common Follow-Up Questions
Key Takeaways
- CSI replaced in-tree volume plugins with a plug-in architecture
- CSI drivers consist of a controller component and a node component
- CSI enables advanced features like snapshots, cloning, and topology-aware provisioning