# Storage Basics and Volumes

> Chapter 11 of the Courseiva CNCF-CKA curriculum — https://courseiva.com/learn/cncf-cka/storage-basics-and-volumes

**Official objective:** Storage - 10% — Understand volumes, persistent volumes, and persistent volume claims.

## Introduction

Kubernetes storage separates the container from the data it needs. This matters for the CKA exam because you must know how to make data survive a Pod crash, how to share files between containers, and how to allocate external storage to applications without rewriting your Pod definition every time.

## The Shared Warehouse Storage Locker Analogy

A busy city with a massive shared warehouse building in its centre. Inside are hundreds of identical metal storage lockers, each with a lock but no label. Tenants in the building next door — different shops, a dentist, a small bakery — all need to store things. The only rule is: no one can keep anything sitting out in the hallway because the hallway belongs to the warehouse owner, and it must stay clear for everyone.

Each shopkeeper walks in, picks an empty locker, puts a padlock on it, and piles in their boxes. That locker is their temporary cache — fast to access, but if the shopkeeper forgets to pay the monthly rental fee, the warehouse manager empties the locker and gives it to the next person. The shopkeeper has to re-pack everything from scratch. That temporary, speed-and-convenience storage is like a Kubernetes Pod's ephemeral volume.

Downstairs in the same warehouse, there is a separate, locked, fireproof room. A shopkeeper can rent a permanent crate in that room for a higher fee. The crate stays there even if the shopkeeper forgets to pay for a month. When the shopkeeper comes back, their crate is still there with all the flour and sugar inside. That permanent crate is like a PersistentVolume in Kubernetes — a stable, long-term storage resource that survives even if the shop (the Pod) gets evicted or rebuilt. A note from the warehouse office — the PersistentVolumeClaim — is the receipt that proves the shopkeeper has reserved that specific crate.

## Core explanation

In Kubernetes, a container inside a Pod has its own tiny filesystem. But containers are ephemeral — they come and go. When a container crashes or a Pod is deleted, all the files stored inside that container are gone. That is not acceptable for applications that need to keep data, like a database that must save customer orders or a web server that serves images.

To solve this, Kubernetes introduces the concept of volumes. A volume is a directory that is mounted into a container, but its data lives outside the container. The Pod specification declares which volumes are attached. Because the volume is separate from the container, the data survives even if the container restarts.

There are many types of volumes, but they fall into two broad categories: ephemeral volumes and persistent volumes. Ephemeral volumes (like emptyDir or ConfigMap) live exactly as long as the Pod. When the Pod is deleted, the ephemeral volume is erased. Persistent volumes (like hostPath, NFS, or cloud-provider volumes) are designed to keep data across Pod restarts and deletions.

A PersistentVolume (PV) is a piece of storage in the cluster that has been provisioned by an administrator. It is the actual storage resource — a disk from a cloud provider, an NFS share, or a local SSD on a node. Think of it as the physical storage locker itself.

A PersistentVolumeClaim (PVC) is a request for storage by a user. It specifies how much storage is needed and what access mode is required (ReadWriteOnce, ReadOnlyMany, or ReadWriteMany). The Kubernetes control plane matches a PVC to a suitable PV that can satisfy the request. Once matched, the PV is bound to that PVC, and the Pod can use the PVC to mount the storage into its containers.

Access modes are an important detail to understand.

- ReadWriteOnce (RWO): the volume can be mounted as read-write by a single node at a time.
- ReadOnlyMany (ROX): the volume can be mounted as read-only by many nodes simultaneously.
- ReadWriteMany (RWX): the volume can be mounted as read-write by many nodes at the same time.

Not every storage backend supports all three modes. For example, many cloud block storage services support only RWO, while NFS supports RWX.

Storage lifecycle is managed through reclaim policies. When a PVC is deleted, the PV it was bound to is released. The reclaim policy determines what happens to that PV: Retain keeps the volume and its data for manual reclamation, Delete removes the volume and its data automatically, and Recycle (deprecated in newer versions) scrubs the volume and makes it available again.

