Skip to main content
RunBook Academy

CephXCIII · Changing CRUSH TopologyChanging CRUSH Topology

Moving buckets in the hierarchy

Advanced⏱ ~17 mincephcrushtool

What you'll learn

  • Move buckets safely
  • Predict the movement a move causes
  • Handle moves that restructure the hierarchy
  • Verify the result

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

Moving a bucket changes placement for every PG that could map through it, and the volume depends on what the move changes about the selection.

The move commands

# a host into a rack
ceph osd crush move ceph-07 rack=rack4

# a rack under a different root
ceph osd crush move rack4 root=default

# an individual OSD to a different host — rarely correct
ceph osd crush move osd.84 host=ceph-08

The third is almost always wrong: an OSD’s CRUSH host should match its physical host, and moving it makes the map describe something untrue.

ceph osd crush tree
ceph osd find 84

Predicting the movement

MoveMovement
Host into a rack, from the default rootproportional to how placement changes
Host between rackspotentially large for rack-domain pools
Rack under a different rootevery pool using that root
An empty bucketnone
A bucket whose children are emptynone
# compute it before committing
ceph osd getcrushmap -o /tmp/crush.bin
crushtool -d /tmp/crush.bin -o /tmp/crush.txt
# edit the move into /tmp/crush.txt
crushtool -c /tmp/crush.txt -o /tmp/crush-new.bin
crushtool -i /tmp/crush.bin --compare /tmp/crush-new.bin --rule 1 --num-rep 3

The comparison gives the exact PG count that changes.

Restructuring the hierarchy

Introducing a rack level to a host-only hierarchy:
  create the rack buckets
  move each host into its rack
  change the rule to use the rack failure domain
ceph osd crush add-bucket rack1 rack
ceph osd crush add-bucket rack2 rack
ceph osd crush add-bucket rack3 rack
for r in rack1 rack2 rack3; do ceph osd crush move $r root=default; done

ceph osd crush move ceph-01 rack=rack1
ceph osd crush move ceph-02 rack=rack2
ceph osd crush move ceph-03 rack=rack3
Moving hosts into racks alone moves little — the hosts are still under the
same root and the rule still selects by host.
Changing the rule to rack is what moves the data.

Separating the two means the structural change and the placement change can be staged.

# Substitute the pool you are moving before running:
POOL=rbd-vms

ceph osd crush rule create-replicated rack-rule default rack
ceph osd pool set "$POOL" crush_rule rack-rule

Verifying

ceph osd crush tree
ceph osd tree
ceph -s | grep misplaced
# every host is where it should be
ceph osd crush tree --format json | python3 -c '
import sys, json
def walk(n, parent=None):
    if n.get("type") == "host": print(n["name"], "under", parent)
    for c in n.get("children", []):
        if isinstance(c, dict): walk(c, n["name"])
for r in json.load(sys.stdin)["nodes"]:
    if r.get("type") == "root": walk(r)'

Quiz

Knowledge check · 4 questions

  1. Q1. Why does moving hosts into newly created rack buckets move little data?

  2. Q2. Moving an OSD to a different CRUSH host is a reasonable way to balance host utilisation.

  3. Q3. Introduce a rack level to a flat hierarchy.

    A cluster has hosts directly under the root and now spans three racks. The team wants rack-level failure domains.

  4. Q4. How do you compute the movement a CRUSH move will cause?

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

Production discipline

Stage a hierarchy restructure: move the hosts into their buckets first, which moves little, then change the rule, which moves a lot. Never place an OSD in a CRUSH host different from its physical one — every failure domain guarantee becomes false and nothing detects it.

Cross-course references

  • Kubernetes: topology labels must correspond to physical reality to mean anything
  • Linux: staging structural and behavioural changes separately makes each verifiable