Ceph administration demands precision. A single misapplied command can cascade into data unavailability or prolonged recovery. This guide provides version-aware, production-tested workflows for Reef (18.2.x), Squid (19.2.x), and 20.x releases. It replaces generic cheat sheets with concrete procedures: inventory baselines, scoped configuration changes, diagnostic deep-dives, and documented recovery paths for monitor quorum loss, OSD replacement, PG inconsistency, and capacity pressure. Every command includes expected output signals, verification steps, and rollback actions.

## Prerequisites and Environment Inventory

### Supported Release Matrix

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Series</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Version Range</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">cephadm Default</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Container Runtime</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Minimum Kernel</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Python</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Reef</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">18.2.x</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Yes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">podman / docker</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">5.15+</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">3.8+</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Squid</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">19.2.x</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Yes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">podman / docker</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">6.1+</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">3.10+</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">20.x</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">20.0.x</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Yes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">podman / docker</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">6.5+</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">3.11+</td></tr></tbody>
</table>
</div>
Package-based deployments (apt, yum, dnf) use systemctl for daemon management; cephadm clusters run all daemons in containers. Never mix orchestration methods on the same cluster.

### Admin Access Requirements

- Keyring : /etc/ceph/ceph.client.admin.keyring (mode 0600, owned by root:root) or CEPH_KEYRING environment variable.

- Config : /etc/ceph/ceph.conf or CEPH_CONF pointing to a valid config with mon_host entries.

- Privileges : sudo or root; cephadm requires passwordless sudo for the cephadm user.

- Network : TCP 6789/3300 (mon), 6800–7300 (OSD/MDS/MGR/RGW) reachable between all nodes; DNS or /etc/hosts resolution for monitor hostnames.

- Quorum Health : ceph -s must show mon: <N> daemons, quorum <ids> before any write operation.

### Baseline Capture Commands

Run these before any change and store outputs with timestamped filenames:

ceph -s -f json
ceph versions -f json
cephadm ls -f json
ceph config dump -f json > baseline-config-$(date +%F-%H%M).json
ceph auth ls -f json
ceph osd tree -f json > baseline-topology-$(date +%F-%H%M).json 
 Commit these to version control or attach to your change ticket for rollback reference.

## Architecture Quick-Reference

### Daemon Roles and Key Commands

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Daemon</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Purpose</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Health Check</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Common CLI</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Monitor (mon)</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Cluster map, quorum, auth</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph mon dump</code>, <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph tell mon.* version</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph mon stat</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Manager (mgr)</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Metrics, modules, dashboard, orchestrator</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph mgr stat</code>, <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph mgr module ls</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph tell mgr.* perf dump</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">OSD</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Data storage, replication, recovery</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph osd tree</code>, <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph osd df</code>, <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph osd perf</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph daemon osd.&lt;id&gt; perf dump</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">MDS</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">CephFS metadata, journal</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph fs status</code>, <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph mds stat</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph tell mds.* session ls</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">RGW</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">S3/Swift object gateway</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph orch ps --daemon-type rgw</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">radosgw-admin realm list</code></td></tr></tbody>
</table>
</div>

### CRUSH Hierarchy and Device Classes

Default hierarchy:

root=default
 datacenter=dc1
 room=room1
 row=row1
 rack=rack1
 chassis=chassis1
 host=storage-01
 osd.0 (class=hdd)
 osd.1 (class=nvme) 
 Device classes ( hdd , ssd , nvme ) drive PG placement via crush rules. List classes with ceph osd crush class ls .

### PG State Cheat Sheet

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">State</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Meaning</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Action Required</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">active+clean</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Healthy, all replicas current</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">None</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">active+remapped</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Acting set ≠ up set; backfill in progress</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Monitor</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">degraded</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Missing replicas, below min_size</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Investigate OSD down</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">peering / recovery / backfill</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Transient rebuild states</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Wait, verify progress</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">incomplete</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Insufficient OSDs to satisfy min_size</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Add OSDs or adjust min_size</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">stale</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">PG not updated by mon; possible mon issue</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Check mon quorum</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">undersized</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Fewer copies than size but ≥ min_size</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Plan OSD replacement</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">inconsistent</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Scrub detected data mismatch</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph pg repair</code> (see warnings)</td></tr></tbody>
</table>
</div>

## Version and Environment Inventory (Concrete)

### Core Inventory Commands

# Full version report (JSON includes overall, mon, mgr, osd, mds, rgw)
ceph versions -f json

