What Are CSI Drivers and How Do They Work in Kubernetes?

advanced|storagedevopssreCKA
TL;DR

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

How is a CSI driver deployed in a cluster?
Typically as a controller Deployment (for provisioning/attaching) and a node DaemonSet (for mounting). Both include sidecar containers for registration and communication.
What are CSI sidecars?
Helper containers like external-provisioner, external-attacher, external-resizer, and node-driver-registrar that bridge the Kubernetes API to the CSI driver.
How do volume snapshots work with CSI?
The CSI snapshot controller and external-snapshotter sidecar manage VolumeSnapshot and VolumeSnapshotContent CRDs to create and restore snapshots.

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