๐Ÿ“– Read-only preview โ€” lessons, diagrams, and quizzes only. The hands-on labs, live grading, and progress tracking require running the real course locally against a Kubernetes cluster.Run it locally โ†’

Module 7 ยท Lesson 7.1

Volumes, PersistentVolumes & PersistentVolumeClaims

Everything you've run so far has been stateless โ€” delete the pod, nobody cares what was on disk. Real apps (databases, caches, file uploads) need data to outlive the pod that wrote it. Kubernetes gives you two very different tools for this, and mixing them up is a common source of confusion.

Ephemeral: the Volume

A plain Volume (like emptyDir) is a directory whose lifecycle is tied to the Pod, not any single container. Two containers in one Pod can share an emptyDir to pass data between them โ€” but delete the Pod, and it's gone. No different, really, from a scratch directory on a traditional VM that gets wiped on reboot.

Persistent: PV and PVC

A PersistentVolume (PV) is a piece of real storage โ€” a cloud disk, an NFS share, a local path โ€” with a lifecycle independent of any Pod. A PersistentVolumeClaim (PVC) is a request for storage ("1Gi, ReadWriteOnce") that gets matched (bound) to a PV satisfying it. Your Pod never touches a PV directly; it mounts a PVC, and the PVC is what's bound to a PV behind the scenes.

This indirection is deliberate: the same PVC spec works whether the cluster provisions an AWS EBS volume, a GCP disk, or (as in your lab) a path on a kind node โ€” the Pod's manifest doesn't change.

Dynamic provisioning, and why claims get stuck

Almost nobody hand-creates PVs anymore. A StorageClass (next lesson) tells the cluster how to automatically create a PV the moment a matching PVC shows up โ€” that's dynamic provisioning, and it's what you've been relying on implicitly every time a PVC bound instantly.

PVC โ†’ StorageClass โ†’ PV

PVC: dataReadWriteOnce
โ†’
StorageClass: standardprovisioner: local-pathsupports: RWO only
โ†’
PV provisionedBound
A PVC doesn't ask for a disk, it asks for a shape of storage. The StorageClass's provisioner either can or can't produce that shape โ€” if it can't, the claim just sits Pending, with no error anywhere except one Event.

When a PVC's request can't actually be satisfied โ€” an access mode the provisioner doesn't support, more capacity than exists, a StorageClass that doesn't exist โ€” it doesn't error. It just sits Pending, forever, silently. This is exactly the "PVC stuck Pending" failure you'll diagnose in the lab, and it's a genuinely common real-world ticket.

The infrastructure analogy

An emptyDir is local scratch disk on an instance. A PV/PVC pair is much closer to attaching an EBS volume or an NFS mount โ€” storage that exists as its own resource, survives the compute being replaced, and gets attached/detached rather than created fresh each time.

In the lab, you'll feel the ephemeral case directly, then diagnose a claim stuck Pending the way you'd diagnose it on a real cluster: by reading the one event that tells you exactly what's wrong.

๐Ÿงช Lab: lab-13-volumes-pv-pvc

Preview only

Goal

Feel the difference between a volume that dies with its pod and one that outlives it, then diagnose and fix a PVC stuck Pending โ€” one of the most common "why is my pod not starting" tickets you'll get in real clusters.

Tasks

Part 1 โ€” ephemeral volume

  1. Apply manifests/emptydir-pod.yaml: kubectl apply -f manifests/emptydir-pod.yaml
  2. Confirm both containers in scratch-writer share data: kubectl exec -n lab-13-volumes-pv-pvc scratch-writer -c reader -- cat /scratch/log.txt
  3. Delete the pod: kubectl delete pod scratch-writer -n lab-13-volumes-pv-pvc โ€” that emptyDir is gone with it. Nothing persists it; that's the point.

Part 2 โ€” a PVC stuck Pending

  1. Apply the broken claim: kubectl apply -f manifests/pvc-and-pod.yaml
  2. Check status: kubectl get pvc,pod -n lab-13-volumes-pv-pvc โ€” both data and writer are stuck Pending.
  3. Find out why: kubectl describe pvc data -n lab-13-volumes-pv-pvc โ€” read the Events at the bottom carefully, they name the exact problem.
  4. Check what the cluster's default StorageClass actually supports: kubectl get storageclass standard -o yaml (look at provisioner).
  5. Fix manifests/pvc-and-pod.yaml so the claim can actually be satisfied, then kubectl delete -f manifests/pvc-and-pod.yaml && kubectl apply -f manifests/pvc-and-pod.yaml.
  6. Confirm: kubectl get pvc,pod -n lab-13-volumes-pv-pvc โ€” data is Bound, writer is Running.

Check

Run the check once writer is Running and data is Bound.

This lab runs against a real local Kubernetes cluster with an automated grader โ€” clone the repo and run make start to do it for real.

๐Ÿ“ Quiz

1. Two containers in the same Pod share an `emptyDir` volume. What happens to that data when the Pod is deleted?

2. What does a Pod actually mount โ€” a PersistentVolume directly, or a PersistentVolumeClaim?

3. A PVC requests `ReadWriteMany` from a StorageClass whose provisioner only supports `ReadWriteOnce`. What's the symptom?scenario

4. Why doesn't a Pod's manifest need to change when storage moves from a local kind cluster to AWS EBS?

5. You SSH onto a kind node and look for the PVC. You won't find it as a literal disk โ€” why?scenario

Progress isn't saved in this preview โ€” run the course locally to track completion and grade labs for real.