土法炼钢 · 系统与基础设施

【Rook / CSI】排障坐标系:Pending、MountFailed、feature 静默失败与升级卡住

文章导航

分类入口
storagekubernetes
标签入口
#rook#csi#troubleshooting#pvc#volumesnapshot#rbd-features#upgrade#v1.20.4

目录

「PVC 一直 Pending」与「Pod MountFailed」的根因很少落在同一层。前者多数在 Controller 路径(provisioner、Secret、pool);后者多数在 Node 路径(plugin 注册、map/mount、内核)。若一上来重启整个 rook-ceph 命名空间,因果链会被冲掉,还可能把可恢复的 mon 抖动放大成双故障。

本文是系列第 13 篇:按六轴映射症状,并把每一步钉到 API / sidecar / CSI / Rook / Ceph 五层。观测字段语义见第 12 篇;RADOS 深排障外链 ceph/16。不粘贴未执行的集群输出。

本文是「Rook / CSI:K8s 上的 Ceph 编排内核」系列第 13 篇(共 16 篇)。→ 系列目录

篇目 核心内容
第 12 篇 · 可观测 toolbox / 插件 / CSI metrics 口径
第 13 篇 · 排障坐标系 六轴归因与层映射
第 14 篇 · 对照替代路径 云 CSI / Longhorn / 裸 Ceph

版本锚定:Rook v1.20.4;Ceph-CSI v3.17.0;K8s v1.31–v1.36


一、先选轴,再动参数

轴一:PVC Pending              — 卷未 Bound
轴二:MountFailed / 附加失败   — Bound 后挂不上
轴三:RBD feature 静默失败     — 挂上但怪 / 部分 I/O 异常
轴四:VolumeSnapshot 未就绪    — snap ReadyToUse 长期 false
轴五:升级卡住                 — Operator/CSI/Ceph 滚动不收敛
轴六:mon endpoint / Secret 错配 — 认证或地址与真实集群不一致

每轴固定三列:症状 → 先查什么(按层)→ 不要先做什么。与 Ceph 排障SPDK 排障 同一纪律:一次否证一轴

flowchart TD
  symptom["Symptom"]
  symptom --> axis["Pick one axis"]
  axis --> a1["Pending"]
  axis --> a2["MountFailed"]
  axis --> a3["Feature silent fail"]
  axis --> a4["Snapshot not ready"]
  axis --> a5["Upgrade stuck"]
  axis --> a6["Mon/Secret mismatch"]
触发选轴的症状 先查(层顺序) 不要先做
PVC Pending;无 PV API Events → sidecar provisioner → CSI → Rook pool CR → Ceph lspools 重启全部 OSD;改 imageFeatures「碰运气」
Pod ContainerCreating/MountFailed;PVC 已 Bound VolumeAttachment → node registrar → CSI plugin → dmesg → Ceph slow ops 删 PVC「重建试试」;先扩 OSD
已挂载;应用 checksum/性能/特性相关异常;Events 干净 CSI map 选项 / 内核能力 → RBD image features(第 7 篇) 当网络问题狂抓包;当 Ceph 满盘
VolumeSnapshot readyToUse: false snapshot CRD/controller → snapshotter sidecar → CSI → Ceph snap 对象 只删 SnapshotClass 重装;忽略 CRD 版本
Operator/Driver 条件不 Ready;镜像拉取循环 Rook Operator 日志 → CSI Operator/Driver CR → Ceph 主版本闸门(第 11 篇) 跳主版本「一次升两级」
日志含 auth/connect mon 失败;其它 PVC 正常或全挂 Secret/CSI config 中 mon 列表与 key → 对照 toolbox 轮换所有 keyring;重建集群

默认入口顺序(可裁剪):kubectl describe pvc → 对应 provisioner/plugin 日志 →(数据面)toolbox ceph health detail

层坐标(全文复用)

典型对象 否证问题
API PVC、PV、VolumeAttachment、VolumeSnapshot* 控制器是否已写入失败原因?
Sidecar csi-provisioner、attacher、snapshotter、resizer 哪个 RPC 返回了非 OK?
CSI csi-rbdplugin / csi-cephfsplugin 驱动是否执行了 map/mount/subvolume 调用?
Rook Operator、CephCluster、CephBlockPool、Driver CR reconcile 是否创建了池/密钥/端点?
Ceph mon/osd/mds、image、subvolume RADOS 是否接受该操作?

