Skip to main content
RunBook Academy

CephCIV · Multi-Tenancy in PracticeMulti-Tenancy in Practice

Operating CephFS subvolume tenancy over time

Advanced⏱ ~18 minceph

What you'll learn

  • Manage subvolume lifecycle after creation
  • Change a quota safely
  • Handle snapshots per tenant
  • Understand where CephFS quota enforcement actually happens

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

Not yet marked complete on this device.

Why this matters in production

Subvolumes are easy to create and the operational questions arrive afterwards: growth, snapshots, and what happens at the limit.

Lifecycle after creation

ceph fs subvolume ls cephfs
ceph fs subvolume info cephfs acme-prod --group_name tenants
{
    "bytes_quota": 5497558138880,
    "bytes_used": 3211698176,
    "path": "/volumes/tenants/acme-prod/<uuid>",
    "mode": 16877,
    "created_at": "2026-03-14 09:12:01"
}
# per-tenant usage across a group
ceph fs subvolume ls cephfs --group_name tenants --format json | python3 -c '
import sys,json,subprocess
for s in json.load(sys.stdin):
    n = s["name"]
    i = json.loads(subprocess.check_output(
        ["ceph","fs","subvolume","info","cephfs",n,"--group_name","tenants",
         "--format","json"]))
    q = i.get("bytes_quota") or 0
    u = i.get("bytes_used") or 0
    pct = (100.0*u/q) if isinstance(q,int) and q else 0
    print("%-20s %8.1f GiB / %8.1f GiB  %5.1f%%" %
          (n, u/1024**3, (q/1024**3) if isinstance(q,int) else 0, pct))'

Changing a quota

ceph fs subvolume resize cephfs acme-prod 10995116277760 --group_name tenants
# removing the quota entirely
ceph fs subvolume resize cephfs acme-prod infinite --group_name tenants
ChangeEffect
Increasingtakes effect for clients as they refresh
Decreasing below current usageexisting data stays; new writes are refused
infiniteno quota; the tenant is bounded only by the pool
Decreasing below current usage does not delete anything. It stops
growth, which is usually what is wanted, and it does surprise a tenant
who expected an error at set time rather than at write time.

Snapshots per tenant

ceph fs subvolume snapshot create cephfs acme-prod snap-$(date +%Y%m%d) \
  --group_name tenants
ceph fs subvolume snapshot ls cephfs acme-prod --group_name tenants
ceph fs subvolume snapshot info cephfs acme-prod snap-20260818 \
  --group_name tenants
ceph fs subvolume snapshot rm cephfs acme-prod snap-20260701 --group_name tenants
Snapshot capacity is not free and is not counted against the subvolume
quota — it consumes pool capacity as the snapshotted data diverges.
ceph df detail

Where quota enforcement happens

CephFS quotas are enforced by the client, not by the MDS or the OSDs.
ClientEnforces
Kernel client, recentyes
ceph-fuseyes
An old kernel clientmay not
A client with a modified implementationnot necessarily
ceph tell mds.0 client ls --format json | python3 -c '
import sys,json
for c in json.load(sys.stdin):
    md = c.get("client_metadata", {})
    print("%-18s %-14s %s" % (md.get("entity_id"), md.get("ceph_version","?")[:12],
                              md.get("hostname")))'
So a subvolume quota bounds a cooperating tenant. A pool quota, enforced
at the cluster, bounds any tenant.

Quiz

Knowledge check · 4 questions

  1. Q1. Where are CephFS quotas enforced?

  2. Q2. A tenant on a modest subvolume quota can occupy far more pool capacity than that quota suggests.

  3. Q3. Reduce a tenant's CephFS quota.

    A tenant's subvolume quota needs reducing from 10 TiB to 5 TiB. They currently use 7 TiB.

  4. Q4. What bounds a non-cooperating tenant that a subvolume quota does not?

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

Production discipline

Use a per-tenant pool with a pool quota where the boundary must hold regardless of client behaviour — CephFS subvolume quotas are enforced by the client. Track snapshot retention separately; snapshots consume pool capacity without counting against the subvolume quota.

Cross-course references

  • Kubernetes: ResourceQuota is enforced by the API server, not the workload
  • Linux: a limit the client enforces bounds cooperation, not capability