Storage¶
Overview¶
This domain represents 10% of the CKA exam. While it is the smallest domain, storage tasks are usually straightforward if you understand the PV/PVC model and can write the YAML correctly.
Storage - Kubernetes storage overview
Persistent Volumes (PV)¶
Persistent Volumes are cluster-level storage resources provisioned by an administrator or dynamically via Storage Classes. They exist independently of any pod that uses them.
PV Specification¶
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-data
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /mnt/data
Access Modes¶
| Mode | Abbreviation | Description |
|---|---|---|
| ReadWriteOnce | RWO | Can be mounted as read-write by a single node |
| ReadOnlyMany | ROX | Can be mounted as read-only by many nodes |
| ReadWriteMany | RWX | Can be mounted as read-write by many nodes |
| ReadWriteOncePod | RWOP | Can be mounted as read-write by a single pod (v1.29+) |
Important: Access modes describe the capability of the volume, not the enforced access. For example, a hostPath volume only supports RWO because it is local to a single node.
Volume Modes¶
- Filesystem (default) - volume is mounted as a directory in the container
- Block - volume is presented as a raw block device (no filesystem)
Reclaim Policies¶
What happens to the PV when its PVC is deleted:
- Retain - PV is kept with its data intact, must be manually cleaned up
- Delete - PV and the underlying storage resource are deleted
- Recycle (deprecated) - basic scrub (
rm -rf /thevolume/*) before making available again
PV Status Lifecycle¶
- Available - free resource, not yet bound to a claim
- Bound - volume is bound to a PVC
- Released - PVC has been deleted, but the resource is not yet reclaimed
- Failed - volume has failed its automatic reclamation
Persistent Volumes - Complete PV documentation
Persistent Volume Claims (PVC)¶
PVCs are requests for storage by users. They consume PV resources similar to how pods consume node resources.
PVC Specification¶
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: manual
PV-PVC Binding¶
A PVC binds to a PV based on: 1. Access mode - must match 2. Storage size - PV must have capacity >= PVC request 3. Storage class - must match (empty string means no class) 4. Label selector - optional, further constrains binding
If multiple PVs satisfy a PVC, Kubernetes picks the one with the smallest capacity that still meets the request.
# PVC with label selector
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-specific
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
selector:
matchLabels:
environment: production
Using PVCs in Pods¶
apiVersion: v1
kind: Pod
metadata:
name: app-with-storage
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: data-volume
mountPath: /usr/share/nginx/html
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: pvc-data
Persistent Volume Claims - PVC documentation Configure a Pod to Use a PersistentVolume - PV/PVC tutorial
Storage Classes¶
Storage Classes enable dynamic provisioning of Persistent Volumes. When a PVC requests a Storage Class, the provisioner automatically creates a PV.
Storage Class Definition¶
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/no-provisioner # For local/hostPath
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
Common Provisioners¶
| Provisioner | Description |
|---|---|
kubernetes.io/aws-ebs | AWS Elastic Block Store |
kubernetes.io/gce-pd | GCE Persistent Disk |
kubernetes.io/azure-disk | Azure Managed Disk |
kubernetes.io/no-provisioner | No dynamic provisioning (local volumes) |
Volume Binding Modes¶
- Immediate (default) - PV is provisioned as soon as PVC is created
- WaitForFirstConsumer - PV provisioning is delayed until a pod using the PVC is scheduled. This ensures the PV is created in the same topology zone as the pod.
Dynamic Provisioning Flow¶
- Administrator creates a StorageClass
- User creates a PVC referencing the StorageClass
- The provisioner automatically creates a PV matching the PVC
- The PVC binds to the new PV
- Pod mounts the PVC
# PVC using dynamic provisioning
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-storage
resources:
requests:
storage: 20Gi
Default Storage Class¶
When a PVC does not specify a storageClassName, the default Storage Class is used.
# Check default storage class
kubectl get sc
# Set a storage class as default
kubectl annotate storageclass fast-storage \
storageclass.kubernetes.io/is-default-class=true
# Remove default annotation from another class
kubectl annotate storageclass old-default \
storageclass.kubernetes.io/is-default-class-
Storage Classes - StorageClass documentation Dynamic Volume Provisioning - Dynamic provisioning guide Change Default StorageClass - Managing default class
Volume Types¶
emptyDir¶
Temporary storage that exists for the lifetime of the pod. Deleted when the pod is removed.
spec:
containers:
- name: app
volumeMounts:
- name: cache
mountPath: /cache
volumes:
- name: cache
emptyDir:
sizeLimit: 500Mi
Use Cases: - Scratch space for temporary data - Sharing files between containers in a multi-container pod - Cache storage
hostPath¶
Mounts a file or directory from the host node's filesystem into the pod.
spec:
containers:
- name: app
volumeMounts:
- name: host-data
mountPath: /data
volumes:
- name: host-data
hostPath:
path: /var/data
type: DirectoryOrCreate
hostPath Types: - "" (empty) - no checks - DirectoryOrCreate - create directory if it does not exist - Directory - directory must exist - FileOrCreate - create file if it does not exist - File - file must exist
Warning: hostPath volumes are a security risk in production. They give pods access to the host filesystem. Use with caution and prefer PVCs instead.
configMap Volume¶
Mounts ConfigMap data as files in a container.
spec:
containers:
- name: app
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
name: app-config
items: # Optional: mount specific keys
- key: config.yaml
path: app-config.yaml
secret Volume¶
Mounts Secret data as files in a container. Files are base64-decoded.
spec:
containers:
- name: app
volumeMounts:
- name: certs
mountPath: /etc/certs
readOnly: true
volumes:
- name: certs
secret:
secretName: tls-certs
Volumes - All volume types Projected Volumes - Combining sources
Volume Expansion¶
Storage Classes with allowVolumeExpansion: true allow PVCs to be resized.
# Edit the PVC to increase storage
kubectl edit pvc my-pvc
# Change spec.resources.requests.storage to a larger value
# Or patch it
kubectl patch pvc my-pvc -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
Note: You can only expand volumes, never shrink them. Some volume types require the pod to be restarted for the filesystem to be resized.
Expanding Persistent Volumes - Volume expansion
Complete PV/PVC Example¶
Here is a complete example creating a PV, PVC, and pod that uses it:
# 1. Create the Persistent Volume
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data
---
# 2. Create the Persistent Volume Claim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pvc
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
---
# 3. Create a Pod using the PVC
apiVersion: v1
kind: Pod
metadata:
name: task-pod
spec:
containers:
- name: task-container
image: nginx
volumeMounts:
- name: task-storage
mountPath: /usr/share/nginx/html
volumes:
- name: task-storage
persistentVolumeClaim:
claimName: task-pvc
Key Exam Tips for This Domain¶
- PV/PVC binding - access mode and storage class must match; PV capacity must be >= PVC request
- Know the three reclaim policies - Retain, Delete, Recycle (deprecated)
- storageClassName must match exactly between PV and PVC (including empty string vs no field)
- hostPath is commonly used in exam environments since there is no cloud provisioner
- Practice writing PV, PVC, and Pod YAML from scratch - you will need to do this quickly
- WaitForFirstConsumer binding mode is important for topology-aware provisioning
- Volume mounts go in the container spec, volumes go in the pod spec - do not confuse them