StorageClass and Dynamic Provisioning
CKA Exam Domain 4 — StorageClass definition, dynamic PV provisioning, CSI drivers, default StorageClass
← Back to CKA Practice Index StorageClass provides administrators with a way to describe "classes" of storage, enabling dynamic PV provisioning and avoiding the need for manual PV pre-provisioning.
1. StorageClass Definition and Provisioner
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
encrypted: "true"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate
Core fields:
| Field | Description |
|---|---|
provisioner | Name of the storage backend driver |
parameters | Parameters passed to the provisioner |
reclaimPolicy | Reclaim policy for dynamically created PVs (Delete or Retain) |
allowVolumeExpansion | Whether to allow PVC expansion |
volumeBindingMode | Binding mode (Immediate or WaitForFirstConsumer) |
mountOptions | Mount options |
2. Dynamic PV Provisioning Principles
- User creates PVC (specifying
storageClassName: fast) - Kubernetes control plane finds the corresponding StorageClass
- Calls the StorageClass provisioner to create storage resources
- Automatically creates a PV and binds it to the PVC
- Pod uses PVC to mount storage
User (PVC) ──► StorageClass ──► Provisioner ──► Actual Storage ──► PV
3. Default StorageClass
After setting a default StorageClass, creating a PVC without specifying storageClassName will automatically use the default StorageClass.
# View the current default StorageClass
kubectl get storageclass
# Set a StorageClass as default
kubectl patch storageclass standard -p \
'{"metadata": {"annotations": {"storageclass.kubernetes.io/is-default-class": "true"}}}'
metadata:
annotations:
storageclass.kubernetes.io/is-default-class: "true"
Note:
storageClassName: ""in a PVC means not using the default StorageClass, but using a static PV instead.
4. Common Provisioners
AWS EBS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: aws-ebs-gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
fsType: ext4
encrypted: "true"
iopsPerGB: "10"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
GCE PD
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gce-pd-ssd
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd
replication-type: none
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
Azure Disk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azure-disk
provisioner: disk.csi.azure.com
parameters:
skuname: Premium_LRS
cachingMode: ReadOnly
reclaimPolicy: Delete
allowVolumeExpansion: true
NFS (via CSI)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
server: nfs-server.example.com
share: /exports
reclaimPolicy: Delete
volumeBindingMode: Immediate
mountOptions:
- hard
- nfsvers=4.1
5. volumeBindingMode
| Mode | Description |
|---|---|
Immediate | Create PV and bind immediately after PVC creation |
WaitForFirstConsumer | Wait until the first Pod uses the PVC before creating PV (AZ-aware based on Pod scheduling) |
WaitForFirstConsumer is commonly used in multi-cloud/multi-AZ environments to ensure the PV is created in the same availability zone as the Pod.
6. volumeBindingMode Comparison
# Delayed binding: PV is created in the AZ where the Pod is scheduled
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: regional-ssd
provisioner: pd.csi.storage.gke.io
volumeBindingMode: WaitForFirstConsumer
7. CSI Driver Concepts and Usage
CSI (Container Storage Interface) is the recommended storage plugin mechanism for Kubernetes.
Advantages:
- Plugins do not need to be compiled into Kubernetes binaries
- Deployed via DaemonSet, hot-pluggable
- Supports snapshots, expansion, cloning, and other advanced features
# View installed CSI drivers
kubectl get csidriver
# View CSI node status
kubectl get csinodes
8. Useful Commands
# View all StorageClasses
kubectl get sc
kubectl get storageclass
# View StorageClass details
kubectl describe sc <storage-class-name>
# Create StorageClass (from YAML)
kubectl create -f sc.yaml
# Delete StorageClass
kubectl delete sc <storage-class-name>
# Check default StorageClass
kubectl get sc -o jsonpath='{.items[*].metadata.annotations.storageclass\.kubernetes\.io/is-default-class}'
9. Exam Key Points
- PVC without
storageClassName= uses default StorageClass - PVC with
storageClassName: ""= uses static PV (manually created) WaitForFirstConsumeris very important in topology-aware environments- Dynamic PV
reclaimPolicydefaults toDelete - CSI is the currently recommended official storage extension method
🧪 Complete Hands-on Example: Dynamically Creating PVs Using StorageClass
Scenario
Define a StorageClass and use it to automatically create PVs, observing the complete dynamic provisioning process and the effect of the reclaim policy (Delete).
Prerequisites
- The cluster needs a CSI driver provisioner (e.g.,
ebs.csi.aws.com,pd.csi.storage.gke.io, etc.) - If using minikube, enable the
standardStorageClass; the following example uses the localstandardas a simulation
Steps
Step 1: View Existing StorageClasses in the Cluster
kubectl get sc
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
# standard (default) k8s.io/minikube-hostpath Delete Immediate false 15d
Step 2: Create a Custom StorageClass
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
provisioner: k8s.io/minikube-hostpath
parameters:
type: pd-ssd
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
EOF
kubectl get sc
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
# fast-storage k8s.io/minikube-hostpath Delete Immediate true 5s
# standard (default) k8s.io/minikube-hostpath Delete Immediate false 15d
Step 3: Create a PVC Referencing This StorageClass
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: fast-storage
EOF
Step 4: Observe the PV Being Dynamically Created
kubectl get pvc
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
# dynamic-pvc Bound pvc-8f3b2c1d-... 1Gi RWO fast-storage 10s
kubectl get pv
# NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS AGE
# pvc-8f3b2c1d-... 1Gi RWO Delete Bound default/dynamic-pvc fast-storage 10s
The PV name is a dynamically generated UUID format, and RECLAIM POLICY automatically inherits Delete from the StorageClass.
Step 5: View Detailed Information of the Dynamic PV
kubectl describe pv pvc-8f3b2c1d-...
# ...
# Source:
# Type: HostPath (bare host directory volume)
# Path: /data/hostpath-provisioner/default/dynamic-pvc
# ...
# Reclaim Policy: Delete
# StorageClass: fast-storage
Step 6: Delete PVC and Observe PV Auto-Deletion
kubectl delete pvc dynamic-pvc
kubectl get pvc
# No resources found in default namespace.
kubectl get pv
# (the previously dynamically created PV has been automatically deleted, not displayed)
Due to reclaimPolicy: Delete, the associated PV is automatically deleted after PVC deletion, no manual intervention required.
Verification
# Verify the StorageClass was created successfully
kubectl get sc fast-storage -o jsonpath='{.provisioner}'
# k8s.io/minikube-hostpath
# Verify the PVC references the correct StorageClass
kubectl get pvc dynamic-pvc -o jsonpath='{.spec.storageClassName}'
# fast-storage
# Verify the dynamic PV reclaim policy
kubectl get pv -o jsonpath='{.items[0].spec.persistentVolumeReclaimPolicy}'
# Delete
Exam Tips
- A PVC without
storageClassNameuses the cluster's default StorageClass - A PVC with
storageClassName: ""means using a static PV, dynamic provisioning not enabled - Dynamic PV reclaim policy defaults to
Delete; change toRetainif you want to preserve data - In
WaitForFirstConsumermode, the PVC STATUS remainsPendingafter creation until the first Pod uses it - In the exam, if a dynamic provisioning scenario appears, remember to check whether the
StorageClassprovisioner matches