PVC Pending 与「集群不健康」的观测入口不同。前者可能卡在
external-provisioner 的 gRPC、mon endpoint Secret、或节点上
krbd map;后者可能是 PG degraded、OSD nearfull、或 CSI
插件本身已挂。若先盯 Grafana 里一条
ceph_cluster_total_used_bytes,往往会错过
sidecar 直方图里已经飙高的 CreateVolume
失败码。
本文是系列第 12 篇,目标是:先选观测层,再读字段语义与失败模式;不虚构 Prometheus scrape 样本,不把文档示例输出当本机实测。
本文是「Rook / CSI:K8s 上的 Ceph 编排内核」系列第 12 篇(共 16 篇)。→ 系列目录
篇目 核心内容 第 11 篇 · 升级闸门 Rook/Ceph 主版本纪律;CSI CRD/sidecar 错位 第 12 篇 · 可观测 toolbox / 插件 / CSI metrics / Exporter 口径 第 13 篇 · 排障坐标系 Pending、MountFailed、feature 静默失败
版本锚定:Rook v1.20.4(
rook.io/docs/rook/v1.20/);Ceph-CSI v3.17.0;K8s v1.31–v1.36。RADOS 字段语义默认对齐站内 Ceph 可观测(Squid);Tentacle 特性须显式标注。
一、先选观测层,再动命令
编排层比裸 Ceph 多两层:K8s API 对象与 CSI sidecar。读信号时固定这个栈:
K8s API 层: PVC/PV/VolumeAttachment/VolumeSnapshot 状态与 Events
Sidecar 层: csi-provisioner / snapshotter / attacher / resizer 日志与直方图
CSI 驱动层: csi-rbdplugin / csi-cephfsplugin;liveness-prometheus
Rook 控制面: Operator reconcile、CephCluster/Driver CR 条件
Ceph 数据面: toolbox / kubectl rook-ceph → ceph -s、pg、osd perf
Metrics: mgr Prometheus module;ceph-exporter;CSI ServiceMonitor
| 层 | 刷新语义 | 适合回答 | 不适合单独回答 |
|---|---|---|---|
| PVC Events | 近实时,但文案被控制器截断 | 「谁先拒绝了 Bound」 | 磁盘是否饱和 |
| Sidecar 直方图 | 取决于 scrape 间隔(常见 5–30s) | CreateVolume / Snapshot 失败码分布 | PG peering 细节 |
| CSI liveness | 探针周期级 | 插件进程是否还活着 | 业务 I/O P99 |
ceph -s |
MON 聚合,约数秒 | 集群健康摘要 | CSI Secret 是否错配 |
| mgr Prometheus | 默认十余秒级聚合 | 容量/健康趋势 | 亚秒 RocksDB stall |
| ceph-exporter | 更高频 daemon perf | OSD 内部 counter 趋势 | PVC 供给失败原因 |
纪律:同一事故窗口里,先用 API/Events 定「卡在哪一层」,再用 Ceph 字段定「数据面是否病了」。两层同时绿、业务仍挂,才下钻 NodeStage 与 features(第 7、13 篇)。
flowchart TD
symptom["Symptom: Pending / MountFailed / Slow IO"]
symptom --> pick["Pick observation layer"]
pick --> api["K8s API + Events"]
pick --> side["Sidecar logs + histograms"]
pick --> live["CSI liveness gauge"]
pick --> rad["toolbox / rook-ceph plugin"]
pick --> prom["mgr Prometheus / exporter"]
二、Toolbox:进入 Ceph 方言的标准入口
Rook 把 ceph CLI 放进 toolbox
Deployment(命名空间通常为 rook-ceph)。它不是
Dashboard 替代品,而是把站内 Ceph 系列的字段语义接到
K8s 值班手册的通道。
常用入口(命令语义;输出须在真实集群执行):
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
ceph -s
ceph health detail
ceph osd df tree
ceph pg dump_stuck| 命令族 | 语义 | 常见误读 |
|---|---|---|
ceph -s / health detail |
MON 聚合健康;WARN≠不可写 | 「WARN 就必须立刻停业务」——多数 nearfull/slow_request 仍可写 |
osd df tree |
单 OSD USE% | 只看 ceph df 集群均值漏掉倾斜满盘 |
pg dump_stuck |
卡在 unclean/inactive/stale 的 PG | 与 PVC Pending 无一一对应——需再查 image/subvolume 所在 pool |
osd perf |
commit/apply 均值 | 当成应用端到端延迟 |
字段细则见 Ceph 第 15 篇。本篇只钉一条边界:toolbox 回答 RADOS 是否健康;不回答 StorageClass 参数是否写错。
从 CSI 容器测 mon 连通性
Rook CSI 排障文档要求:供给失败时,在 provisioner 的
csi-rbdplugin / csi-cephfsplugin
容器内探测 mon 的 v2 端口(默认
3300)。看到 ceph v2 字样表示 TCP
握手到了 Ceph 协议;无响应则优先查网络策略 / hostNetwork /
mon Service,而不是先改 StorageClass 的
imageFeatures。
三、kubectl rook-ceph 插件(已文档化)
Rook v1.20 文档专章 kubectl
Plugin 说明:经 Krew 安装 rook-ceph
插件后,可在不 exec toolbox 的情况下跑 ceph
子命令,并辅助 Operator 重启、OSD purge、mon/OSD debug
模式。
安装与典型用法(以官方文档为准):
kubectl krew install rook-ceph
kubectl rook-ceph ceph status
kubectl rook-ceph debug start rook-ceph-mon-b
kubectl rook-ceph debug stop rook-ceph-mon-b| 能力 | 用途 | 边界 |
|---|---|---|
kubectl rook-ceph ceph … |
与 toolbox 同方言,适合脚本化值班 | 仍依赖集群 RBAC 与 mon 可达 |
| health 类子命令 | 快速看 Rook Pod / Ceph 健康摘要 | 摘要不等于 PVC Events |
| debug start/stop | 停 daemon、挂调试 Pod,跑
ceph-objectstore-tool 等 |
维护操作;与业务 I/O 观测层分离 |
| restart operator / purge OSD | 控制面急救 | 误用会扩大 blast radius——先读 Operator 日志定因 |
工程判断:插件缩短「进
toolbox」的摩擦,但不改变观测栈分层。把它当「能跑
ceph 的 kubectl」,不要当「能解释 MountFailed
的万能入口」。
四、CSI liveness sidecar:活着 ≠ 供给成功
Rook 文档(Ceph CSI Drivers / Prometheus
Monitoring)写明:CSI Pod 可带
liveness-prometheus
sidecar,暴露探针类指标;默认关闭,需在
Operator
配置里启用(Helm:csi.enableLiveness;或
operator 环境变量
CSI_ENABLE_LIVENESS=true)。集成 scrape
时再部署 csi-metrics-service-monitor.yaml 一类
ServiceMonitor。
指标语义(不粘贴 scrape 样本)
| Metric / 信号 | 类型语义 | 1 / OK 含义 |
0 / 异常含义 |
失败模式 |
|---|---|---|---|---|
csi_liveness |
gauge | 对 CSI 端点的 liveness 探针成功 | 探针失败或驱动无响应 | 进程僵死、socket 丢失、容器 OOM 后未就绪 |
| 探针延迟(若暴露) | 观测「多久才答」 | 稳定低延迟 | 延迟爬升常先于 gauge 翻 0 | 节点 CPU 饿死、gRPC 线程堵死 |
误读:csi_liveness==1
只说明「插件还能被探针打到」,不保证
CreateVolume 成功、也不保证 NodePublish 能 map
设备。供给失败时 sidecar 直方图与 Events 优先;liveness 绿而
PVC Pending,说明问题在
Ceph/配置/网络,不在「驱动死了」。
与 gRPC / sidecar 直方图的分工
Kubernetes CSI
sidecar(provisioner、attacher、resizer、snapshotter)经
csi-lib-utils 暴露直方图族,名称以官方 sidecar
为准,常见为:
| Metric | 标签(语义) | 读法 |
|---|---|---|
csi_sidecar_operations_seconds |
driver_name、method_name、grpc_status_code |
按 RPC 方法看耗时分布与非 OK 码占比 |
关键 method_name
与编排动作的对应(规范路径,非完整枚举):
| method_name(示意) | 对应 K8s 动作 | 失败时优先查 |
|---|---|---|
/csi.v1.Controller/CreateVolume |
PVC→PV 供给 | pool/fs 是否存在、Secret、mon 连通 |
/csi.v1.Controller/DeleteVolume |
PVC 删除回收 | image 仍被 map、trash、权限 |
/csi.v1.Controller/CreateSnapshot |
VolumeSnapshotContent | snapshot CRD/controller 版本、驱动能力 |
/csi.v1.Controller/ControllerExpandVolume |
PVC 扩容 | allowVolumeExpansion、expand Secret |
/csi.v1.Node/NodeStageVolume |
节点预挂载 | plugin DaemonSet、设备、krbd |
/csi.v1.Node/NodePublishVolume |
挂到 Pod 目录 | SELinux、挂载选项、目标路径 |
Ceph-CSI 历史上自带过驱动内 gRPC
metrics,社区方向是改以 sidecar
暴露为准(见 ceph-csi 对 sidecar metrics
的跟进)。运维上以当前镜像实际 /metrics
暴露名为准,正文不虚构序列值。
告警建议(语义级,非抄录阈值):
csi_liveness == 0持续超过探针探针窗口 → 驱动层事故,先看对应节点 plugin Pod。CreateVolume上非OK的grpc_status_code比率升高 → 供给轴(第 13 篇轴一),不要先调 OSD 线程。- 仅有延迟桶右移、码仍为 OK → 可能是 Ceph slow ops 或网络
RTT,转 toolbox/
osd perf。
五、mgr Prometheus 与 ceph-exporter:两套口径
Rook v1.20 监控文档明确区分:
| 来源 | 暴露什么 | 典型用途 |
|---|---|---|
| mgr Prometheus module | 除 daemon 细粒度 perf counter 以外的集群指标 | ceph_health_status、PG/OSD up/in、pool
吞吐、容量 |
| ceph-exporter | Ceph daemon performance counters | 更接近 perf dump 的长期序列 |
部署路径(官方 examples,版本钉
v1.20.4):deploy/examples/monitoring/ 下的
service-monitor.yaml、exporter-service-monitor.yaml、prometheus.yaml
等。Helm 侧 monitoring.enabled /
createPrometheusRules 控制 RBAC
与规则生成——前提是集群已有 Prometheus Operator
或兼容发现机制。
与编排故障相关的 metric 家族(语义)
| Metric 家族 | 语义 | 编排侧用法 |
|---|---|---|
ceph_health_status |
0=OK,1=WARN,2=ERR | ERR 时供给/挂载失败概率升;仍需
health detail 分型 |
ceph_osd_up / ceph_osd_in |
进程与权重 | down+in 预示 recovery 风暴,可能拖慢
CreateVolume |
ceph_pg_degraded /
recovering |
PG 降级/恢复 | 解释「供给成功但 I/O 慢」 |
ceph_osd_commit_latency_ms |
OSD 提交延迟 gauge | 对照 sidecar CreateVolume 延迟;口径是 OSD 层,非 PVC 端到端 |
ceph_cluster_total_*_bytes |
集群容量 | 容量规划;满盘轴见 Ceph 第 16 篇 |
RBD per-image
IO:CephBlockPool 的
enableRBDStats: true
才会打开镜像级统计;默认关。打开后增加
mgr/导出负荷,适合定点排障,不适合「默认全开当业务账单」。
Dashboard 接
Prometheus:CephCluster.spec.dashboard.prometheusEndpoint
只影响 Dashboard 拉图,不替代
ServiceMonitor。官方警告:不要把 Prometheus 存到同一
Ceph 集群——集群挂时告警面一起瞎。
六、把 PVC 状态接到观测层
| PVC / 快照现象 | 先看哪一层 | 再看哪一层 |
|---|---|---|
| Pending 久 | Events + csi-provisioner 日志 /
CreateVolume 直方图 |
toolbox:lspools / fs ls、mon
连通 |
| Bound 但 Pod MountFailed | VolumeAttachment + node plugin 日志 / NodeStage 直方图 | dmesg、krbd features、节点 plugin
是否在该节点 |
| VolumeSnapshot 不 ready | snapshot-controller + csi-snapshotter |
CRD 版本是否匹配;Ceph 侧 snap 是否创建 |
| 业务慢、PVC 已挂 | 应用延迟 | osd perf / exporter;勿只看
csi_liveness |
Events 文案常被截断成
failed to provision volume with StorageClass …。真正的
gRPC Aborted / Unavailable /
InvalidArgument 在 provisioner
或驱动容器日志里——Events
是索引,不是根因库。
七、观测口径的常见误判
csi_liveness=1≠ 供给健康:见第四节。
- mgr 绿 ≠ CSI 绿:mgr 不懂 StorageClass
Secret;CSI 失败时 Ceph 可以完全
HEALTH_OK。
ceph_cluster_total_used_bytes低 ≠ 无 nearfull:阈值按单 OSD;用osd df tree/ 对应 per-OSD 指标。
- sidecar 直方图 OK 码占比高 ≠ P99
可接受:OK 只说明 RPC 返回成功;慢在 Ceph 时码仍是
OK、桶右移。
- ServiceMonitor 已创建 ≠ 正在
scrape:Prometheus 实例必须选中对应
label/namespace;Rook 文档对此有专门注意。
- 插件
ceph status与 toolbox 不一致:查的不是同一命名空间 / 同一CephCluster,或 RBAC 指到了别的 context。
- 打开 RBD image stats
后「容量指标变了」:那是新增序列,不是集群突然多用了一倍盘。
- Dashboard 能画图 ≠
告警会响:
prometheusEndpoint只服务 Dashboard 拉数;Pager 仍依赖 Prometheus 规则与路由是否落地。
八、接到排障轴
第 13 篇六轴的入口可压缩成:
| 轴 | 先看的观测 |
|---|---|
| PVC Pending | Events → CreateVolume 直方图/日志 → mon 连通 / pool |
| MountFailed | VolumeAttachment → NodeStage 日志 → dmesg / plugin 注册 |
| feature 静默失败 | 应用症状 + 节点内核/map 选项;指标常「全绿」 |
| Snapshot not ready | snapshot CRD/controller → snapshotter 直方图 |
| 升级卡住 | Operator/Driver CR 条件 + sidecar 镜像版本;非单看
ceph -s |
| mon/Secret 错配 | provisioner 认证错误日志;toolbox 用同一 keyring 复现 |
无真实 Rook 集群时,只保留上述语义;不要把文档示例里的
HEALTH_OK
截图粘进事故报告冒充本环境。排障结论必须能回指到本集群的
Event、sidecar 日志或 toolbox
输出;引用官方截图只能说明字段长什么样,不能代替本环境证据。
值班最小仪表盘(语义清单)
不必一次接满 Grafana 市场里的所有 Ceph 看板。编排值班至少要能同时看到三类信号,且知道它们不可互相替代:
- 租户面:PVC/
VolumeSnapshot非 Bound/ready 计数,按 StorageClass 分组——回答「谁在疼」。
- CSI 面:
csi_liveness与 CreateVolume/NodeStage 非 OK 比率——回答「疼在插件还是更下层」。
- RADOS
面:
ceph_health_status、nearfull 相关序列、commit latency——回答「疼在磁盘/恢复/满盘」。
缺第 1 类会把存储告警当成噪音;缺第 2 类会在
HEALTH_OK 时对 Pending 束手;缺第 3 类会在
sidecar
全绿时对业务超时误判为「应用问题」。三类齐备仍可能漏掉轴三静默失败——那一轴本来就不以指标翻转开场,必须靠
features 门禁与抽样对比节点。
日志与指标的时间对齐
sidecar 直方图的 scrape 时间戳、kubelet Event 的
lastTimestamp、OSD log
的本地时钟,三者经常差数秒到数十秒。排障时先选定一个事故窗口(例如
PVC
创建时刻前后五分钟),再在该窗口内对齐,而不是拿「此刻」的
ceph -s 否证「十分钟前」的 CreateVolume
失败。时钟 skew 本身会进 Ceph HEALTH_WARN;若
mon 已报 skew,指标对齐要更保守。
九、谱系、争论与开放问题
谱系
CSI 可观测面来自三条线的叠合:(1)SIG Storage 把 in-tree
插件拆成 CSI gRPC + 外部 sidecar
后,失败首先表现为 RPC 状态码与 sidecar 日志;(2)Ceph
自身的 MON 聚合 + OSD perf_counters(Weil et
al. OSDI 2006 / PDSW 2007 的自治 OSD 叙事);(3)Rook
把后两者编进 K8s ServiceMonitor / toolbox / kubectl
插件。本篇不发明新指标,只把哪条线回答哪类问题钉死。
争论:编排 SLO 看 sidecar 还是看 mgr
A 侧:平台团队以 PVC 供给成功率与
csi_sidecar_operations_seconds 非 OK 比率做
SLO——贴近租户体验。
B 侧:存储团队以
ceph_health_status / commit latency 做
SLO——贴近介质与恢复。
双方都对,但违约时的 runbook 不同:A
违约先查 Secret/网络/CRD;B 违约先查 OSD/PG。把 B 的绿写成 A
的达标,是多租户平台最常见的假关闭。
开放问题
- liveness 探针窗口与 gRPC
线程饿死是否同相:短于 scrape
间隔的驱动卡死,能否稳定翻掉
csi_liveness?可检验:在实验集群对 plugin 注入可控阻塞,对比 gauge 翻转与 CreateVolume 失败谁先出现。
- sidecar 直方图与 Ceph slow ops 的因果可观测性:在仅有 OK 码、延迟桶右移时,能否自动归因到特定 OSD,而无需人工对齐时间窗?入口:exporter-exporter 高频序列 vs sidecar scrape 对齐实验。
参考资料
官方文档(A 级)
- Rook v1.20 — Prometheus Monitoring(mgr vs exporter、CSI liveness、RBD stats)
- Rook v1.20 — kubectl Plugin
- Rook v1.20 — CSI Common Issues
- Rook v1.20 — Ceph CSI Drivers(liveness sidecar 说明)
- kubernetes CSI — csi-lib-utils
metrics(
csi_sidecar_operations_seconds) - Ceph Squid — mgr Prometheus
站内对照
- Ceph
可观测(ceph/15) —
ceph -s/ PG / OSD perf 字段语义 - Ceph 排障(ceph/16) — 五轴与 slow ops
- 本系列第 13 篇 — 编排侧排障坐标系
论文谱系
- Weil, S. A. et al. (2006). Ceph: A Scalable, High-Performance Distributed File System. OSDI ’06
- Weil, S. A. et al. (2007). RADOS. PDSW ’07
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Rook / CSI】编排全景:五轴坐标系与 16 篇路线
相对 ceph/ RADOS 内核与 storage/ 云块选型,钉清 Rook/CSI 编排层缺口;定义 CSI RPC、sidecar、Operator/CRD、数据面归属、升级闸门五条坐标系,给出 16 篇阅读路线与 PVC Bound 之后 I/O 仍走 krbd→PG→BlueStore 的边界。
【Rook / CSI】RBD 供给路径:StorageClass 到 CreateVolume 到 image
拆解 Rook 默认 RBD CSI 如何把 StorageClass 参数与 Secret 转成 CreateVolume,再落到 Format 2 image;钉死 provisioner 命名前缀、池与 imageFeatures 边界,并外链 ceph/12 的对象命名——不重写 BlueStore。
【Rook / CSI】挂载与 features:NodeStage、krbd 错位与 read affinity
拆解 RBD 的 NodeStageVolume/NodePublishVolume、map 路径与 imageFeatures 对 krbd 的依赖;说明失败为何常表现为挂上但怪;钉死 csi.readAffinity 与 Tentacle v20.2.0 损坏警告,并简述 network fencing。
【Rook / CSI】CephFS CSI:subvolume、RWX 与编排侧 MDS 税
拆解 Rook 上 CephFS CSI 如何用 subvolume 兑现 ReadWriteMany;钉死 provisioner 命名、StorageClass 与配额边界,并说明编排侧为 MDS/caps 付出的税——外链 ceph/13,不重写 journal 内核。