█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/DevOps and Infrastructure/Kubernetes/Persistent Storage
35 minIntermediate

Persistent Storage

After this lesson, you will be able to: Use PersistentVolumes, PersistentVolumeClaims, and StorageClasses to give Pods durable storage.

Containers are ephemeral. Stateful workloads (DBs, caches, uploads) need persistent storage. K8s abstracts that with PV / PVC / StorageClass.

Prerequisites:Services and Networking

The three storage objects

StorageClass: a 'type' of storage available in the cluster. Examples: AWS gp3 SSD, GCP pd-balanced, NFS server. Cluster admin defines these. PersistentVolumeClaim (PVC): an APP's request, 'I want 10Gi of fast storage'. App writes this; cluster fulfills. PersistentVolume (PV): the actual storage that's been provisioned to fulfill a PVC. Usually auto-created by the StorageClass.

Postgres with persistent storage

The canonical stateful-workload pattern.

sql
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
spec:
accessModes: [ReadWriteOnce]
storageClassName: standard # or gp3, pd-balanced, etc.
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: StatefulSet # not Deployment for stateful workloads
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 1
selector:
matchLabels: { app: postgres }
template:
metadata: { labels: { app: postgres } }
spec:
containers:
- name: postgres
image: postgres:16-alpine
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef: { name: postgres-secret, key: password }
ports:
- containerPort: 5432
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: postgres-data

Access modes

ReadWriteOnce (RWO): one node at a time can mount RW. The default; works for almost all single-instance DBs. ReadOnlyMany (ROX): many nodes mount RO. Used for shared static assets. ReadWriteMany (RWX): many nodes mount RW. Requires a shared filesystem (NFS, EFS, Azure Files). Rare in modern apps. RWO is the default; reach for the others only when you have a specific reason.

Deployment vs StatefulSet for stateful workloads

Deployment: Pods are interchangeable; identity doesn't matter. Don't use for databases. StatefulSet: Pods have stable, ordered identities (myapp-0, myapp-1, ...). Each has its own PVC. K8s scales them one at a time. Use for databases, distributed systems, queues. For most learners: stick with managed databases (RDS, Cloud SQL, Supabase) and avoid running stateful workloads in K8s unless you have a strong reason.

💡 Backups are NOT a Kubernetes feature

K8s ensures the Pod runs; it does NOT back up your data. Use the database's native tooling (pg_dump, logical replication) PLUS volume-level snapshots (cloud provider feature). Test the restore process at least quarterly. A backup you've never restored is decorative.

Common mistakes only experienced engineers avoid

Running production databases in K8s without a backup strategy. Using Deployment for stateful workloads. Loses data on scale-down. Forgetting `storageClassName`. Defaults vary by cluster; explicit is safer. PVC that's too small. Many cloud providers DON'T support online expansion; you'll need to migrate data. Provision generously. Sharing a single PVC across many Pods with ReadWriteOnce. Only ONE Pod can mount it; others stay Pending.

Quick Check

Should you run your production Postgres in Kubernetes?

Pick the honest answer.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Services and Networking
Back to Kubernetes
Helm→