Home › CKA › Topics › Practice tasks › Storage Provisioning
CKA · Storage

Storage Provisioning

Create a new StorageClass named local-storage with the provisioner rancher.io/local-path. Set volumeBindingMode to WaitForFirstConsumer. Do not make it the default SC.

Check live lab access → All CKA tasks

Live lab access

This task description is public. Its live lab requires full access; six other CKA labs are available in Free Practice with AI Lab Coach.

Create an account to continue →

Explore the six free labs with AI Lab Coach →

Read the brief on any device. Use a desktop or laptop for the terminal lab. Nothing starts until you choose Start.

The task

Create a new StorageClass named local-storage with the provisioner rancher.io/local-path. Set volumeBindingMode to WaitForFirstConsumer. Do not make it the default SC.

Patch the StorageClass to make it the default StorageClass.

Ensure local-storage is the only default class.

Do not modify any existing Deployments or PersistentVolumeClaims.

Original Prepium workshop · Tested on Kubernetes v1.35.0 on 1 October 2026 in a three-node kind cluster, which ships the rancher.io/local-path provisioner and a default class named standard. Use a disposable cluster: this workshop changes which StorageClass is the cluster default, and the cleanup step changes it back.

StorageClasses, WaitForFirstConsumer, and owning the default class

A StorageClass tells Kubernetes how to create a volume when a claim asks for one: which provisioner to call, what to do with the volume when the claim is deleted, and when to provision. The default class is simply the one whose storageclass.kubernetes.io/is-default-class annotation is "true"; claims that omit storageClassName receive it at admission.

1. Look before you change anything

kubectl get storageclass
kubectl get storageclass -o custom-columns=NAME:.metadata.name,DEFAULT:.metadata.annotations.storageclass\.kubernetes\.io/is-default-class

The (default) marker in the first command is derived from that annotation. The second command shows the raw value, which is what you edit.

2. Create a class that waits for a consumer

Save this as storageclass-wffc.yaml. It defines a new class and a claim that uses it.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: tutorial-local
provisioner: rancher.io/local-path
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: scratch
  namespace: prepium-tutorial
spec:
  storageClassName: tutorial-local
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Mi
kubectl create namespace prepium-tutorial
kubectl apply -f storageclass-wffc.yaml
kubectl -n prepium-tutorial get pvc scratch
kubectl -n prepium-tutorial describe pvc scratch

The claim is Pending, and that is correct. The event reads waiting for first consumer to be created before binding. With volumeBindingMode: WaitForFirstConsumer, provisioning is delayed until a Pod using the claim is scheduled, so the volume can be created on the node where that Pod will run. With Immediate, the volume is created first and the Pod must then fit wherever the volume landed. Do not "fix" this Pending state; give it a consumer.

kubectl -n prepium-tutorial run consumer --image=busybox:1.36 --restart=Never \
  --overrides='{"spec":{"containers":[{"name":"consumer","image":"busybox:1.36","command":["sleep","3600"],"volumeMounts":[{"name":"s","mountPath":"/s"}]}],"volumes":[{"name":"s","persistentVolumeClaim":{"claimName":"scratch"}}]}}'
kubectl -n prepium-tutorial wait --for=condition=Ready pod/consumer
kubectl -n prepium-tutorial get pvc scratch
kubectl get pv "$(kubectl -n prepium-tutorial get pvc scratch -o jsonpath='{.spec.volumeName}')" -o jsonpath='{.spec.nodeAffinity}{"\n"}'

Now the claim is Bound to a dynamically created PV, and that PV carries node affinity for the node the Pod was scheduled on.

3. Change the default safely

kubectl annotate storageclass tutorial-local storageclass.kubernetes.io/is-default-class=true --overwrite
kubectl get storageclass

Both classes now show (default). Kubernetes tolerates this: since v1.26, a claim without a class gets the most recently created default, which in our run was tutorial-local. It is still a configuration error, because which class wins depends on creation order and two people reading the cluster can reach different conclusions. Remove the flag from the old class:

kubectl annotate storageclass standard storageclass.kubernetes.io/is-default-class=false --overwrite
kubectl get storageclass

Exactly one class is marked (default). Changing the default does not touch existing claims: scratch keeps its class and its volume. The default only affects claims created afterwards.

Example checkEvidence
Class has the right provisioner and modePROVISIONER and VOLUMEBINDINGMODE columns
Exactly one defaultOne annotation value of "true" across all classes
Existing workloads untouchedExisting claims keep their storageClassName

Cleanup (restores the original default): kubectl annotate storageclass standard storageclass.kubernetes.io/is-default-class=true --overwrite, then kubectl delete namespace prepium-tutorial and kubectl delete storageclass tutorial-local. Reference: Storage Classes and changing the default StorageClass. Next, try binding a claim to a specific PV.

Exam
CKA
Domain
Storage
Grading
Programmatic · partial credit

What this tests

Configure persistent volumes, claims, storage classes, and volume access modes. On the CKA exam, Storage tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.

Practice it for real

The public description lets you study the task before signing up. Full access includes every live lab. Six selected CKA scenarios are included in Free Practice, with five shared sessions each week. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.

Related CKA tasks