Skip to main content

Chapter 6.2 - PersistentVolumes and PersistentVolumeClaims

Learning Objectives

By the end of this chapter, you will be able to:

  • Understand PersistentVolumes (PV) and PersistentVolumeClaims (PVC)
  • Create and use PVs and PVCs
  • Understand access modes (RWO, ROX, RWX)
  • Manage the storage lifecycle
  • Understand reclaim policies
  • Choose the right storage type based on the use case

Introduction

Ephemeral volumes (emptyDir, tmpfs) are deleted when the Pod terminates. For important data that must persist (databases, user files, etc.), Kubernetes uses PersistentVolumes and PersistentVolumeClaims.


Key Concepts

PersistentVolume (PV)

A PersistentVolume is a storage resource in the cluster that has been provisioned by an administrator. It is a cluster-level resource, independent of Pods.

PersistentVolumeClaim (PVC)

A PersistentVolumeClaim is a storage request by a user. The PVC binds a PV to a Pod.


Creating a PersistentVolume

Example: PV with hostPath (Local Development)

apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-volume
labels:
type: local
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /data/pv-volume

Note: hostPath is for local development only. In production, use cloud solutions (EBS, Azure Disk, GCE Persistent Disk) or NFS.

Example: PV with NFS

apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs
spec:
capacity:
storage: 50Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
server: nfs-server.example.com
path: /exports/data

Creating a PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: manual

Binding Process:


Access Modes

Access modes determine how the volume can be mounted:

ReadWriteOnce (RWO)

  • A single node can mount the volume in read-write mode
  • Multiple Pods on the same node can share the volume
  • Use case: Databases, stateful applications

ReadOnlyMany (ROX)

  • Multiple nodes can mount the volume in read-only mode
  • Use case: Read-only configuration files, shared data

ReadWriteMany (RWX)

  • Multiple nodes can mount the volume in read-write mode
  • Use case: Shared file systems (NFS, GlusterFS)

Using in a Pod

apiVersion: v1
kind: Pod
metadata:
name: pv-pod
spec:
containers:
- name: app
image: nginx:1.20
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: pv-claim

Complete Flow:


Reclaim Policies

The reclaim policy determines what happens to the PV when the PVC is deleted.

Retain

The PV is retained even after the PVC is deleted. Data remains intact.

Use Cases:

  • Important data to back up
  • Need for manual recovery
  • Compliance and auditing

Delete

The PV is automatically deleted along with the PVC. Data is lost.

Use Cases:

  • Temporary data
  • Development environments
  • Dynamic provisioning

Recycle (Deprecated)

This policy is deprecated. Use Retain or Delete instead.


Complete Example: Database

Step 1: Create the PersistentVolume

apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
labels:
app: postgres
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: fast-ssd
hostPath:
path: /data/postgres

Step 2: Create the PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: fast-ssd

Step 3: Use in a Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:14
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc

Useful Commands

View PVs and PVCs

# List PVs
kubectl get pv

# PV details
kubectl describe pv pv-volume

# List PVCs
kubectl get pvc

# PVC details
kubectl describe pvc pv-claim

Check Binding

# View binding state
kubectl get pv
kubectl get pvc

# View details
kubectl get pv pv-volume -o yaml
kubectl get pvc pv-claim -o yaml

Delete a PVC

# Delete PVC
kubectl delete pvc pv-claim

# Check PV state after deletion
kubectl get pv pv-volume

Storage Types

Local Storage (hostPath)

Advantages:

  • Simple for development
  • No external dependency

Disadvantages:

  • Not portable
  • Risk of data loss
  • Does not work with multiple nodes

Usage: Local development only

NFS (Network File System)

Advantages:

  • Supports ReadWriteMany
  • Shareable between nodes
  • Easy to set up

Disadvantages:

  • Limited performance
  • Single point of failure
  • Requires an NFS server

Usage: Shared files, collaborative applications

Cloud Storage (EBS, Azure Disk, GCE PD)

Advantages:

  • High performance
  • Cloud-native integration
  • Dynamic provisioning
  • Automatic snapshots

Disadvantages:

  • Cost based on usage
  • Cloud provider dependency

Usage: Production, critical applications


Best Practices

1. Use StorageClasses

Prefer dynamic provisioning with StorageClasses rather than manually creating PVs.

2. Choose the Right Reclaim Policy

  • Retain: For important data
  • Delete: For temporary data

3. Appropriate Sizing

Don't over-allocate. Start small and expand if needed (with allowVolumeExpansion: true).

4. Backups

Set up regular backups for important data.

5. Monitoring

Monitor storage usage to prevent exhaustion.


Summary

In this chapter, you learned:

PersistentVolume (PV): Cluster-level storage resource
PersistentVolumeClaim (PVC): Storage request by a user
Access Modes: RWO (one node), ROX (multiple nodes read-only), RWX (multiple nodes read-write)
Reclaim Policy: Retain (keep) or Delete (remove)
Storage types: hostPath (dev), NFS (shared), Cloud (production)
Usage: Via persistentVolumeClaim in Pods
Best practices: StorageClasses, appropriate sizing, backups


Next Steps

Chapter 6.3: StorageClasses and Dynamic Provisioning
Lab 6.2: PersistentVolumes and PVCs


Chapter created: December 2024