Skip to main content
RunBook Academy

CephXLV · RADOS Gateway (RGW)RADOS Gateway (RGW)

Zones: the unit of data placement

Advanced⏱ ~17 minradosgw-admin

What you'll learn

  • Explain what a zone owns
  • Inspect and modify zone configuration
  • Relate zones to pools and placement targets
  • Understand the realm, zonegroup, zone hierarchy

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

Every RGW deployment has a zone, whether or not anyone configured one. It is the object that owns the pools, and understanding it is what makes placement targets, storage classes, and eventually multisite comprehensible rather than a set of commands to copy.

The hierarchy

realm                 ← a namespace for the whole configuration
└── zonegroup         ← a replication group; contains zones
    └── zone          ← owns pools; holds the actual data
radosgw-admin realm list
radosgw-admin zonegroup list
radosgw-admin zone list

radosgw-admin realm get
radosgw-admin zonegroup get
radosgw-admin zone get --rgw-zone=default

A single-site deployment has one of each. The structure exists so that multisite is a matter of adding zones rather than restructuring.

What a zone owns

radosgw-admin zone get --rgw-zone=default | jq '{name, system_key, placement_pools}'
{
  "name": "default",
  "placement_pools": [{
    "key": "default-placement",
    "val": {
      "index_pool": "default.rgw.buckets.index",
      "storage_classes": {
        "STANDARD": {"data_pool": "default.rgw.buckets.data"}
      },
      "data_extra_pool": "default.rgw.buckets.non-ec"
    }
  }]
}

Plus the zone-level pools:

radosgw-admin zone get --rgw-zone=default | \
  jq '{domain_root, control_pool, gc_pool, lc_pool, log_pool, user_uid_pool}'
PoolHolds
domain_root / .rgw.metabucket and user metadata
.rgw.buckets.indexbucket indexes
.rgw.buckets.dataobject data
.rgw.buckets.non-ecin-flight multipart state
.rgw.logoperation and usage logs
.rgw.controlcontrol objects
gc_poolgarbage collection queue

Placement targets and storage classes

radosgw-admin zonegroup placement add \
    --rgw-zonegroup=default --placement-id=cold-placement

radosgw-admin zone placement add \
    --rgw-zone=default --placement-id=cold-placement \
    --data-pool=cold-ec-pool \
    --index-pool=default.rgw.buckets.index

radosgw-admin user modify --uid=alice --placement-id=cold-placement

A placement target names a set of pools. A storage class within it names a data pool, which is what a lifecycle transition moves objects between.

Applying changes

radosgw-admin period update --commit
ceph orch restart rgw.default

Zone and zonegroup changes require a period commit to take effect. This is the step most commonly forgotten, and its absence makes a correct configuration change appear to do nothing.

Quiz

Knowledge check · 4 questions

  1. Q1. You modify a zone's placement configuration and the change has no effect. What is the most likely omission?

  2. Q2. The realm and zonegroup objects are only needed for multisite deployments.

  3. Q3. Add a cold storage tier to an existing RGW deployment.

    A team wants to offer a cheaper storage class backed by an EC pool, so that lifecycle rules can transition old objects to it. The existing deployment uses the default zone with a single replicated data pool.

  4. Q4. What is the relationship between a placement target and a storage class?

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

Production discipline

Run radosgw-admin period update --commit after every zone or zonegroup change and verify the gateways picked it up; the change appears applied in zone get regardless, which makes its absence hard to spot. Document the pool-to-purpose mapping for your zone, since the names are similar and their requirements differ substantially.

Cross-course references

  • Kubernetes: a config change that needs a rollout to take effect has the same applied-but-not-live property
  • Linux: configuration written but not reloaded is the identical class of confusion