Challenge, Medium,  on  Kubernetes

Kubernetes - Dynamic Provisioning with StorageClass

A StorageClass names a provisioner and carries provisioning settings. If a PVC has no storageClassName, the DefaultStorageClass admission controller adds the cluster default to it on creation.

This challenge uses local-path, the built-in provisioner in k3s.


Task 1 - Omit storageClassName

When a PVC omits storageClassName, the admission controller fills in the cluster default for it.

Check which class is the default:

kubectl get storageclass

Steps:

  • Create a PVC named pvc-default without a storageClassName field, capacity 1Gi, access mode ReadWriteOnce
  • Inspect spec.storageClassName on the created PVC and confirm local-path was injected

Task 2 - Explicit storageClassName

When a PVC sets storageClassName to a named class, the admission controller does not inject anything.

A StorageClass field called volumeBindingMode controls when the volume gets created. The local-path class in this cluster is set to wait for a pod to request the PVC first. You will see this field again later in this challenge.

Steps:

  • Create a PVC named pvc-local-path with storageClassName: local-path set explicitly, capacity 1Gi, access mode ReadWriteOnce
  • Confirm spec.storageClassName is local-path

Task 3 - Switching the Default StorageClass

The default StorageClass is just a regular StorageClass with the storageclass.kubernetes.io/is-default-class: "true" annotation. Anyone can move that annotation to a different class, changing the default. Switching it requires setting the annotation to "true" on the new class and "false" on the old one. Any PVC created without storageClassName after the swap picks up the new default at admission time.

When more than one StorageClass carries the is-default-class: "true" annotation, the admission controller picks the most recently created one for new PVCs that omit storageClassName. The official recommendation is to keep only one class marked as default.

Steps:

  • Create a StorageClass sc-default-new with provisioner: rancher.io/local-path, volumeBindingMode: WaitForFirstConsumer, and the storageclass.kubernetes.io/is-default-class annotation set to "true"
  • Set is-default-class to "false" on the existing local-path StorageClass. Try kubectl annotate instead of editing the object by hand
  • Create a PVC pvc-default-2 with no storageClassName, capacity 1Gi, access mode ReadWriteOnce
  • Verify the admission controller injected sc-default-new instead of local-path

Task 4 - Find the Volume on the Node

The local-path provisioner creates a directory on the node and stores its path in the PV spec. That directory is what the pod sees as its mounted volume.

Steps:

  • Create a pod disk-view-pod (image busybox, command sleep 3600) that mounts pvc-default (from Task 1) at /data
  • Get the host directory path from the PV spec. This is the same directory local-path mounts into the pod as /data
  • Log in to cplane-01, go to that path, and write a file named from-node.txt there from the node's shell, not through the pod
  • Exec into the pod and verify the file appears under /data, written from the node side