CKA — StorageClasses
CKA Exam Domain
Storage — 10%
StorageClasses enable dynamic provisioning of PersistentVolumes. Instead of an admin manually creating PVs, a StorageClass tells Kubernetes how to create them on demand when a PVC is submitted.
What Is a StorageClass?
A StorageClass provides a way to describe the “classes” of storage available in your cluster. Different classes might map to different quality-of-service levels, backup policies, or provisioner types.
Without StorageClasses:
Admin creates PV → User creates PVC → Kubernetes binds them
With StorageClasses:
Admin creates StorageClass → User creates PVC → Kubernetes auto-creates PV → Binding happens
This is called dynamic provisioning — and it is how most production clusters operate.
StorageClass Spec
Here is a complete StorageClass definition:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
Key fields:
| Field | Description |
|---|---|
provisioner |
The volume plugin used to create PVs (e.g., CSI driver, cloud provider) |
volumeBindingMode |
When PV binding and provisioning occur |
reclaimPolicy |
What happens to dynamically provisioned PVs when PVCs are deleted |
parameters |
Provisioner-specific settings (disk type, IOPS, etc.) |
Exam tip: Note the API group —
apiVersion: storage.k8s.io/v1, notv1. This is a common mistake on the exam.
Dynamic Provisioning
The dynamic provisioning flow:
- Admin creates a StorageClass with a provisioner
- User creates a PVC referencing the StorageClass
- Kubernetes calls the provisioner to create a PV matching the PVC request
- The PV is automatically bound to the PVC
# StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
# PVC referencing the StorageClass
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: standard
Note:
kubernetes.io/no-provisionerdoes not support dynamic provisioning — it requires pre-created PVs. This provisioner is commonly used in CKA exam environments withhostPathvolumes. For actual dynamic provisioning, you would use a CSI driver or cloud provisioner.
StorageClass Parameters
Parameters are specific to the provisioner. Here are some examples:
AWS EBS Example
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
fsType: ext4
iops: "3000"
throughput: "125"
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
GCE PD Example
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ssd
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
Default StorageClass
A default StorageClass is used when a PVC does not specify a storageClassName. You mark a StorageClass as default using an annotation:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
Behavior:
- PVCs without
storageClassName→ use the default StorageClass - PVCs with
storageClassName: ""(empty string) → no StorageClass, only binds to PVs with no class - Only one StorageClass should be marked as default per cluster
Check the default StorageClass:
kubectl get storageclass
The default class shows (default) next to its name:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE AGE
standard (default) kubernetes.io/no-provisioner Delete WaitForFirstConsumer 5d
fast kubernetes.io/no-provisioner Delete WaitForFirstConsumer 2d
volumeBindingMode
This field controls when PV binding and dynamic provisioning happen:
| Mode | Description | When to Use |
|---|---|---|
Immediate |
PV is bound as soon as PVC is created | When storage is available from any node (e.g., network-attached storage) |
WaitForFirstConsumer |
PV binding is delayed until a Pod using the PVC is scheduled | When storage is topology-dependent (e.g., local disks, zone-specific volumes) |
Why WaitForFirstConsumer matters:
- Prevents PV from being provisioned in a different zone than where the Pod runs
- Ensures the scheduler can consider storage constraints when placing the Pod
- Recommended for most use cases
Exam tip: If you see a PVC stuck in
Pendingand the StorageClass hasWaitForFirstConsumer, it might be waiting for a Pod to be created — this is expected behavior, not an error.
Provisioners Comparison
| Provisioner | Type | Dynamic Provisioning | Notes |
|---|---|---|---|
kubernetes.io/no-provisioner |
Local | No | Requires pre-created PVs, common in CKA exam |
kubernetes.io/aws-ebs |
AWS | Yes (in-tree, deprecated) | Use ebs.csi.aws.com instead |
ebs.csi.aws.com |
AWS | Yes (CSI) | AWS EBS CSI driver |
pd.csi.storage.gke.io |
GCP | Yes (CSI) | GCE Persistent Disk CSI driver |
disk.csi.azure.com |
Azure | Yes (CSI) | Azure Disk CSI driver |
rancher.io/local-path |
Local | Yes | Used in k3s, kind, and some CKA environments |
kubectl Commands
Essential StorageClass commands for the exam:
# List all StorageClasses
kubectl get storageclass
kubectl get sc # shorthand
# Describe a StorageClass
kubectl describe storageclass fast
# Get StorageClass in YAML format
kubectl get sc fast -o yaml
# Delete a StorageClass
kubectl delete sc fast
Practice Questions
Q1. Create a StorageClass named local-storage with provisioner kubernetes.io/no-provisioner and volumeBindingMode WaitForFirstConsumer.
Show Answer
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
kubectl apply -f local-storage.yaml
kubectl get sc local-storage
Q2. What is the difference between Immediate and WaitForFirstConsumer volume binding modes?
Show Answer
- Immediate: PV is bound to the PVC as soon as the PVC is created, regardless of whether a Pod is using it. This can lead to topology issues if the PV is provisioned in a different zone than where the Pod runs.
- WaitForFirstConsumer: PV binding is delayed until a Pod using the PVC is scheduled. This ensures the PV is provisioned in the correct topology (zone, node) for the Pod.
WaitForFirstConsumer is the recommended mode for most scenarios.
Q3. How do you set a StorageClass as the default?
Show Answer
Add the annotation storageclass.kubernetes.io/is-default-class: "true" to the StorageClass:
kubectl patch storageclass <name> -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
Or in the YAML:
metadata:
annotations:
storageclass.kubernetes.io/is-default-class: "true"
Only one StorageClass should be marked as default per cluster.
Q4. A PVC with storageClassName: "" (empty string) is created. Which PVs can it bind to?
Show Answer
A PVC with storageClassName: "" will only bind to PVs that have no storageClassName set. It explicitly opts out of dynamic provisioning and will not use the default StorageClass.
This is different from omitting storageClassName entirely, which causes the PVC to use the default StorageClass.
Q5. Why does kubernetes.io/no-provisioner not support dynamic provisioning?
Show Answer
The no-provisioner is designed for local volumes and pre-created PVs. It tells Kubernetes that PVs using this StorageClass must be manually created by the admin — the provisioner will not automatically create them when a PVC is submitted.
This is commonly used in CKA exam environments where hostPath PVs are pre-created. The StorageClass still serves a purpose: it groups PVs and enables WaitForFirstConsumer binding mode.