CephCIX · Disaster RecoveryDisaster Recovery
Scenario modelling: what survives each failure
What you'll learn
- Build a scenario model for a cluster
- Determine what survives each scenario
- Identify scenarios with no surviving copy
- Use the model to prioritise investment
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
Every design decision assumes some failure will not happen. Writing those assumptions down is what makes them reviewable.
Building the model
# what the cluster's structure is
ceph osd tree
ceph osd crush rule ls
ceph osd crush rule dump | python3 -c '
import sys,json
for r in json.load(sys.stdin):
dom = [s.get("type") for s in r.get("steps",[]) if s.get("type")]
print("%-20s failure domain: %s" % (r["rule_name"], dom))'
ceph osd pool ls detail | grep -E '^pool' | head
For each failure scenario, the question is: does a complete copy of
each pool's data survive?
The scenarios
| Scenario | Survives if |
|---|---|
| One disk | replication or EC — always |
| One host | failure domain is host or wider |
| One rack | failure domain is rack or wider |
| One room or power domain | CRUSH reflects it |
| The site | a copy exists elsewhere |
| Two sites simultaneously | a third copy exists |
| The cluster, logically (bad change) | an off-cluster copy exists |
| The organisation’s whole environment | an externally-held copy exists |
# does the CRUSH topology actually reflect the physical layout?
ceph osd tree | head -30
A cluster whose CRUSH map has every host under one rack bucket cannot
survive a rack failure regardless of what the racks physically are.
# simulate: which PGs would be affected by losing a bucket
ceph osd crush tree --format json | python3 -c '
import sys,json
def walk(n, depth=0):
print(" "*depth + "%s (%s)" % (n.get("name"), n.get("type")))
for c in n.get("children", []): pass
for n in json.load(sys.stdin).get("nodes", [])[:15]:
print("%-6s %-16s %s" % (n.get("type"), n.get("name"), n.get("id")))'
Finding the uncovered scenarios
For each scenario, record:
what survives
where it is
how it would be used
how long that would take
| Scenario | Surviving copy | Uncovered |
|---|---|---|
| Disk, host, rack | the cluster itself | no |
| Site | mirror at site B | no |
| Both sites | — | yes |
| Bad operator change | off-cluster backup | no |
| Ransomware with cluster credentials | object-locked copy | check |
| Backup target also lost | — | check |
Two uncovered scenarios are usually acceptable and should be written
down as accepted risk. Two uncovered scenarios nobody has noticed are
not the same thing.
Using the model
The model turns "should we invest in X" into "X covers scenario N,
which is currently uncovered and has impact Y".
| Investment | Covers |
|---|---|
| Rack-level failure domain | rack loss |
| A second site with mirroring | site loss |
| Off-cluster backup | logical destruction |
| Object lock on the backup | ransomware reaching the backup |
| A third copy or a third site | simultaneous two-site loss |
Quiz
Knowledge check · 4 questions
Q1. What invalidates a scenario model built from pool replication settings?
Q2. A scenario model is only useful if every scenario is covered.
Q3. Build a scenario model.
A cluster spans three racks with rack-level failure domain, has a mirror at a second site, and nightly off-cluster backups to a target in the same building as the primary.
Q4. What should be recorded for each scenario in the model?
Passing score: 75%. Answers are checked in this browser.
Production discipline
Verify the CRUSH tree against actual physical placement before trusting a scenario model — pool settings say the cluster survives rack loss even when every host sits under one rack bucket. Write down the uncovered scenarios as accepted risk; that is what makes them decisions.
Cross-course references
- Kubernetes: topology spread constraints only work if node labels reflect reality
- Linux: an assumption written down is reviewable; the same assumption implicit is not