# cephadm-managed daemon inventory
cephadm ls -f json

# Orchestrator host/daemon view
ceph orch host ls -f json
ceph orch ps -f json --format=json-pretty

# Capacity and utilization
ceph df -f json
ceph osd df -f json
ceph pg stat -f json 

### Expected JSON Fields and Health Indicators

- ceph versions : "overall": "18.2.4" , "mon": ["18.2.4", "18.2.4", "18.2.4"] , "mgr": "18.2.4" , "osd": ["18.2.4" ...] . Mixed versions → plan upgrade.

- cephadm ls : Each entry shows "style": "cephadm:v18.2.4" , "name": "osd.0" , "container_image_name": "docker.io/ceph/ceph:v18.2.4" , "status": "running" .

- ceph df : "stats": {"total_bytes": 10995116277760, "total_used_bytes": 3298534883328, "total_avail_bytes": 7696581394432} . total_avail_bytes below 30% → rebalance needed.

- ceph pg stat : "pgmap": {"num_pgs": 1024, "num_objects": 50000, "state": ["active+clean": 1020, "active+remapped": 4]} .

## Safe Configuration Path

### Read-Only Audit First

 # Full effective config (all sections, all daemons)
ceph config dump -f json

# Single key for a specific daemon or global
ceph config get global osd_pool_default_size
ceph config get osd.0 osd_memory_target
ceph config get mgr mgr/cephadm/container_image_base 

### Scoped Changes with Defined Blast Radius

 Change Command Blast Radius Prerequisites 
 Enable PG autoscaler (preferred over manual pg_num) ceph config set global osd_pool_default_pg_autoscale_mode on All new pools; existing pools unchanged until ceph osd pool set <pool> pg_autoscale_mode on Mgr active, PG autoscaler module enabled 
 Set default replica count ceph config set global osd_pool_default_size 3 New pools only min_size ≤ size ; quorum healthy 
 Allow pool deletion (dangerous) ceph config set global mon_allow_pool_delete true Cluster-wide; enables destructive ops Maintenance window, backup verified 
 Pin cephadm container image ceph config set mgr mgr/cephadm/container_image_base docker.io/ceph/ceph Next redeploy/upgrade Image exists in registry, matches release series 

### Verification After Change

 # Show diff from on-disk ceph.conf and monitor DB
ceph config diff -f json

# Confirm pool-level autoscaler state
ceph osd pool ls detail -f json | jq '.[] | {pool_name, pg_autoscale_mode, pg_num, pgp_num}'

# Health and PG state
ceph -s
ceph pg stat 

### Rollback Procedures

 # Remove a config key (reverts to compiled default or parent scope)
ceph config rm global osd_pool_default_pg_autoscale_mode

# Restore previous explicit value
ceph config set global osd_pool_default_size 3

# Redeploy affected daemons to pick up config (cephadm only)
cephadm redeploy --limit osd --dry-run
cephadm redeploy --limit osd 
 ⚠️ Blast Radius : cephadm redeploy restarts daemons; schedule during low I/O. Verify ceph -s returns HEALTH_OK within 5 minutes.

## Verification and Diagnostics

### Health Deep-Dive

# Detailed health with codes and descriptions
ceph health detail -f json

# Mute a specific check with TTL (e.g., during planned OSD maintenance)
ceph health mute OSD_DOWN 1h --sticky

# PGs by state (filter for actionable states)
ceph pg ls bystate degraded,inconsistent,incomplete,stale,undersized -f json

# OSD tree with weights and device classes
ceph osd tree -f json

# OSD performance counters (latency, throughput)
ceph osd perf -f json 

### Slow Operations and OSD Internals

 # Historic slow ops on a specific OSD (requires mgr active)
ceph daemon osd.0 dump_historic_ops -f json

# Heap stats across all OSDs (memory pressure)
ceph tell osd.* heap stats -f json

# Perf dump from OSD daemon (latency histograms, queue depths)
ceph daemon osd.0 perf dump -f json | jq '.osd_op_latency, .commit_latency, .apply_latency' 

### Network and Clock Diagnostics

 # Monitor clock skew check (requires mon quorum)
ceph mon_clock_skew_check -f json

# Mon version and map epoch
ceph tell mon.* version -f json

# Network connectivity from admin node
ceph tell mon.* ping -f json 

### Log Collection

 # cephadm logs (last 100 lines)
ceph log last cephadm 100

# Systemd journal for a specific daemon (package or cephadm)
journalctl -u ceph-<FSID>@osd.0 -n 200 --no-pager