二、轴一:PVC Pending

症状

核对路径(按层)

APIdescribe pvc 读 Events;确认 StorageClass 的 provisioner 与命名空间前缀一致(Rook 默认形如 rook-ceph.rbd.csi.ceph.com,非默认命名空间必须改前缀——见第 6 篇)。

Sidecarkubectl -n rook-ceph logs deploy/csi-rbdplugin-provisioner -c csi-provisioner(CephFS 则换 cephfs provisioner)。找 CreateVolume 的 gRPC 码:NotFound(池/FS 不存在)、Unauthenticated/PermissionDenied(进轴六)、Unavailable(mon/网络)、Aborted(并发同 ID 操作,文档提示常与集群/网络有关)。

CSI:同一 Pod 的 csi-rbdplugin / csi-cephfsplugin 容器日志——sidecar 只调度,真正讲 Ceph 方言的是驱动容器。

RookCephBlockPool / CephFilesystem 是否 Ready;Operator 是否报错创建池。

Ceph:toolbox 中 ceph osd lspoolsceph fs lsceph fs subvolumegroup ls;确认 StorageClass 里的 pool/fsName 与集群一致。CephFS 未显式配置时,CSI 默认 subvolumegroup 名为 csi

连通性:按 Rook CSI Common Issues,从 所有 provisioner 副本的驱动容器探测 mon :3300,期望协议应答含 ceph v2

不要先做:改应用副本数;在未确认池存在时删除 StorageClass;把 Pending 当成「集群要扩容」。


三、轴二:MountFailed / 附加失败

症状

三步挂载回顾(Rook 文档)

  1. 驱动注册:节点上 plugin DaemonSet 的 driver-registrar 向 kubelet 注册。
  2. VolumeAttachment:attacher sidecar 调 ControllerPublish。
  3. NodeStage / NodePublish:节点插件 map(RBD)或 mount(CephFS)并绑到 Pod 目录。

核对路径

APIkubectl get volumeattachment;确认 ATTACHER 驱动名与节点名。应用是否调度到没有 csi-rbdplugin/csi-cephfsplugin Pod 的节点?

Sidecardriver-registrar 日志中应出现 PluginRegistered:trueLost connection to unix:///csi/csi.sock 表示节点插件 socket 断了——优先重启该节点 plugin Pod,而不是全集群。

CSI:在应用所在节点的 plugin 容器内检查是否有卡住的 rbd map / mount / mkfs(Rook 文档的 stale operations 检查)。dmesg 看内核拒绝 map 的原因。

Rook/Ceph:集群 HEALTH_ERR、大量 slow ops、MDS 不可用(CephFS)都会让 Stage 超时。此时 PVC Bound 只说明控制面供给成功,数据面仍可拒绝挂载

不要先做--force 删业务 Pod 当第一手段(节点丢失场景除外,见第 15 篇 fencing);在未看 VolumeAttachment 前重建 PVC。


四、轴三:RBD feature 静默失败

这是 ceph/18 点名的编排摩擦之一:CSI 声明的 RBD image features 与节点 krbd/内核能力不一致时,往往不是干脆的 ProvisioningFailed,而是「挂上了但行为怪」。

症状

核对路径

CSI / 节点:该节点内核版本与 rbd 模块对 features 的支持;NodeStage 使用的 map 选项(第 7 篇)。对比能工作的节点与失败节点的内核与 CSI plugin 版本。

Cephrbd info 查看 image 实际 features 位;与 StorageClass 参数对照。

API:本轴 Events 常无信息——不能用「没有 FailedMount」否证本轴。

不要先做:当纯网络分区抓包;在未对齐 features 前开启 read affinity(Tentacle+/内核版本约束见官方 CSI 文档与第 7、11 篇)。

与轴二的分界:轴二是挂不上;轴三是挂上了但不满足 features 谈判假设。选错轴会在 Stage 日志里空转。


五、轴四:VolumeSnapshot 未就绪

症状

核对路径