Dynamic provisioning is another key concept. Instead of an administrator pre-creating PVs, you can define a StorageClass. A StorageClass specifies a provisioner (like kubernetes.io/aws-ebs or kubernetes.io/gce-pd) that automatically creates a PV when a PVC is submitted. This makes storage management much more automated.

To summarise the process: a user creates a PVC specifying size and access mode. The control plane finds or creates a matching PV. The PVC and PV become bound. The Pod definition references the PVC. When the Pod starts, the volume is mounted into the container at the specified mount path.

## Real-world context

A small e-commerce company runs a Kubernetes cluster in a public cloud. The company has a single-node MySQL database Pod that stores product catalogue data. The cluster is running in an auto-scaling group, and occasionally a node fails and a new one spins up.

The database Pod writes its data files to the container's local filesystem. One day, the node running the database Pod goes down. The cluster reschedules the Pod onto a new node, but all the product data is gone. The company loses three days' worth of inventory updates. This is the problem persistent storage solves.

The IT team decides to fix this using persistent volumes and claims. They create a StorageClass named fast-ssd that provisions an AWS EBS volume with 50GB of space and a reclaim policy of Retain. Then they create a PersistentVolumeClaim named mysql-pvc, requesting 50GB of storage with access mode ReadWriteOnce. The StorageClass automatically provisions a matching PV.

Next, they edit the MySQL Pod YAML to include a volumes section that references mysql-pvc, and a volumeMounts section inside the container definition that mounts that volume at /var/lib/mysql. Now, when the Pod starts, the MySQL data is written to the EBS volume, not to the container's ephemeral filesystem.

Three weeks later, another node fails. The database Pod is recreated on a new node. The new node attaches the same EBS volume from the PVC. The MySQL data is still there — all the product inventory is safe.

The team later needs to take a backup of the database for disaster recovery. They can simply create a snapshot of the underlying EBS volume from the cloud console, independent of Kubernetes. The PVC and PV still reference the original volume, so the database continues working perfectly.

When the company decides to upgrade the database and test a new version, they create a new PVC that requests the same size and access mode, but with a different StorageClass that uses a slower, cheaper disk type. They point the old Pod to the new PVC, test the new version, and if everything works, they delete the old PV manually (Retain policy) to clean up unused storage resources.

The key actions an IT professional performs with storage in Kubernetes include:
- Creating StorageClass definitions to automate volume provisioning.
- Creating PersistentVolumeClaims in application namespaces.
- Configuring Pod volumes and volumeMounts in deployment manifests.
- Monitoring PV bound status and capacity via kubectl get pv and kubectl get pvc.
- Adjusting reclaim policies based on data retention requirements.
- Handling cross-namespace access to shared PVs when using ReadWriteMany storage backends.

## Exam focus

The CKA exam dedicates a significant 10% to storage, and this is one of the most straightforward sections if you understand the fundamentals. The exam expects you to be able to create, configure, and troubleshoot persistent storage in a Kubernetes cluster.

The most common question types include:
- Given a scenario, create a PersistentVolume with specific capacity, access mode, and a hostPath storage backend.
- Create a PersistentVolumeClaim that requests a certain amount of storage and binds to an existing PV.
- Configure a Pod to use a PVC, mount it at a specific path, and verify that the data persists after the Pod is deleted and recreated.
- Modify an existing deployment to use a PVC instead of emptyDir or hostPath.
- Inspect and troubleshoot PV/PVC binding failures due to mismatched labels, sizes, or access modes.

