Stage 5 · Platform
Networking, Storage & Service Mesh
CSI & Persistent Storage
Volume lifecycle, snapshots, expansion, and topologies.
CSI Architecture
CSI (Container Storage Interface) is the standard for integrating storage systems with Kubernetes. A CSI driver consists of a controller (manages volumes) and a node plugin (mounts volumes on nodes). Storage vendors implement CSI drivers for their specific systems.
CSI Controller (Deployment)
- CreateVolume: Provision new volumes
- DeleteVolume: Remove volumes
- ControllerPublish: Attach volume to node
- ControllerUnpublish: Detach volume
- CreateSnapshot: Create volume snapshots
- RestoreSnapshot: Restore from snapshot
CSI Node Plugin (DaemonSet)
- NodeStageVolume: Format and mount to staging dir
- NodePublishVolume: Mount from staging to pod path
- NodeUnpublishVolume: Unmount from pod
- NodeGetCapabilities: Report node capabilitiesThe controller runs as a Deployment (one active replica with leader election). The node plugin runs as a DaemonSet on every node. They communicate via gRPC with the kube-controller-manager and kubelet.
Volume Lifecycle
CSI volumes go through a defined lifecycle: provisioning, attaching, mounting, using, unmounting, detaching, and deletion. Each step is handled by a different CSI operation. Understanding this lifecycle helps debug storage issues.
- Provisioning — CSI controller creates the volume in the storage system
- Attaching — Controller attaches the volume to the target node (cloud API call)
- Staging — Node plugin formats and mounts to a staging directory
- Publishing — Node plugin bind-mounts from staging to the pod's volume mount path
- Usage — Application reads/writes data
- Unpublishing — Node plugin unmounts from pod path
- Detaching — Controller detaches volume from node
- Deletion — CSI controller deletes the volume from storage system
Dynamic Provisioning
Dynamic provisioning automatically creates storage volumes when a PVC is created. The StorageClass defines which CSI driver and parameters to use. When a PVC references a StorageClass, Kubernetes calls the CSI driver to create the volume.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
namespace: production
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 50Gi
selector:
matchLabels:
tier: productionThe PVC references StorageClass fast-ssd. Kubernetes finds the CSI driver for that StorageClass and calls CreateVolume. The resulting PV is automatically bound to this PVC.
WaitForFirstConsumer delays binding until a pod using the PVC is scheduled. This ensures the volume is created in the same zone as the pod. Immediate (default) binds immediately, which can cause zone mismatch issues in multi-zone clusters.
Volume Snapshots
Volume snapshots capture the state of a volume at a point in time. They are used for backups, cloning, and disaster recovery. The VolumeSnapshotClass defines which CSI driver and parameters to use for snapshots.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: app-data-snapshot
namespace: production
spec:
volumeSnapshotClassName: csi-snapclass
source:
persistentVolumeClaimName: app-data
---
# Restore from snapshot
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-restored
namespace: production
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 50Gi
dataSource:
name: app-data-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.ioThe PVC uses dataSource to specify a VolumeSnapshot as the source. The CSI driver creates a new volume initialized with the snapshot data. The restored volume must be at least as large as the snapshot.
Volume Expansion
Volume expansion allows growing a PVC without deleting and recreating it. The StorageClass must set allowVolumeExpansion: true. Expansion works for both online (while mounted) and offline (while detached) depending on the CSI driver.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: expandable
provisioner: ebs.csi.aws.com
allowVolumeExpansion: true # Required for expansion
parameters:
type: gp3
reclaimPolicy: Retain
---
# Expand PVC from 50Gi to 100Gi
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: expandable
resources:
requests:
storage: 100Gi # Changed from 50GiUpdate the PVC's storage request to the new size. Kubernetes calls the CSI driver's ControllerExpandVolume and NodeExpandVolume operations. Online expansion happens while the volume is mounted — no downtime.
Volume Topology
Volume topology ensures volumes are created in the same zone as the pods that use them. In multi-zone clusters, a volume in zone A cannot be attached to a node in zone B. The VolumeBindingMode and allowedTopologies fields control this behavior.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: zonal-fast
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
- key: topology.kubernetes.io/zone
values:
- us-east-1a
- us-east-1b
- us-east-1c
parameters:
type: gp3
encrypted: "true"WaitForFirstConsumer delays volume creation until a pod is scheduled. The volume is then created in the same zone as the pod. allowedTopologies restricts which zones are used. This prevents cross-zone attachment failures.
Use kubectl get pvc to see binding status. Pending with no PV means no matching PV exists. Pending with a PV means the PV is being provisioned. Bound means the PVC is ready to use. Check Events for binding errors.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.