Filters
How to search
  • Plain words find names, texts and examples.
  • "two words" finds the exact phrase.
  • --name or -x finds an option.
  • #word looks only inside commands.
  • @grep finds lessons and labs that use grep.
  • Filters: cat:network · in:labs · in:notes · level:rhcsa · ch:8 · root:yes. Put ! before a word to leave it out. OR between words means one of them.
  • ↑ ↓ to move · Enter to open · Esc to close · / to search

Chapter 11Name in the course: Storage

Give pods persistent storage

Container files are lost when a pod is replaced. PersistentVolumes (PV) are storage in the cluster; PersistentVolumeClaims (PVC) are requests for it; StorageClasses create PVs on demand (dynamic provisioning).

  • 6 Lessons
  • 1 Commands

$ run as a normal user# run as root (or with sudo)

Skills in this chapter

  • StorageClasses, dynamic provisioning, PVs and PVCs

11.1

Know the storage objects

The app asks with a PVC; Kubernetes binds it to a matching PV (existing or newly created).

ObjectWho makes itMeaning
StorageClassAdminA type of storage + its provisioner
PersistentVolumeAdmin or provisionerA piece of real storage
PersistentVolumeClaimApp team"I need 10 Gi, ReadWriteOnce"
Volume in the podApp teamMounts the PVC into a container

11.2

Know access modes and reclaim policies

Access modes say how many nodes may mount the volume; the reclaim policy says what happens after the PVC is deleted.

Access modeShortMeaning
ReadWriteOnceRWORead-write by one node
ReadOnlyManyROXRead-only by many nodes
ReadWriteManyRWXRead-write by many nodes (NFS, CephFS, Azure Files)
ReadWriteOncePodRWOPRead-write by one pod only
Reclaim policyAfter the PVC is deleted
DeleteThe PV and the real disk are deleted (default for dynamic)
RetainThe PV stays (status Released); an admin cleans up by hand

11.3

Use dynamic provisioning

With a StorageClass, a PVC alone is enough — the provisioner creates the PV.

storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
  annotations: { storageclass.kubernetes.io/is-default-class: "true" }
provisioner: rancher.io/local-path
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: db-data, namespace: shop }
spec:
  accessModes: [ReadWriteOnce]
  storageClassName: fast
  resources:
    requests: { storage: 10Gi }
kubectl get storageclass
kubectl get pvc,pv -n shop
kubectl patch pvc db-data -n shop -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'

Remember

WaitForFirstConsumer creates the volume only when a pod uses it — in the zone of that pod's node. The PVC stays Pending until then; that is normal.

11.4

Create a PV by hand

Without a provisioner, an admin creates PVs; a PVC with the same class, size and mode binds to one.

pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata: { name: pv-logs }
spec:
  capacity: { storage: 5Gi }
  accessModes: [ReadWriteOnce]
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  hostPath: { path: /mnt/data/logs }

11.5

Mount the PVC in a pod

The pod refers to the claim, the container mounts the volume.

pod-pvc.yaml
apiVersion: v1
kind: Pod
metadata: { name: db, namespace: shop }
spec:
  containers:
    - name: postgres
      image: postgres:16
      env: [{ name: POSTGRES_PASSWORD, value: change-me }]
      volumeMounts:
        - { name: data, mountPath: /var/lib/postgresql/data }
  volumes:
    - name: data
      persistentVolumeClaim: { claimName: db-data }
kubectl exec db -n shop -- df -h /var/lib/postgresql/data
kubectl describe pvc db-data -n shop

11.6

Use other volume types

Not every volume is persistent.

VolumeLives as long asUse
emptyDirThe podScratch space, shared between containers of a pod
hostPathThe nodeNode agents; avoid for apps (pins the pod to a node)
configMap, secretThe objectConfig files
persistentVolumeClaimThe PVCApp data

All commands in this chapter