Traps to watch out for:
- The exam loves to test that the access mode of the PVC must match the access mode of the PV. If you create a PVC with ReadWriteOnce but the only available PV has ReadWriteMany, the PVC will remain Pending forever.
- Reclaim policies: candidates often forget to set the reclaim policy when using hostPath. The default reclaim policy is Retain for hostPath, but for many cloud providers it is Delete. Understand the difference and when each applies.
- Volume names: PV names must be unique across the cluster. PVC names must be unique within a namespace.
- StorageClass: if you do not specify a StorageClass in the PVC, the cluster uses the default StorageClass. If there is no default, the PVC stays Pending. The exam sometimes explicitly states 'do not use dynamic provisioning', meaning you must create PVs manually and omit the storageClassName field.
- hostPath volumes: these are intended for single-node testing only. In production, you should not use them. The exam does test hostPath, so remember that hostPath volumes have limitations: they do not work across nodes and are not suitable for multi-node deployments.

Key definitions to memorise:
- PV: cluster-wide storage resource.
- PVC: namespace-scoped request for storage.
- StorageClass: template for dynamic provisioning.
- accessModes: RWO, ROX, RWX.
- reclaimPolicy: Retain, Delete, Recycle.
- volumeMode: Filesystem (default) or Block.
- persistentVolumeReclaimPolicy: determines what happens to the PV after the PVC is deleted.
- hostPath: mounts a file or directory from the host node's filesystem into a Pod.

The exam also expects you to know how to inspect PV and PVC status using kubectl get pv and kubectl get pvc, and to recognise that a PVC in 'Pending' status usually indicates a binding issue. Use kubectl describe pvc <name> to see the events that explain why binding failed.

## Step by step

1. **Define the StorageClass** — Create a StorageClass YAML that specifies the provisioner (e.g., kubernetes.io/aws-ebs) and the reclaim policy. This template tells Kubernetes how to automatically create a PV when a PVC is submitted. Without this step, you must manually create PVs.
2. **Create the PersistentVolumeClaim** — Write a PVC YAML that requests a specific amount of storage (e.g., 10Gi) and an access mode (e.g., ReadWriteOnce). Optionally, specify a StorageClass name. This PVC is submitted to the cluster and triggers the dynamic provisioning process if a StorageClass is referenced.
3. **Automatic PV Creation (Binding)** — When the PVC is created, the control plane checks for a StorageClass with dynamic provisioning. If found, it creates a new PV that matches the PVC's request exactly. The PVC and PV become bound, and the PVC status changes from 'Pending' to 'Bound'.
4. **Configure the Pod to Use the PVC** — In your Pod or Deployment YAML, add a volumes section that references the PVC by name. Inside each container, add a volumeMounts section that defines the mount path (e.g., /data). This connects the storage to the container's filesystem at the specified location.
5. **Deploy and Verify Persistence** — Apply the Pod YAML. Write a test file to the mount path inside the container using kubectl exec. Delete the Pod and recreate it. Run kubectl exec again and check that the test file still exists in the mount path. This confirms the data survived the Pod deletion.

## Comparisons

### Ephemeral Volume (emptyDir) vs Persistent Volume (PV)

**Ephemeral Volume (emptyDir):**
- Lives only as long as the Pod exists.
- Data is deleted when the Pod is deleted.
- Does not require a PVC; defined directly in the Pod spec.
- 
- 
- 

**Persistent Volume (PV):**
- Lives independently of any Pod.
- Data persists across Pod restarts and deletions.
- Requires a PVC to be used by a Pod.
- 
- 
- 

### PersistentVolume (PV) vs PersistentVolumeClaim (PVC)

**PersistentVolume (PV):**
- Cluster-wide resource, not namespaced.
- Provisioned by an administrator or by dynamic provisioning.
- Contains capacity, access mode, and storage backend details.
- 
- 
- 

**PersistentVolumeClaim (PVC):**
- Namespaced resource, scoped to a specific namespace.
- Created by a user to request storage.
- Contains desired capacity, access mode, and optionally a StorageClass.
- 
- 
- 

### ReadWriteOnce (RWO) vs ReadWriteMany (RWX)

**ReadWriteOnce (RWO):**
- Volume can be mounted as read-write by one node at a time.
- Supported by most cloud block storage services (e.g., AWS EBS).
- Cannot be used by multiple Pods on different nodes simultaneously.
- 
- 
- 

