Skip to main content
RunBook Academy

CephCXXIV · Production Reference ArchitectureProduction Reference Architecture

The monitoring stack that ships with the design

Intermediate⏱ ~18 mincephpromtool

What you'll learn

  • Deploy the monitoring stack with retention that outlives an incident
  • Choose alert conditions from Ceph health checks rather than raw metrics
  • Derive each threshold from the time required to act on it
  • Keep metrics and alerting available when the cluster is not

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

Ceph degrades gracefully, which means it will run for weeks in a state that is quietly consuming your remaining redundancy. Alerting is what converts that silence into a ticket, and the thresholds decide whether the ticket arrives while there is still time to act on it.

The stack

ceph mgr module enable prometheus
ceph config set mgr mgr/prometheus/scrape_interval 15

ceph orch apply node-exporter --placement='*'
ceph orch apply prometheus   --placement="1 node1"
ceph orch apply alertmanager --placement="1 node1"
ceph orch apply grafana      --placement="1 node1"
ceph orch ls --service_type prometheus
# specs/prometheus.yaml — retention has to outlive the investigation
service_type: prometheus
placement:
  hosts: [node1]
spec:
  retention_time: "30d"
  retention_size: "50GB"

Fifteen days of retention loses the baseline for any incident whose question is whether this month looks like last month.

Alert on health checks, not on raw metrics

Health checkSeverityDelayWhy that delay
MON_DOWN with quorum lostcritical0the cluster is not writable
MON_DOWN, quorum heldwarning5 mina reboot takes about that long
OSD_DOWN, singlewarning10 minone OSD is inside the redundancy budget
OSD_HOST_DOWNcritical2 mina failure domain has left
PG_AVAILABILITYcritical1 minIO is blocked right now
PG_DEGRADEDwarning30 minexpected during any recovery
OSD_NEARFULLcritical0the warning arrives too late to be the first signal
POOL_NEARFULLwarning1 hprocurement has a lead time
SLOW_OPSwarning5 minbursts are normal, sustained is not
MON_CLOCK_SKEWwarning10 minit precedes quorum instability
RECENT_CRASHwarning0a crash is never expected
PG_NOT_DEEP_SCRUBBEDwarning1 daysilent corruption goes undetected
CRASH_ID=2026-08-18T02:11:04.128Z_9f2c
ceph health detail
ceph crash ls-new
ceph crash info ${CRASH_ID}

Health checks already encode Ceph’s own judgement about what is abnormal. Alerting on them gives you names that match the documentation and the mailing list, which matters at three in the morning.

Thresholds derived from time to fix

ceph osd dump | grep -E 'full_ratio'
# full_ratio 0.95  backfillfull_ratio 0.9  nearfull_ratio 0.85
ceph osd set-nearfull-ratio 0.82
ceph osd df | sort -rnk 17 | head -5
Growth 2% of capacity per week. Procurement, delivery, racking and
burn-in: 8 weeks. To have 8 weeks of runway you must be alerted at 16
percentage points below the point where you stop, so the capacity alert
fires around 70%, not at the 85% nearfull ratio.
ThresholdSet byNot set by
Capacity warningprocurement lead time and growth ratea round number
OSD down delayhow long a reboot takespatience
Slow ops windownormal burst durationalert fatigue
Scrub agethe recovery point you accept for silent corruptionthe default

Keeping the view when the cluster is gone

# scrape the cluster Prometheus from an external one
# - job_name: ceph-federate
#   honor_labels: true
#   metrics_path: /federate
#   params: { 'match[]': ['{job=~"ceph.*"}'] }
#   static_configs: [{ targets: ['node1:9095'] }]
curl -s http://node1:9095/federate --data-urlencode 'match[]={job=~"ceph.*"}' | head

Alertmanager notifications must leave by a path that does not traverse the cluster. A cluster-hosted Alertmanager on the host that just died sends nothing at all.

Quiz

Knowledge check · 4 questions

  1. Q1. Why should the capacity alert fire around 70% rather than at the default 0.85 nearfull ratio?

  2. Q2. A cluster reporting 80% average utilisation is safely below the 0.85 nearfull ratio.

  3. Q3. Review the alerting configuration on a cluster that has just had an unnoticed outage.

    A host was down for nine days before anyone noticed. Prometheus retains 15 days. Alertmanager runs on the same host as Prometheus, on node1. The only alert configured is on overall cluster health not being OK.

  4. Q4. Why alert on Ceph health check names rather than on raw Prometheus metrics?

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

Production discipline

Derive each threshold from how long the corresponding fix takes, and write that reasoning down next to the rule — a threshold with no stated basis gets relaxed the first time it is inconvenient. Put metrics retention and at least one Alertmanager receiver outside the cluster, because the outages worth alerting on are the ones that take the dashboard with them.

Cross-course references

  • Kubernetes: alert on the condition the controller reports, not on the metric you rebuilt from scratch
  • Linux: filesystem monitoring has the same lead-time arithmetic behind its thresholds