# Ceph daemon log via socket (works for both deployments)
ceph daemon osd.0 log flush
ceph daemon osd.0 log reopen 

## Failure Modes and Recovery

### Monitor Quorum Loss

 Symptoms : ceph -s shows mon: 1 daemons, quorum <single> , HEALTH_ERR , client I/O errors. Prerequisites : At least one mon running, access to its DB ( /var/lib/ceph/mon/ceph-<id>/store.db ).

Recovery :

# 1. Dump monmap from surviving mon
ceph mon dump -f json > monmap-backup.json

# 2. Stop all mons, inject monmap on each
systemctl stop ceph-mon@<id> # or cephadm: ceph orch daemon stop mon.<host>
ceph-mon -i <id> --inject-monmap monmap-backup.json

# 3. Start mons sequentially, verify quorum
systemctl start ceph-mon@<id>
ceph -s 
 Disaster Recovery : If all mons lost, rebuild from ceph-mon --mkfs -i <id> --monmap <file> --keyring <admin-keyring> using a saved monmap.

### OSD Down / Out / Replacement

Symptoms : ceph osd tree shows down , out , or destroyed ; PGs degraded / recovery .

Workflow :

# 1. Mark OSD out (starts rebalance)
ceph osd out 12

# 2. Wait for PGs to reach active+clean (monitor)
ceph -w # or: while ceph pg ls degraded -f json | grep -q degraded; do sleep 10; done

# 3. Destroy OSD (removes from crush, deletes auth)
ceph osd destroy 12 --yes-i-really-mean-it

# 4. Zap device (package or cephadm)
ceph-volume lvm zap /dev/sdX --destroy

# 5. Add replacement (cephadm)
ceph orch daemon add osd storage-01:/dev/nvme0n1
# Package: ceph-volume lvm create --bluestore --data /dev/nvme0n1 
 ⚠️ Warning : Never ceph osd destroy without prior ceph osd out and clean rebalance. Data loss risk if PGs not active+clean .

### PG Inconsistent / Stuck

Symptoms : ceph health detail shows PG_INCONSISTENT , ceph pg ls inconsistent returns PG IDs. Prerequisites : Identify affected PGs, verify backups, understand ceph pg repair may discard data.

Recovery :

# 1. List inconsistent PGs with details
ceph pg ls inconsistent -f json

# 2. Repair single PG (run on primary OSD if possible)
ceph pg repair 1.5

# 3. Monitor repair state
ceph pg ls 1.5 -f json -w # watch for "repair" state to clear

# 4. If repair fails, deep-scrub first
ceph pg deep-scrub 1.5
ceph pg repair 1.5 
 🔄 Rollback : No automated rollback; restore from backup if repair causes data loss.

### Full / Nearfull Cluster

Symptoms : HEALTH_ERR / HEALTH_WARN FULL / NEARFULL , ceph df shows > 85% / 95% used.

Recovery :

# 1. Identify utilization outliers
ceph osd df -f json | jq '.nodes[] | select(.type=="osd") | {id, utilization, kb_avail}'

# 2. Temporarily adjust full ratios (buys time)
ceph config set global mon_osd_full_ratio 0.95
ceph config set global mon_osd_nearfull_ratio 0.85

# 3. Reweight overfull OSDs (gradual)
ceph osd crush reweight osd.0 0.8

# 4. Add capacity (preferred)
ceph orch daemon add osd <host>:<device>

# 5. Trigger balancer
ceph balancer on
ceph balancer status -f json 

### cephadm Bootstrap / Upgrade Failures

 Symptoms : cephadm bootstrap hangs, cephadm upgrade reports upgrade_plan errors.

Diagnostics :

# Dry-run before any change
cephadm bootstrap --dry-run --config /etc/ceph/ceph.conf
cephadm upgrade --dry-run --image docker.io/ceph/ceph:v19.2.0

# Inspect upgrade plan
cephadm upgrade --dry-run --image docker.io/ceph/ceph:v19.2.0 -f json | jq '.upgrade_plan'

# Redeploy specific daemon type after failed upgrade
cephadm redeploy --limit mgr --dry-run
cephadm redeploy --limit mgr 
 Recovery : Rollback container image via ceph config set mgr mgr/cephadm/container_image_base  then cephadm redeploy --limit mgr .

## Operations Checklist (Runbook Style)

### Pre-Change Validation

- [ ] ceph -s → HEALTH_OK or known HEALTH_WARN (documented)

- [ ] ceph config dump -f json > pre-change-$(date +%F-%H%M).json

- [ ] ceph df → capacity headroom > 20%

