πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Storage advanced ⏱ 15 minutes K8s 1.28+

K8s CSI Drivers: Container Storage Guide

Install and configure Kubernetes CSI drivers for persistent storage. CSI architecture, StorageClass provisioners, snapshots, and volume expansion patterns.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: CSI (Container Storage Interface) is the standard for Kubernetes storage plugins. Install a CSI driver (e.g., aws-ebs-csi-driver, csi-driver-nfs), create a StorageClass pointing to the CSI provisioner, then use PVCs as normal. CSI enables dynamic provisioning, snapshots, volume expansion, and cloning β€” features not available with in-tree drivers.

The Problem

Kubernetes deprecated in-tree storage plugins (aws-ebs, gce-pd, azure-disk):

  • Tied to Kubernetes release cycle
  • Can’t update storage driver independently
  • Limited features (no snapshots, no cloning)
  • No standard interface for new storage backends

The Solution

CSI Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Kubernetes Control Plane                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ CSI Controller   β”‚  β”‚ External          β”‚ β”‚
β”‚  β”‚ (Deployment)     β”‚  β”‚ Provisioner       β”‚ β”‚
β”‚  β”‚ - Provisioner    β”‚  β”‚ Snapshotter       β”‚ β”‚
β”‚  β”‚ - Attacher       β”‚  β”‚ Resizer           β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Per Node (DaemonSet)                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                        β”‚
β”‚  β”‚ CSI Node Plugin  β”‚                        β”‚
β”‚  β”‚ - Mount/Unmount  β”‚                        β”‚
β”‚  β”‚ - Format volume  β”‚                        β”‚
β”‚  β”‚ - Node stage     β”‚                        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Install CSI Driver (AWS EBS Example)

# AWS EBS CSI Driver
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 \
  -n kube-system

# Verify
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver
kubectl get csidrivers
# NAME              ATTACHREQUIRED   PODINFOONMOUNT
# ebs.csi.aws.com   true            false

Install NFS CSI Driver

helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs \
  -n kube-system

# Create StorageClass for NFS
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
  server: nfs.example.com
  share: /exports/kubernetes
reclaimPolicy: Delete
volumeBindingMode: Immediate
mountOptions:
  - nfsvers=4.1
  - hard
EOF

StorageClass with CSI

# AWS EBS gp3
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-gp3
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  encrypted: "true"
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

---
# GCP PD CSI
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: pd-ssd
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

Volume Snapshots

# VolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: ebs-snapshot-class
driver: ebs.csi.aws.com
deletionPolicy: Delete

---
# Create snapshot
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: db-snapshot
spec:
  volumeSnapshotClassName: ebs-snapshot-class
  source:
    persistentVolumeClaimName: postgres-data

---
# Restore from snapshot
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data-restored
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: ebs-gp3
  resources:
    requests:
      storage: 50Gi
  dataSource:
    name: db-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io

Volume Cloning

# Clone existing PVC (CSI required)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data-clone
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: ebs-gp3
  resources:
    requests:
      storage: 50Gi
  dataSource:
    name: postgres-data          # Source PVC
    kind: PersistentVolumeClaim
DriverProvisionerUse Case
AWS EBSebs.csi.aws.comBlock storage on AWS
GCP PDpd.csi.storage.gke.ioBlock storage on GCP
Azure Diskdisk.csi.azure.comBlock storage on Azure
NFSnfs.csi.k8s.ioNFS shares (RWX)
Ceph RBDrbd.csi.ceph.comCeph block storage
CephFScephfs.csi.ceph.comCeph filesystem (RWX)
Longhorndriver.longhorn.ioDistributed storage
OpenEBScstor.csi.openebs.ioContainer-native storage

Common Issues

β€œdriver not found” when creating PVC

CSI driver not installed. Check: kubectl get csidrivers. Install the appropriate driver for your storage backend.

Volume stuck in β€œAttaching”

Node-level CSI plugin (DaemonSet) not running. Check: kubectl get pods -n kube-system -l app=csi-node.

Snapshot β€œnot ready”

VolumeSnapshotClass driver doesn’t match PVC’s StorageClass provisioner. They must use the same CSI driver.

Best Practices

  • Use CSI drivers over in-tree plugins β€” in-tree are deprecated
  • Enable volume expansion β€” allowVolumeExpansion: true on StorageClass
  • WaitForFirstConsumer β€” binds volume to pod’s node for topology awareness
  • Regular snapshots β€” automated backup via CronJob + VolumeSnapshot
  • Test restore procedures β€” snapshots are useless if restore doesn’t work

Key Takeaways

  • CSI is the standard interface for Kubernetes storage plugins
  • Install CSI driver β†’ create StorageClass β†’ use PVCs as normal
  • CSI enables snapshots, cloning, and expansion not available with in-tree drivers
  • Volume snapshots provide point-in-time backup with CSI
  • WaitForFirstConsumer binding mode is essential for topology-aware provisioning
#csi #storage #persistent-volumes #snapshots #drivers
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens