Skip to main content
RunBook Academy

KubernetesXLVIII · Storage FundamentalsStorage fundamentals

Storage concepts — access modes, capacity, and the API surface

Advanced⏱ ~16 minkubectl

What you'll learn

  • Explain the access modes (RWO, ROX, RWX, RWOP) and what each enables
  • Distinguish volume modes (filesystem, block) and their use cases
  • Describe the binding semantics between PV and PVC
  • Apply the API surface to design PVCs correctly

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

The Kubernetes storage API surface is small but precise: access modes, capacity, volume modes, and binding. This lesson walks each, explains what they mean, and shows how they combine in a real PVC.

Access modes

Access modes describe how a volume can be mounted:

ModeMeaning
ReadWriteOnce (RWO)Single node can mount as read-write
ReadOnlyMany (ROX)Multiple nodes can mount as read-only
ReadWriteMany (RWX)Multiple nodes can mount as read-write
ReadWriteOncePod (RWOP)Single Pod can mount as read-write (Kubernetes 1.22+)

The access mode is a property of the volume, not the workload. The CSI driver advertises which modes it supports; the user requests a mode in the PVC.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data
spec:
  accessModes: ["ReadWriteOnce"]
  storageClassName: ssd
  resources:
    requests:
      storage: 100Gi

A PVC requesting ReadWriteMany cannot be bound to a PV that only supports ReadWriteOnce. The binding controller rejects the binding if the access modes do not match.

Volume modes

Volume modes describe how the volume appears to the Pod:

ModeMeaning
FilesystemThe volume is formatted with a filesystem and mounted as a directory. Default.
BlockThe volume is exposed as a raw block device. The application uses it directly, no filesystem.

Filesystem is the standard mode; the kubelet formats the volume (if needed) and mounts it as a directory. Block is for applications that manage their own filesystem (database storage engines, raw device access).

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: raw-data
spec:
  accessModes: ["ReadWriteOnce"]
  storageClassName: ssd
  volumeMode: Block
  resources:
    requests:
      storage: 100Gi

A Block volume is mounted as a device, not a directory. The application sees /dev/xvdba, not /mnt/data.

Capacity

The PVC’s capacity request is a minimum, not a maximum:

spec:
  resources:
    requests:
      storage: 100Gi

The PV must provide at least 100 GB. If the PV provides more (e.g., 200 GB), the PVC sees 200 GB.

Capacity expansion (where supported by the CSI driver) allows the user to grow the PVC:

kubectl edit pvc data
# Change spec.resources.requests.storage to 200Gi

The CSI driver handles the expansion; the filesystem is resized; the application sees the new capacity.

StorageClass

The StorageClass is the user’s pointer to a provisioning template:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ssd
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
allowVolumeExpansion: true

The PVC references the StorageClass by name:

spec:
  storageClassName: ssd

The provisioner (e.g., ebs.csi.aws.com) creates a PV when a PVC is submitted. The volumeBindingMode controls when the PV is created (immediately, or when a Pod schedules).

Binding semantics

The PV and PVC are bound by a controller in the control plane:

flowchart LR
    A[PVC submitted] --> B{StorageClass specified?}
    B -->|yes| C[Provisioner creates PV]
    B -->|no| D[Look for matching existing PV]
    C --> E[Bind PV to PVC]
    D --> F{Found matching PV?}
    F -->|yes| E
    F -->|no| G[PVC Pending]

The binding controller matches PVs to PVCs by:

  • Access modes: the PV’s modes must include at least one of the PVC’s modes.
  • Capacity: the PV’s capacity must be >= the PVC’s request.
  • StorageClass: the PV’s StorageClass must match the PVC’s (or be unset if the PVC’s is unset).
  • Selector: the PVC’s selector must match the PV’s labels (if specified).

A PVC that does not match any existing PV is Pending until a PV is provisioned (dynamic) or until an existing PV is created (static).

The API surface summary

FieldWhereEffect
accessModesPVCWhat mount modes the volume must support
storageClassNamePVCWhich StorageClass to provision from
resources.requests.storagePVCMinimum capacity
volumeModePVCFilesystem or block
selectorPVCLabel selector for matching PVs
volumeNamePVCExplicit PV to bind to
reclaimPolicyPVWhat happens to the PV when PVC is deleted
persistentVolumeReclaimPolicyStorageClassDefault reclaim policy for provisioned PVs

The API surface is small but the combinations are expressive. Operators must understand each field to design PVCs correctly.

Quiz

Knowledge check · 4 questions

  1. Q1. A database workload needs to mount the same volume from multiple Pods on different nodes with read-write access. Which access mode is required?

  2. Q2. A PVC requesting 100 GB will be bound to a PV with exactly 100 GB of capacity.

  3. Q3. A team designs a PVC for a database workload that needs RWX. Walk through the design decisions and identify what is required.

    PostgreSQL StatefulSet. Multiple read-replica Pods on different nodes need to mount the same data volume with read-write access (for replication).

  4. Q4. Name the four fields that determine PVC-PV binding and explain how the binding controller uses them.

Passing score: 75%. Answers are checked in this browser.

Production discipline

  • Choose the access mode by the workload. RWX is rare and constrained; RWO is the standard.
  • Capacity is a minimum, not a maximum. The PV can provide more than requested.
  • Volume mode Block for raw device access, Filesystem for standard mounts. The choice affects the Pod’s view.
  • StorageClass is the template, the PVC is the request. The provisioner is the implementation.
  • Binding is by selector, capacity, StorageClass, and access mode. A PVC that does not match is Pending.