**ReadWriteMany (RWX):**
- Volume can be mounted as read-write by many nodes simultaneously.
- Requires a shared filesystem like NFS or a cloud-native RWX solution.
- Suitable for shared configurations or applications that need concurrent writes.
- 
- 
- 

## Diagram

_This flowchart shows the lifecycle of a PersistentVolumeClaim, from creation through binding, Pod mounting, and data persistence across Pod deletions._

```mermaid
flowchart TD
    A[User creates PVC] --> B{Match found in cluster?}
    B --> |Yes| C[PVC bound to existing PV]
    B --> |No| D{StorageClass defined?}
    D --> |Yes| E[Dynamic provisioning creates PV]
    E --> C
    D --> |No| F[PVC remains Pending]
    C --> G[Pod mounts PVC at /mount/path]
    G --> H[Data persists beyond Pod lifecycle]
    H --> I[Pod deleted, PVC exists]
    I --> J[New Pod uses same PVC, data available]
```

## Common misconceptions

- **Misconception:** A container stores data permanently because it has its own filesystem. **Reality:** A container's filesystem is ephemeral. When the container stops or is deleted, all data in that filesystem is lost. Persistent volumes are required to store data beyond the container's life. (This misconception comes from a misunderstanding that containers are similar to virtual machines. In a VM, the disk persists unless explicitly deleted. Containers are designed to be stateless by default.)
- **Misconception:** All Kubernetes volumes are persistent by default. **Reality:** No. Many volume types like emptyDir, configMap, and secret are ephemeral — they exist only as long as the Pod runs. Only persistent volumes (PVs) backed by actual external storage are designed to survive Pod deletion. (Beginners hear the word 'volume' and assume it implies permanence. They do not distinguish between ephemeral and persistent volume types.)
- **Misconception:** A PVC automatically creates a PV with exactly the storage requested. **Reality:** A PVC is a request. It does not automatically create a PV unless a StorageClass with dynamic provisioning is defined. Without a StorageClass, the cluster must have a pre-existing PV that matches the request criteria. (The phrase 'persistent volume claim' sounds like 'I claim this storage', which implies immediate ownership. In reality, it is a request that may remain pending if no matching PV is available.)
- **Misconception:** A PV can be used directly by a Pod without a PVC. **Reality:** A PV cannot be used by a Pod directly. A Pod must reference a PVC, and that PVC must be bound to a PV. The PVC acts as the interface between the Pod and the PV. (The exam tests this distinction heavily. Beginners often try to skip the PVC and reference a PV name directly in a Pod spec, which results in an error.)
- **Misconception:** A PVC can be bound to any PV regardless of namespace. **Reality:** PVCs are namespaced — each exists in a specific namespace. PVs are cluster-wide resources not bound to any namespace. However, a PVC can only bind to a PV if the PVC's namespace has no effect on the binding. The PVC can access any PV that matches its criteria. (People assume that because PVCs are namespaced, they can only see PVs in the same namespace. But PVs are not namespaced, so a PVC in namespace 'app' can bind to any PV in the cluster.)
- **Misconception:** emptyDir volumes survive Pod restarts. **Reality:** emptyDir volumes survive container restarts within a Pod, but they do NOT survive Pod deletion. If the Pod is deleted, the emptyDir is removed. Persistent volumes are needed for data to survive Pod deletion. (This is a very common exam trap. emptyDir is ephemeral at the Pod level, but since it does survive container crashes, beginners incorrectly assume it is persistent.)

## Key takeaways

