CephLXXXVII · Kubernetes CephFSKubernetes CephFS
Shared CephFS volumes across pods
What you'll learn
- Explain the guarantees CephFS provides to concurrent writers
- Use the locking mechanisms that work
- Recognise patterns that fail despite POSIX semantics
- Design applications for shared volumes
Prerequisites
None — start here.
Verified against Ceph Tentacle 20.2.x · Ceph Squid 19.2.x (supported previous) · cephadm matches the verified Ceph release · podman 4.x · csi-rbd and csi-cephfs current · RBD / CephFS / RGW current (matches Ceph release) · Linux kernel 5.15+ (5.10 minimum) · Ubuntu 24.04 LTS (Ceph host baseline) · Debian 12 (Bookworm) (Ceph host baseline) · Rocky Linux / RHEL / AlmaLinux 9.x (Ceph host baseline) · Proxmox VE 9.x (cross-course integration) · Kubernetes 1.31+ (cross-course integration) · 2026-08-18
Why this matters in production
CephFS gives several pods a genuinely shared POSIX filesystem, which is more than most shared storage provides and less than some applications assume.
What is guaranteed
| Guarantee | Provided |
|---|---|
| A write visible to other clients after it completes | yes |
| POSIX read/write semantics | yes |
fcntl advisory locks across clients | yes |
flock across clients | yes |
| Atomic rename within the filesystem | yes |
| Directory operations serialised correctly | yes |
O_APPEND atomicity across clients | yes |
| Byte-range locking | yes, advisory |
| Mandatory locking | no |
spec:
accessModes: [ReadWriteMany]
storageClassName: ceph-fs
The locking that works
import fcntl
with open('/data/shared.lock', 'w') as f:
fcntl.flock(f, fcntl.LOCK_EX)
# exclusive across every pod on every node
fcntl.flock(f, fcntl.LOCK_UN)
# from a shell
flock /data/shared.lock -c 'do-the-thing'
Both flock and fcntl locks are coordinated by the MDS and work across
nodes, which is the property that makes CephFS suitable for leader
election and coordinated access.
Patterns that fail despite POSIX semantics
| Pattern | Problem |
|---|---|
| Assuming a lock survives a client eviction | the MDS releases it |
| Relying on lock ordering for correctness | no ordering guarantee between waiters |
| Using file existence as a lock | not atomic; use O_EXCL |
| Heavy small-file metadata operations | MDS becomes the bottleneck |
| Many pods appending to one file | correct but heavily contended |
| Assuming close-to-open consistency is enough | CephFS is stronger, but applications may assume weaker |
# atomic creation, correct
fd = os.open('/data/lock', os.O_CREAT | os.O_EXCL | os.O_WRONLY)
The eviction case
ceph tell mds.0 client ls
ceph osd blocklist ls
A client that loses contact with the MDS is eventually evicted
→ its capabilities are revoked
→ its locks are released
→ another pod can acquire them
→ the evicted pod may still believe it holds the lock
Applications relying on locks for correctness must handle losing them, which means checking a fencing token or re-validating rather than assuming continuity.
Designing for shared volumes
| Requirement | Approach |
|---|---|
| Coordinated writes | flock with re-validation after any I/O error |
| Independent per-pod data | separate directories, no coordination needed |
| High metadata rate | consider whether the workload suits a filesystem |
| Leader election | a dedicated mechanism, not a file lock |
| Append-only log from many writers | one writer, others queue |
Quiz
Knowledge check · 4 questions
Q1. What makes ReadWriteMany meaningful for CephFS and impossible for RBD?
Q2. A CephFS `flock` held by a pod persists even if that pod's client is evicted by the MDS.
Q3. Design an application for a shared CephFS volume.
An application will run several replicas writing to a shared CephFS volume, using a lock file to coordinate exclusive sections.
Q4. Why is using file existence as a lock incorrect on CephFS?
Passing score: 75%. Answers are checked in this browser.
Production discipline
Use flock or fcntl for coordination on shared CephFS volumes —
both are arbitrated by the MDS and work across nodes — and treat any I/O
error as a signal the client may have been evicted and its locks released.
Never use file existence as a lock; O_CREAT | O_EXCL is the atomic
primitive.
Cross-course references
- Kubernetes: leases and leader election exist because file locks are not sufficient
- Linux: NFS and cluster filesystems face identical lock-recovery semantics