API:确认集群已安装匹配的 snapshot CRDsnapshot-controller。Rook 文档写明:Rook 只部署 snapshotter sidecar,不捆绑 controller;发行版若未带,需自行安装。kubectl get crd | grep snapshot 应能看到三类 CRD。

Sidecarcsi-snapshotter 日志;Content 的 error 字段。

CSI / Ceph:RBD 卷级 snap 与 CephFS subvolume/目录级 snap 语义不同(第 9 篇)。「Content 已 ready」不等于「业务理解的整卷一致点」——尤其 CephFS 不要用 VolumeSnapshot 冒充任意目录 .snap

不要先做:混用不同 API 组版本的 SnapshotClass;在 CephFS 上假设与 RBD 相同的崩溃一致性叙事。


六、轴五:升级卡住

症状

核对路径

Rook:Operator 日志中的 reconcile 错误;是否违反「Ceph 一次一个主版本」闸门(第 11 篇)。v1.20 起 CSI 配置路径以 Ceph-CSI OperatorOperatorConfig/Driver 为准——仍改旧 ConfigMap 期望生效,属于本轴常见假动作。

Sidecar:provisioner/snapshotter 镜像 tag 与集群 CRD 是否匹配;snapshot 尤其敏感。

Cephceph versions;是否误用 Tentacle v20.2.0 + read affinity 等已知风险组合(以官方 Ceph Upgrades 为准,标 Tentacle+)。

不要先做:跳过中间主版本;同时改 CRUSH、开加密、开 fencing「顺便升级」。


七、轴六:mon endpoint / Secret 错配

症状

核对路径

