Access Modes
Access modes determine how a PersistentVolume can be mounted and accessed by pods. They specify whether one or multiple pods can access the volume, and whether those pods have read-only or read-write access. Choosing the correct access mode is crucial for ensuring your application works correctly and efficiently.
Understanding Access Modes
Access modes are declared in both PersistentVolumes and PersistentVolumeClaims. For a PVC to bind to a PV, their access modes must be compatible. Kubernetes defines three access modes:
ReadWriteOnce (RWO)
ReadWriteOnce allows the volume to be mounted as read-write by a single node. This is the most common and widely supported access mode.
Key characteristics:
- One pod can mount the volume at a time
- The pod has both read and write access
- Most storage types support RWO (AWS EBS, GCE Persistent Disk, Azure Disk, local storage)
- If multiple pods try to mount, only one succeeds
Binding behavior:
- The volume is bound to a specific node
- Pods on the same node can potentially share the volume (rarely used in practice)
- When the pod is deleted, the volume can be bound to a pod on a different node
Example:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: database-pvc
spec:
accessModes:
- ReadWriteOnce # Only one pod can mount
storageClassName: fast-ssd
resources:
requests:
storage: 100Gi
Use cases:
- Databases (MySQL, PostgreSQL, MongoDB)
- Single-instance applications with persistent data
- Applications that need exclusive write access
- Most stateful applications
Limitations:
- Cannot be shared by multiple pods simultaneously
- If you need multiple pods to write, you must use ReadWriteMany (if supported)
ReadOnlyMany (ROX)
ReadOnlyMany allows the volume to be mounted as read-only by multiple nodes simultaneously.
Key characteristics:
- Multiple pods can mount the volume at the same time
- All mounts are read-only (no writes allowed)
- Useful for sharing configuration or reference data
- Fewer storage types support ROX compared to RWO
Binding behavior:
- Multiple pods can mount the same volume
- All mounts are read-only
- If a pod tries to write, the write operation fails
Example:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: config-pvc
spec:
accessModes:
- ReadOnlyMany # Multiple pods, read-only
storageClassName: standard
resources:
requests:
storage: 10Gi
Use cases:
- Configuration files shared across multiple pods
- Reference data (databases, lookup tables)
- Read-only content distribution
- Shared libraries or assets
Limitations:
- No write access (all mounts are read-only)
- Not all storage types support ROX
- If you need writes from multiple pods, use ReadWriteMany
ReadWriteMany (RWX)
ReadWriteMany allows the volume to be mounted as read-write by multiple nodes simultaneously. This is the most flexible but least commonly supported access mode.
Key characteristics:
- Multiple pods can mount the volume simultaneously
- All pods have read and write access
- Only network-based storage typically supports RWX (NFS, some cloud file storage)
- Performance can be slower than RWO due to network overhead
Binding behavior:
- Multiple pods on different nodes can mount and write
- Filesystem-level locking may be needed for concurrent writes
- Network latency affects performance
Example:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-content-pvc
spec:
accessModes:
- ReadWriteMany # Multiple pods, read-write
storageClassName: nfs-storage
resources:
requests:
storage: 500Gi
Use cases:
- Shared file storage (web content, user uploads)
- Content management systems
- Applications that need shared writable storage
- Collaboration tools
Limitations:
- Only supported by network file systems (NFS, cloud file storage)
- Performance is typically slower than RWO
- Requires careful application design for concurrent writes
- May need application-level locking for data consistency
Access Mode Selection Guide
Use this decision tree to choose the right access mode:
Storage Type Support
Not all storage types support all access modes:
| Storage Type | RWO | ROX | RWX |
|---|---|---|---|
| AWS EBS | ✅ | ❌ | ❌ |
| GCE Persistent Disk | ✅ | ❌ | ❌ |
| Azure Disk | ✅ | ❌ | ❌ |
| Local Storage | ✅ | ❌ | ❌ |
| NFS | ✅ | ✅ | ✅ |
| GlusterFS | ✅ | ✅ | ✅ |
| CephFS | ✅ | ✅ | ✅ |
| AWS EFS | ✅ | ✅ | ✅ |
| Azure Files | ✅ | ✅ | ✅ |
| GCE Filestore | ✅ | ✅ | ✅ |
Multiple Access Modes
You can specify multiple access modes in a PVC. The PV must support at least one of them:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: flexible-pvc
spec:
accessModes:
- ReadWriteOnce
- ReadOnlyMany # Will bind to PV that supports either
storageClassName: standard
resources:
requests:
storage: 50Gi
However, once bound, the actual access mode is determined by what the PV supports.
Real-World Examples
Database (RWO)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
spec:
accessModes:
- ReadWriteOnce # Database needs exclusive access
storageClassName: fast-ssd
resources:
requests:
storage: 200Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 1 # Single instance with RWO
template:
spec:
containers:
- name: postgres
image: postgres:14
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 200Gi
Shared Configuration (ROX)
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
config.yaml: |
database: postgres
cache: redis
---
# Using ConfigMap is better, but if you need a large volume:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-config
spec:
accessModes:
- ReadOnlyMany # Multiple pods read configuration
storageClassName: standard
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 3 # Multiple replicas sharing config
template:
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: config
mountPath: /etc/app
readOnly: true
volumes:
- name: config
persistentVolumeClaim:
claimName: shared-config
Shared Content (RWX)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: web-content
spec:
accessModes:
- ReadWriteMany # Multiple pods write content
storageClassName: nfs-storage
resources:
requests:
storage: 500Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
replicas: 5 # Multiple replicas sharing content
template:
spec:
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: content
mountPath: /usr/share/nginx/html
volumes:
- name: content
persistentVolumeClaim:
claimName: web-content
Access Mode Mismatch
If a PVC requests an access mode that no available PV supports, the PVC will remain in Pending state:
# Check PVC status
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES
my-pvc Pending # Stuck because no PV matches
# Check events
kubectl describe pvc my-pvc
# Events:
# Warning ProvisioningFailed no volume plugin matched
Solutions:
- Create a StorageClass that supports the required access mode
- Use a storage backend that supports the access mode (e.g., NFS for RWX)
- Change the access mode in the PVC to match available storage
Best Practices
- Use RWO by default - It’s the most widely supported and performant option
- Only use RWX when necessary - It requires network storage and has performance implications
- Consider alternatives - For read-only shared data, consider ConfigMaps instead of ROX volumes
- Match access mode to use case - Don’t request RWX if you only need RWO (better performance)
- Test access patterns - Verify that your storage backend supports the access mode you need
- Document requirements - Document why a specific access mode is needed
- Plan for scaling - Consider how access modes affect horizontal scaling
Troubleshooting
PVC Stuck in Pending
If a PVC is stuck because of access mode mismatch:
- Check available StorageClasses:
kubectl get storageclass - Verify StorageClass supports the access mode
- Check PVC events:
kubectl describe pvc <name> - Consider using a different storage backend that supports your access mode
Multiple Pods Need Write Access
If multiple pods need write access but you’re using RWO:
- Consider if RWX is truly needed (often RWO per pod is sufficient)
- Use StatefulSets with individual PVCs per pod (RWO per pod)
- Use a storage backend that supports RWX (NFS, cloud file storage)
- Consider application architecture changes to reduce shared write requirements
See Also
- PVs & PVCs - Creating and using persistent volumes
- Reclaim Policy - What happens when PVCs are deleted
- StorageClasses - Dynamic provisioning and storage templates
- StatefulSets - Managing stateful applications