Storage on OpenShift — classes, claims, and where data lives
Storage trips people up because three objects are involved and the disk itself lives somewhere none of them are. Here’s the whole chain.
The three objects
Section titled “The three objects”- A PersistentVolumeClaim (PVC) is what your app asks for: “I need 20Gi of read-write storage.” It lives in your namespace, next to your workload.
- A StorageClass describes how to satisfy that ask — which provisioner to call, what kind of disk, what parameters. It’s cluster-scoped.
- A PersistentVolume (PV) is the actual provisioned piece of storage the claim binds to. Usually you never create these by hand; the StorageClass’s provisioner makes them on demand (dynamic provisioning).
Pod ──uses──▶ PVC ──references──▶ StorageClass ──provisions──▶ PV ──▶ real disk (namespace) (cluster) (backend)A claim in practice
Section titled “A claim in practice”apiVersion: v1kind: PersistentVolumeClaimmetadata: name: dataspec: accessModes: ["ReadWriteOnce"] storageClassName: my-block-storage # omit to use the cluster default resources: requests: storage: 20GiCheck what classes exist and which is the default:
oc get storageclass# the one marked (default) is used when a PVC omits storageClassNameAccess modes — the one that bites
Section titled “Access modes — the one that bites”- ReadWriteOnce (RWO) — mountable read-write by a single node. Most block storage. Fine for databases and single-replica apps.
- ReadWriteMany (RWX) — mountable read-write by many nodes at once. Needs a file/shared backend (NFS, CephFS). Required when several pods on different nodes must write the same volume.
- ReadOnlyMany (ROX) — many nodes, read-only.
Reaching for RWX when you only have block storage is a classic stall. If two replicas need to share a volume and your backend is block-only, that’s a design signal, not a storage bug.
Where the data actually lives
Section titled “Where the data actually lives”A common misconception is that PVC data sits “on the cluster” or on the control plane. It doesn’t. The bytes live in whatever the StorageClass’s backend provisions — a cloud block volume, a Ceph pool via OpenShift Data Foundation, a LUN on an external SAN through its CSI driver, an NFS export. The masters hold cluster state (in etcd); they never hold your application’s volume data. That distinction matters the moment you start thinking about backups: backing up etcd protects the cluster’s configuration, not your databases’ contents — those need their own strategy, which is the next guide.
Reclaim policy — don’t lose (or leak) data
Section titled “Reclaim policy — don’t lose (or leak) data”Each PV has a reclaim policy: Delete (destroy the backing disk when the claim
goes) or Retain (keep it for manual recovery). Dynamic classes usually default
to Delete, which is convenient in dev and dangerous in production — deleting a
PVC can quietly destroy the underlying volume. For anything you care about, use a
StorageClass (or patch the PV) set to Retain.