API / Rook:StorageClass 注解的 csi.storage.k8s.io/*-secret-name 是否指向仍存在的 Secret;CSI 配置里的 mon endpoint 是否与当前 mon Service/IP 一致(mon failover 或 hostNetwork 切换后常见漂移)。

CSI:在 provisioner 驱动容器内用同一 key 与 -m 手工跑 rbd ls(Rook 文档 RBD Commands 节)——能复现则锁在凭据/端点,而非 sidecar bug。

Ceph:确认 CSI 用户 caps 仍包含所需 pool;被人手工改 caps 或重建集群后未轮换 Secret。

不要先做:轮换全部节点证书;删除 toolbox;把问题当成轴一的「池不存在」反复建池。


八、回收 ceph/18 的三条编排摩擦

Ceph 选型终章 只点名、未展开的三条,本坐标系落点如下:

ceph/18 摩擦 落轴 层要点
CSI RBD features ↔︎ 节点 krbd 能力不一致 轴三 常静默;需节点与 image features 对照
Rook 自动升级跳过 Ceph「一次一个主版本」 轴五 Rook 闸门 + 官方升级矩阵
CephFS 目录级 snap ↔︎ VolumeSnapshot 卷级语义 轴四 语义差,不是单纯「CRD 没装」

三条都不是 RADOS 内核 bug;用 Ceph 五轴(slow ops/peering/满盘…)硬套会误判。正确姿势:编排六轴定层 → 若落在 Ceph 层再进 ceph/16 五轴


九、串联案例(机制推演,非实录)

以下仅演示选轴顺序,不含伪造日志。

案例 A:新命名空间 PVC Pending。
轴一:Events 报 ProvisioningFailed → provisioner 日志 NotFound → toolbox lspools 无该 pool → Rook 侧 CephBlockPool 未 Ready。处理:修池 CR,不改 features。

案例 B:PVC Bound,仅某节点 MountFailed。
轴二:VolumeAttachment 指向该节点 → 节点无 rbd plugin Pod → 调度或 DaemonSet 容忍度问题。处理:修节点插件,不删 PVC。

案例 C:全节点 Running,仅新内核节点上应用校验失败。
轴三:对比 rbd info features 与新节点 krbd;旧节点正常。处理:对齐 StorageClass features 或内核,不先做 mon blocklist。

案例 D:升级 Rook 后新建快照失败,旧快照仍可删。
轴五/四:查 snapshot-controller 与 sidecar 版本相对 CRD;同时核对是否误走旧 CSI 配置路径。


十、六轴检查清单(可剪入 on-call)

  1. 用症状表选一轴,写进事故单。
  2. API → sidecar → CSI → Rook → Ceph 顺序否证,跳层须写理由。
  3. Pending 先 mon :3300 与 pool/fs,再谈 OSD。
  4. MountFailed 先确认 plugin 在调度节点上且 PluginRegistered:true
  5. 「怪」但 Running → 考虑轴三,不要被双绿指标安慰。
  6. Snapshot 先 CRD/controller,再 Ceph 语义。
  7. 升级不收敛 → 主版本闸门与 CSI Operator 路径。
  8. toolbox 正常但 CSI 失败 → 轴六凭据/端点。
  9. 确认 Ceph 层有病后再接 ceph/16
  10. 一次变更窗口只拧与当前轴相关的旋钮。

跨轴并发时的优先级

真实事故常同时点亮多轴:例如升级后(轴五)新建 PVC Pending(轴一),同时旧节点 MountFailed(轴二)。优先级建议:

  1. 先停变更面:若轴五未收敛,冻结继续升版本或改 CR,避免在移动靶上排障。
  2. 再保数据面:若 Ceph 已 HEALTH_ERR / 大量 inactive PG,先接 ceph/16,否则新建 PVC 会持续失败,制造噪声。
  3. 再清控制面:轴一/六(Secret、pool、endpoint)——这类修好后 Pending 队列往往自行消化。
  4. 最后清节点面:轴二/三按节点逐个处理,避免全集群重启 plugin。

把「重启 Operator」放在第一步,只适合已经用日志证明 reconcile 死锁且数据面健康的窄场景;否则它会重置你还没读完的因果链。


十一、谱系、争论与开放问题

谱系

编排排障坐标系是 CSI 规范状态机(Controller/Node RPC)与 K8s 外部 sidecar 模式的运维投影,再叠 Rook Operator 的声明式生命周期。它不替代 Weil 路线下的 PG/OSD 故障方言,而是回答「失败首先在哪一层被命名」。ceph/18 的三条摩擦是本坐标系的回归测试集

争论:先重启 plugin 还是先查 Ceph

A 侧:MountFailed 时重启节点 CSI Pod,成功率高、成本低。
B 侧:先 ceph health detail,避免在恢复风暴中重启放大连接抖动。
可检验裁决:若 VolumeAttachment 未创建且 registrar 未注册,判 A;若 Stage 日志已显示 Ceph 超时且 slow_requests 并存,判 B。禁止无日志「两个都重启」。

开放问题

  1. feature 错位能否在调度前失败:轴三今日依赖事后症状;调度器/准入是否能基于节点内核能力拒绝 Pod?仍开放(系列研究台账;入口第 7 篇与 CSI 能力上报讨论)。
  2. 轴六配置漂移的闭环检测:mon endpoint ConfigMap/Secret 与真实 mon map 的持续对账,能否变成 Rook 条件类型而非仅日志?需对照 Operator 条件设计演进。

参考资料

官方文档(A 级)

站内对照

上一篇:可观测 · 系列目录 · 下一篇:对照替代路径

读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。

2026-08-15 · storage / kubernetes

【Rook / CSI】编排全景:五轴坐标系与 16 篇路线

相对 ceph/ RADOS 内核与 storage/ 云块选型,钉清 Rook/CSI 编排层缺口;定义 CSI RPC、sidecar、Operator/CRD、数据面归属、升级闸门五条坐标系,给出 16 篇阅读路线与 PVC Bound 之后 I/O 仍走 krbd→PG→BlueStore 的边界。

2026-08-15 · storage / kubernetes

Rook / CSI:K8s 上的 Ceph 编排内核

补齐站内 Ceph RADOS 内核之上的编排层:CSI 规范与 sidecar、Rook Operator/CRD、Ceph-CSI Operator、RBD/CephFS 供给与挂载、VolumeSnapshot 语义差、升级闸门,以及排障与选型收束。

2026-08-15 · storage / kubernetes

【Rook / CSI】CSI 规范与 K8s 接线:Controller、Node 与 sidecar

拆解 CSI Identity/Controller/Node 服务与 CreateVolume、NodeStageVolume、NodePublishVolume;对照 K8s external-provisioner/attacher/resizer/snapshotter 与 node-driver-registrar;给出 PVC→PV→Pod 挂载调用链与 in-tree→CSI 谱系,并点名规范最小面与 CSI-Addons 争论。


By .