- [ ] Maintenance window approved, stakeholders notified

- [ ] Rollback commands drafted and tested in dry-run mode

### Per-Task Execution Template

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Field</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Example</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Command</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph osd out 12</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Prerequisites</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Quorum healthy, PGs <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">active+clean</code>, OSD 12 <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">up</code> / <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">in</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Expected Output</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">marked osd.12 out</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Verification</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph pg stat</code> shows recovery → <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">active+clean</code> within 30 min</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Rollback</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ceph osd in 12</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Timeout</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">45 minutes; escalate if &gt; 10% PGs stuck recovery</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Operator / Ticket</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ops-2024-0423</code>, <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">alice@example.com</code></td></tr></tbody>
</table>
</div>

### Post-Change Verification

- [ ] ceph -s → HEALTH_OK

- [ ] ceph pg stat → all active+clean (zero degraded , inconsistent , stale )

- [ ] ceph osd perf → commit_latency < 10 ms, apply_latency < 5 ms (adjust for workload)

- [ ] Dashboard alerts clear; no new ceph health detail warnings

- [ ] ceph config diff matches intended change only

### Documentation Requirements

- Ticket reference, operator name, start/end timestamps

- ceph config diff output attached

- ceph -s and ceph pg stat before/after snapshots

- Any anomalies observed and mitigation steps taken

## Realistic Technical Scenario

### Scenario: Add Three NVMe OSDs to storage-04 in a Reef 18.2.4 cephadm Cluster

Goal : Expand capacity by 3 × 3.84 TB NVMe on storage-04 , verify rebalance completes without client-visible latency spike.

### Prerequisites

- Cluster HEALTH_OK , ceph versions shows all daemons 18.2.4

- storage-04 labeled: ceph orch host label add storage-04 nvme

- Devices visible: lsblk -d -o NAME,SIZE,TYPE,MODEL /dev/nvme[0-2]n1

- Admin keyring and ceph.conf on control node

### Execution Steps

# 1. Add OSDs (cephadm orchestrates ceph-volume lvm internally)
ceph orch daemon add osd storage-04:/dev/nvme0n1
ceph orch daemon add osd storage-04:/dev/nvme1n1
ceph orch daemon add osd storage-04:/dev/nvme2n1

# 2. Watch PG rebalance in real time
ceph -w # press 'q' to quit; look for "pgmap" updates

# 3. Monitor PG stats until settled
while true; do
 ceph pg stat -f json | jq '.pgmap | {active_clean: .state_counts[] | select(.name=="active+clean") | .count, recovering: .state_counts[] | select(.name=="recovery") | .count}'
 sleep 30
done

# 4. Verify OSD performance during rebalance
ceph osd perf -f json | jq '.osd_perf_infos[] | select(.id==12 or .id==13 or .id==14) | {id, commit_latency_ms, apply_latency_ms}'

# 5. Check balancer status (auto-enabled in Reef+)
ceph balancer status -f json

# 6. Confirm even utilization
ceph osd df -f json | jq '.nodes[] | select(.type=="osd") | {id, utilization, kb_avail}' | sort -k2 -n 

### Verification Criteria

- All PGs active+clean within 2 hours (adjust for data volume)

- ceph osd perf latency on new OSDs ≤ existing OSD median + 20%

- ceph df shows utilization variance 

### Rollback Plan

 # If rebalance stalls or latency spikes:
ceph orch daemon rm osd.12 osd.13 osd.14
ceph-volume lvm zap /dev/nvme0n1 /dev/nvme1n1 /dev/nvme2n1 --destroy
ceph osd crush rm osd.12 osd.13 osd.14 # if crush entries remain 
 Document final state with ceph config dump > post-expansion-$(date +%F).json .

## Conclusion

Operational safety in Ceph demands version-scoped commands, observed baselines, and tested rollback paths for every change. This guide replaces generic cheat sheets with concrete workflows: inventory Reef, Squid, and 20.x releases via ceph versions and cephadm ls ; diagnose with ceph health detail and ceph daemon perf dump ; execute scoped changes like PG autoscaler enablement or OSD replacement with explicit verification using ceph pg stat and ceph osd perf ; and recover from quorum loss, PG inconsistency, or capacity pressure using documented procedures. Always capture ceph config dump and ceph -s snapshots before and after; mute health checks with TTL during planned maintenance; distinguish cephadm container workflows from package-based systemctl operations. The next step is to select one read-only verification from this guide, run it against your cluster, compare output to the expected signals documented here, and record the result in your runbook.