By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
For engineers who need to deploy stateful apps in production—yesterday.
You’re deploying a database, a logging agent, or a user-uploaded file service in Kubernetes. If you don’t configure storage correctly: - Your data disappears when the pod restarts (because containers are ephemeral).- Your app crashes if it can’t write to disk (e.g., PostgreSQL, Redis, or a WordPress uploads folder).- You violate compliance (e.g., GDPR, HIPAA) by storing sensitive data in the wrong place.
Real-world scenario:You inherit a Kubernetes cluster where a legacy app stores logs in /var/log/app inside the container. When the pod crashes, the logs vanish. Your boss asks, "Where are yesterday’s logs?" You need to persist data outside the pod—this guide shows you how.
/var/log/app
Superpower you gain:- Decouple compute from storage (pods come and go; data stays).- Share data between pods (e.g., a shared config file or a database volume).- Control performance, cost, and durability (SSD vs. HDD, local vs. cloud storage).
PersistentVolume
/dev
readOnly: true
fast-ssd
gp3
io1
ReadWriteOnce
ReadOnlyMany
ReadWriteMany
Retain
Delete
Recycle
kubectl
standard
gp2
We’ll: 1. Create a PVC requesting 5Gi of storage.2. Deploy PostgreSQL with the PVC mounted at /var/lib/postgresql/data.3. Verify data persists after pod deletion.
/var/lib/postgresql/data
# pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: standard # Use your cluster's default StorageClass
Apply it:
kubectl apply -f pvc.yaml
Verify:
kubectl get pvc
Expected output:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE postgres-pvc Bound pvc-12345678-1234-1234-1234-1234567890ab 5Gi RWO standard 5s
# postgres-deployment.yaml 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:13 env: - name: POSTGRES_PASSWORD value: "mysecretpassword" ports: - containerPort: 5432 volumeMounts: - name: postgres-storage mountPath: /var/lib/postgresql/data volumes: - name: postgres-storage persistentVolumeClaim: claimName: postgres-pvc
kubectl apply -f postgres-deployment.yaml
kubectl get pods
NAME READY STATUS RESTARTS AGE postgres-5f7d8c6b8c-abc12 1/1 Running 0 10s
Create a test table: bash kubectl exec -it postgres-5f7d8c6b8c-abc12 -- psql -U postgres Inside the PostgreSQL shell: sql CREATE TABLE test (id serial PRIMARY KEY, name text); INSERT INTO test (name) VALUES ('persistent-data'); \q
bash kubectl exec -it postgres-5f7d8c6b8c-abc12 -- psql -U postgres
sql CREATE TABLE test (id serial PRIMARY KEY, name text); INSERT INTO test (name) VALUES ('persistent-data'); \q
Delete the pod (simulate a crash): bash kubectl delete pod postgres-5f7d8c6b8c-abc12
bash kubectl delete pod postgres-5f7d8c6b8c-abc12
Verify the data is still there: bash kubectl get pods # Wait for the new pod to start kubectl exec -it postgres-5f7d8c6b8c-xyz78 -- psql -U postgres -c "SELECT * FROM test;" Expected output: id | name ----+---------------- 1 | persistent-data
bash kubectl get pods # Wait for the new pod to start kubectl exec -it postgres-5f7d8c6b8c-xyz78 -- psql -U postgres -c "SELECT * FROM test;"
id | name ----+---------------- 1 | persistent-data
kubectl delete deployment postgres kubectl delete pvc postgres-pvc
hostPath
fsGroup
postgres
yaml securityContext: fsGroup: 999 # PostgreSQL's default user ID
yaml resources: requests: storage: 10Gi limits: storage: 20Gi # Prevents runaway growth
yaml metadata: labels: app: postgres env: prod
volumeMode: Filesystem
Block
reclaimPolicy: Retain
bash kubectl top pvc # Requires metrics-server
emptyDir
PersistentVolumeClaim
storageClassName
Pending
kubectl get storageclass
accessModes
Trap: ReadWriteOnce (RWO) won’t work for multiple pods.
Scenario: "You delete a PVC, but the PV is still there. Why?"
reclaimPolicy
Trap: Delete would have removed the PV.
Scenario: "Your PVC is stuck in Pending. What’s the most likely cause?"
PersistentVolume (PV)
PersistentVolumeClaim (PVC)
Challenge:Deploy a Redis pod with a PVC. Write a key-value pair (SET mykey "hello"), delete the pod, and verify the data persists.
SET mykey "hello"
Solution:1. Create a PVC: yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: redis-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi 2. Deploy Redis with the PVC: yaml apiVersion: apps/v1 kind: Deployment metadata: name: redis spec: replicas: 1 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - name: redis image: redis volumeMounts: - name: redis-storage mountPath: /data volumes: - name: redis-storage persistentVolumeClaim: claimName: redis-pvc 3. Test persistence: bash kubectl exec -it redis-<pod-id> -- redis-cli SET mykey "hello" kubectl delete pod redis-<pod-id> kubectl exec -it redis-<new-pod-id> -- redis-cli GET mykey # Should return "hello"
yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: redis-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
yaml apiVersion: apps/v1 kind: Deployment metadata: name: redis spec: replicas: 1 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - name: redis image: redis volumeMounts: - name: redis-storage mountPath: /data volumes: - name: redis-storage persistentVolumeClaim: claimName: redis-pvc
bash kubectl exec -it redis-<pod-id> -- redis-cli SET mykey "hello" kubectl delete pod redis-<pod-id> kubectl exec -it redis-<new-pod-id> -- redis-cli GET mykey # Should return "hello"
Why it works:Redis stores data in /data by default. The PVC ensures the data persists across pod restarts.
/data
kubectl get pv
kubectl describe pvc <name>
Events
accessModes: ReadWriteOnce
storageClassName: standard
kubectl delete pvc <name>
reclaimPolicy: Delete
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.