- Containers are ephemeral; any data written to the container's filesystem is lost when the container is deleted.
- A PersistentVolume (PV) is a cluster-wide resource that represents actual storage, and it lives independently of any Pod.
- A PersistentVolumeClaim (PVC) is a namespaced request for storage that binds to a matching PV based on size, access mode, and StorageClass.
- Access modes (RWO, ROX, RWX) define how many nodes can mount a volume and with what permissions, and must match between PVC and PV.
- StorageClasses enable dynamic provisioning of PVs when a PVC is created, eliminating the need for manual PV creation in many scenarios.
- Reclaim policies (Retain, Delete, Recycle) control what happens to the PV after its PVC is deleted, affecting whether data is kept or destroyed.
- hostPath volumes are useful for testing but are not suitable for production because they tie a Pod to a single node and its local filesystem.
- You must inspect PV and PVC binding status using kubectl get pv and kubectl get pvc; a PVC stuck in 'Pending' indicates a binding issue.

## FAQ

**How is a PersistentVolume different from a normal volume in Kubernetes?**

A normal volume (like emptyDir) is tied to the Pod's lifecycle and is deleted when the Pod is destroyed. A PersistentVolume is a cluster resource that exists independently of any Pod and is designed to persist data across Pod restarts and deletions.

**Why is my PersistentVolumeClaim stuck in Pending status?**

The PVC stays Pending when there is no matching PersistentVolume available. Check if any PV has enough storage, the correct access mode, and a compatible StorageClass. Also verify that the PVC does not have a StorageClass name that does not exist.

**Can I use one PVC with multiple Pods simultaneously?**

Yes, but only if the underlying PV supports ReadWriteMany (RWX) access mode. Most cloud block storage only supports ReadWriteOnce (RWO), meaning only one Pod on one node can use it at a time. For multiple Pods, use a shared filesystem like NFS or a cloud-native RWX solution.

**What happens to the data when a PersistentVolumeClaim is deleted?**

The reclaim policy of the bound PersistentVolume determines the outcome. If the policy is 'Retain', the PV and its data are kept even after the PVC is deleted, but the PV becomes 'Released'. If the policy is 'Delete', the PV and the underlying storage are automatically removed.

**Do I need to create a PersistentVolume manually for every application?**

Not necessarily. By defining a StorageClass with dynamic provisioning enabled, Kubernetes automatically creates a PersistentVolume when a PVC is submitted. This is the recommended approach for most cloud environments.

**What is the difference between hostPath and a PersistentVolume?**

hostPath is a volume type that mounts a file or directory from the node's filesystem into a Pod. It is simple but ties the Pod to a specific node and is not suitable for production. A PersistentVolume abstracts the storage away from the node, making it portable across nodes and suitable for production workloads.

## Check your understanding

1. **What command would you use to check the status of a PersistentVolumeClaim named 'my-pvc'?**

   Answer: You would use 'kubectl get pvc my-pvc' or 'kubectl describe pvc my-pvc' to view its status and events.

2. **A PVC requests 10Gi of storage with ReadWriteOnce access. There is a PV with 20Gi capacity and ReadWriteMany access. Will the PVC bind to this PV?**

   Answer: No, because the access modes do not match. The PVC requires ReadWriteOnce, but the PV offers ReadWriteMany. Matching access mode is mandatory for binding.

3. **What is the purpose of a StorageClass in relation to PersistentVolumes?**

   Answer: A StorageClass defines a provisioner and reclaim policy that enables dynamic provisioning of PersistentVolumes when a PersistentVolumeClaim is created, so you do not need to create PVs manually.

4. **After a PVC is deleted, what determines whether the bound PersistentVolume and its data are kept or removed?**

   Answer: The reclaim policy on the PersistentVolume (Retain, Delete, or Recycle) determines the outcome. 'Retain' keeps the volume and data, 'Delete' removes both.

5. **Can a PersistentVolume be used by a Pod in a different namespace than the PVC that is bound to it?**

   Answer: No. The PVC is namespaced, and a Pod can only mount a PVC that exists in the same namespace as the Pod. However, the PV itself is cluster-wide and not tied to any namespace.

---

Interactive version with quiz and diagrams: https://courseiva.com/learn/cncf-cka/storage-basics-and-volumes
