How Do StorageClasses and Dynamic Provisioning Work?
A StorageClass defines a 'class' of storage with a specific provisioner, parameters, and reclaim policy. When a PVC references a StorageClass, Kubernetes dynamically provisions a PersistentVolume without manual intervention. This eliminates the need for administrators to pre-create PVs.
Detailed Answer
What Is a StorageClass?
A StorageClass is a cluster-level resource that describes a type of storage. It defines three key things:
- Provisioner: Which storage plugin creates volumes (e.g.,
ebs.csi.aws.com,pd.csi.storage.gke.io). - Parameters: Provider-specific settings (disk type, IOPS, replication).
- Reclaim Policy: What happens to the PV when the PVC is deleted.
Defining StorageClasses
AWS EBS (gp3)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
GCP Persistent Disk (SSD)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ssd
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd
replication-type: regional-pd
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
NFS (via external provisioner)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs
provisioner: nfs.csi.k8s.io
parameters:
server: 192.168.1.100
share: /exports/kubernetes
reclaimPolicy: Delete
mountOptions:
- hard
- nfsvers=4.1
How Dynamic Provisioning Works
- A PVC is created with
storageClassName: fast. - The PV controller sees no existing PV that matches.
- It calls the provisioner specified in the
fastStorageClass. - The provisioner (CSI driver) creates the actual storage (e.g., an EBS volume in AWS).
- A PV object is automatically created and bound to the PVC.
# Create a PVC
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: database-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: fast
EOF
# Watch the PV get created automatically
kubectl get pv -w
# Check the PVC is bound
kubectl get pvc database-storage
The Default StorageClass
One StorageClass can be marked as the default. PVCs that omit the storageClassName field will use it:
# Check which StorageClass is default
kubectl get storageclass
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE AGE
# fast (default) ebs.csi.aws.com Delete WaitForFirstConsumer 30d
# nfs nfs.csi.k8s.io Delete Immediate 30d
# Set a StorageClass as default
kubectl patch storageclass fast -p \
'{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
# Remove default designation
kubectl patch storageclass fast -p \
'{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
If a PVC explicitly sets storageClassName: "" (empty string), it opts out of dynamic provisioning and only binds to PVs with no StorageClass.
Volume Binding Modes
Immediate (default)
The PV is provisioned as soon as the PVC is created. This can cause problems with topology-constrained storage because the PV might be created in a different zone than where the Pod will run.
WaitForFirstConsumer
The PV is not provisioned until a Pod using the PVC is scheduled. The scheduler considers the Pod's constraints (node affinity, topology spread) and provisions the volume in the correct zone.
volumeBindingMode: WaitForFirstConsumer # Always use this for zone-aware storage
Reclaim Policies on StorageClasses
| Policy | Behavior | |---|---| | Delete | PV and underlying storage are deleted when PVC is removed | | Retain | PV enters Released state; storage is preserved for manual recovery |
# Important: changing a StorageClass reclaim policy only affects NEW PVs
# Existing PVs keep their original reclaim policy
# To change an existing PV's reclaim policy:
kubectl patch pv pvc-abc123 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
Multiple Storage Tiers
A well-designed cluster offers multiple StorageClasses for different workload needs:
kubectl get storageclass
# NAME PROVISIONER TYPE IOPS THROUGHPUT
# standard ebs.csi.aws.com gp3 3000 125 MiB/s
# fast-ssd ebs.csi.aws.com io2 10000 500 MiB/s
# archive ebs.csi.aws.com sc1 250 n/a
# shared-nfs nfs.csi.k8s.io NFS n/a n/a
Developers select the tier that matches their performance requirements:
# High-performance database
storageClassName: fast-ssd
# Log archive
storageClassName: archive
# Shared configuration files
storageClassName: shared-nfs
Troubleshooting Dynamic Provisioning
# PVC stuck in Pending? Check events:
kubectl describe pvc database-storage
# Common issues:
# - CSI driver not installed
# - Provisioner cannot create storage (permissions, quota)
# - StorageClass name misspelled
# - WaitForFirstConsumer: PVC stays Pending until a Pod is scheduled
# Check CSI driver is running
kubectl get pods -n kube-system | grep csi
# Check CSI driver logs
kubectl logs -n kube-system -l app=ebs-csi-controller
Why Interviewers Ask This
Interviewers want to verify you can set up automated storage provisioning in production and understand how different storage tiers are configured.
Common Follow-Up Questions
Key Takeaways
- StorageClasses automate PV creation through dynamic provisioning
- Each StorageClass specifies a provisioner and storage parameters
- The default StorageClass is used when PVCs omit the storageClassName