Skip to main content
RunBook Academy

CephCXXIV · Production Reference ArchitectureProduction Reference Architecture

The six-node reference topology

Advanced⏱ ~18 mincephcephadmcrushtool

What you'll learn

  • Specify a node from the OSD count outwards
  • Justify six hosts rather than three or four
  • Choose a failure domain that two racks can honour
  • Derive usable capacity that survives a host loss

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

Node count and failure domain fix the availability envelope that every later decision inherits. Six nodes in two racks is the most common shape in the field, and it survives less than the people who build it assume.

The reference node

ComponentSpecificationWhy this number
Chassis2U, 12 x 3.5-inch baysone host is 1/6 of the cluster, so a host loss is a 17% rebuild
Data12 x 18 TB SAS HDD216 TB raw per node
DB/WAL2 x 1.6 TB NVMe, 6 OSDs eachblock.db at 4% of an 18 TB device is roughly 720 GB
Boot2 x 480 GB SATA SSD, mirroredthe OS never shares a device with an OSD
CPU2 x 16 coresabout 1 core per HDD OSD, plus headroom for network, mon, mgr, cephadm
RAM128 GiB4-5 GiB per HDD OSD plus 60 GiB for the OS and co-located daemons
NIC2 x 25 GbE, LACPa node backfills at roughly 20 Gbit/s of drive throughput
# let cephadm size OSD memory from what the host actually has
ceph config set osd osd_memory_target_autotune true
ceph config set mgr mgr/cephadm/autotune_memory_target_ratio 0.7

# or pin it per device class
ceph config set osd/class:hdd osd_memory_target 4294967296
ceph config set osd/class:ssd osd_memory_target 8589934592

Where the numbers change: an all-NVMe node wants 2-4 cores and 8-12 GiB per OSD and 100 GbE, and drops to 8-10 OSDs per chassis because CPU, not the bay count, becomes the limit.

Why six hosts and not three

HostsBehaviour with size=3 and a host failure domain
3placement works; a host loss cannot heal — there is nowhere for the third copy
4one host loss heals; a second concurrent loss does not
5a host loss heals while another host is in a maintenance window
6the above, and 4+2 erasure coding can place on hosts
7+4+2 erasure coding also self-heals a host loss
ceph orch host add node1 10.20.0.11 --labels=mon,osd
ceph osd crush rule create-replicated by-host default host
ceph osd pool set rbd-vm crush_rule by-host

Two racks and three replicas

A rule with `type rack` and size=3 needs three racks. Given two, CRUSH
returns two OSDs and the PGs stay undersized permanently. It does not
fall back to host.
DesignRack lossHost loss
size=3, failure domain hosthalf the OSDs gone; many PGs inactiveheals automatically
size=4, 2 racks x 2 hostsdegraded, still writable at min_size=2heals automatically
size=3, failure domain racknever places; do not build this on two racks
ceph osd getcrushmap -o /tmp/cm && crushtool -d /tmp/cm -o /tmp/cm.txt
# rule two-rack-four-copy {
#   type replicated
#   step take default
#   step choose firstn 2 type rack
#   step chooseleaf firstn 2 type host
#   step emit
# }
crushtool -c /tmp/cm.txt -o /tmp/cm.new
crushtool -i /tmp/cm.new --test --rule 2 --num-rep 4 --show-mappings | head
ceph osd setcrushmap -i /tmp/cm.new

Test the compiled map before installing it. --show-mappings prints the OSD set CRUSH would choose for each PG, and short sets are visible there before they are visible in ceph -s.

Monitors

Three monitors at this size; five once the cluster passes roughly fifteen hosts or spans more failure domains. Across two racks, three monitors put two in one rack.

ceph orch apply mon --placement="label:mon"
ceph quorum_status -f json | python3 -c '
import sys,json
d = json.load(sys.stdin)
print("quorum:", d["quorum_names"], " of", [m["name"] for m in d["monmap"]["mons"]])'

Capacity that survives a host loss

ConstraintCalculationResult
Raw6 x 216 TB1296 TB (1179 TiB)
Replicated at size=31296 / 3432 TB
Target fill 70%432 x 0.70302 TB
One host down, at nearfull 0.85(5 x 216 / 3) x 0.85306 TB

Both constraints land near 300 TB, which is the number to publish. Take another 1-2% off for BlueStore metadata.

Quiz

Knowledge check · 4 questions

  1. Q1. A six-host cluster in two racks uses a CRUSH rule with rack as the failure domain and size=3. What happens?

  2. Q2. With two racks and size=3, a rack failure domain is safe because CRUSH falls back to host placement for the third replica.

  3. Q3. Size a six-node cluster and publish a usable capacity figure.

    Six nodes, each with 12 x 18 TB HDDs, size=3 replication, host failure domain. The finance team wants a single number for the storage they can sell internally.

  4. Q4. Why does the reference design use six hosts rather than four?

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

Production discipline

Publish the capacity figure that survives a host loss, not the one that assumes all six hosts are up. Test any CRUSH rule with crushtool --test --show-mappings before installing it — a rule that cannot satisfy its own replica count fails silently at map load and only becomes visible as undersized PGs afterwards.

Cross-course references

  • Kubernetes: a three-node control plane in two racks has the same quorum problem
  • Linux: quorum devices exist because an even split of votes has no correct winner