17.5 Access Modes: ReadWriteOnce, ReadOnlyMany, ReadWriteMany
Right, let’s talk about access modes. This is where the rubber meets the road for your data. You’ve told Kubernetes you want storage, and it’s given you a shiny PersistentVolumeClaim (PVC). But can one pod use it? Can a hundred? Can they all write to it? The accessModes field in your PVC and PV is your way of laying down the law about this.
Think of it as a traffic cop for your data. You’re not just saying “I need storage”; you’re saying “I need storage and here’s how it’s going to be used.” This is crucial because the underlying storage technology (your cloud provider’s disk, an NFS server, a Ceph cluster) might not support every possible use case. Kubernetes uses your requested access mode to find a PersistentVolume that can actually deliver that behavior.
Let’s break down the three modes you can choose from. Buckle up, because one of them is a bit of a diva.
ReadWriteOnce (RWO)
This is the workhorse, the default you’ll see everywhere. ReadWriteOnce means the volume can be mounted as read-write by a single node. Notice I said node, not pod. This is the first “gotcha” and it’s a big one.
If you’ve got a multi-pod Deployment spread across three nodes, you can’t have them all using the same RWO volume. The first pod that gets scheduled will successfully mount the volume to its node. The second pod, scheduled to a different node, will be stuck in ContainerCreating forever, waiting for the volume to become available. It’s like trying to plug a single physical hard drive into two different computers at the same time—it just doesn’t work.
This is why RWO is perfect for stateful applications like databases (e.g., a single PostgreSQL instance). It’s one pod, on one node, with one volume. The semantics are clear.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-database-pvc
spec:
accessModes:
- ReadWriteOnce # The key line
resources:
requests:
storage: 10Gi
storageClassName: standard
ReadOnlyMany (ROX)
As the name implies, ReadOnlyMany allows the volume to be mounted as read-only by many nodes simultaneously. This is fantastic for distributing static assets, configuration data, or pre-trained machine learning models to a large number of pods.
The key thing to remember here is the “read-only” part. No pod can write to this volume. The data is essentially immutable from the perspective of the pods using it. The data has to be populated onto the volume somehow else before the claim is made—often by a Job or a separate Pod with a ReadWriteOnce claim. This mode is less common than RWO but incredibly useful for specific, large-scale distribution problems.
ReadWriteMany (RWX)
Ah, ReadWriteMany. The holy grail and the source of most of my storage-related headaches. This mode allows a volume to be mounted as read-write by many nodes simultaneously. You’d use this for truly shared storage needs, like a shared upload directory for a web application or a workspace for collaborative tools.
Here’s the catch: most storage systems absolutely hate this. Your basic cloud block storage (like AWS EBS or GCP Persistent Disk) flat-out refuses to do it. They’re physically attached to a single node. Asking for RWX on a standard storage class is a surefire way to get a PVC that’s forever stuck in Pending.
To get RWX, you’re almost always forced to use a different class of storage, typically a network-attached filesystem like NFS, CephFS, or Azure Files. These systems are built for concurrent access, but they come with their own baggage: they’re often more expensive, can have higher latency, and you now have to worry about file locking and data consistency at the application level. Kubernetes doesn’t magically solve those problems for you.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-uploads-pvc
spec:
accessModes:
- ReadWriteMany # Good luck with that on most clusters
resources:
requests:
storage: 100Gi
storageClassName: azurefile # or 'nfs-client', etc.
The Matching Game and Pitfalls
When you create a PVC with a specific access mode, the Kubernetes scheduler goes shopping for a PV that matches it exactly. A PVC asking for RWX will never bind to a PV that only supports RWO. This is why you’ll see PVCs hang indefinitely if your cluster’s storage provisioner can’t provide what you’re asking for.
The best practice? Be brutally honest about what you need. Start with the most restrictive mode that gets the job done. If you only need one pod to write, use RWO. You’ll have a much wider choice of fast, cheap, and reliable storage. Only reach for the complexity of RWX when you have a verified, undeniable requirement for multi-node writing. And when you do, test the living daylights out of your application’s behavior under concurrent load—because the storage subsystem is now a much more complex and potentially flaky part of your stack.