站内 Ceph / RADOS 存储内核 已把一次写讲到 Messenger → PG → BlueStore,并以 终章 明确停在编排层;存储工程 覆盖云块选型。中间仍缺一层:PVC 如何经 CSI sidecar 变成 RBD image / CephFS subvolume,features 与节点内核如何错位,VolumeSnapshot 与目录级快照差在哪,Rook v1.20 为何强制 Ceph-CSI Operator,以及升级如何一次一个主版本。
本文只做三件事:钉缺口、定义后续 15
篇共用的五条坐标系,并给出阅读路线。难点不在「会不会
kubectl apply」,而在控制面与数据面交界上的可核对字段——provisioner
名、CSI RPC
阶段、OperatorConfig/Driver
CR、dataDirHostPath、升级健康闸门。
本篇在系列中的位置
篇目 核心内容 第 1 篇 · 编排全景 缺口、五轴坐标系、16 篇路线 第 2 篇 · CSI 规范与 K8s 接线 Controller/Node、sidecar、PVC→RPC 系列目录 关键问题、阅读路径、全部价值点
版本锚定:Rook v1.20.4(
rook.io/docs/rook/v1.20/);Ceph-CSI v3.17.0;K8s v1.31–v1.36;Ceph 后端支持 Squid v19.2.x / Tentacle v20.2.1+(机制叙述默认对齐站内 Squid;Tentacle 特性须显式标注「Tentacle+」)。无真实 Rook 集群则不粘贴伪造kubectl/ceph -s输出。
一、相对站内已有内容,缺口在哪
下表列出各已有系列的视角,以及本系列补的格子。规则是:不重写已有内容,只填真正空着的格子。
| 已有内容 | 视角 | 本系列补什么 |
|---|---|---|
| ceph/ 01–18 | RADOS 内核:Map、PG、BlueStore、RBD/CephFS/RGW | 编排与 CSI 挂载生命周期;不重写 BlueStore |
| ceph/18 | 点名 Rook/CSI 摩擦,停损线 | 成系列展开状态机与失败模式 |
| storage/70 | 云块选型 | 对照叶;不写云厂商 API 教程 |
| containers/、k8s-network/ | 运行时 / 网络 | 边界外链;本系列焦点在存储 CSI |
结论:读者能读
ceph -s、理解 PG/BlueStore,但不知道 PVC
Pending 卡在 provisioner 还是 mon endpoint、挂载成功却因 RBD
feature 静默失败、快照 ready
却语义不是「整卷」、升级跳主版本为何炸。本系列补「K8s
存储编排内核」那一格。
与通识教程的差别也在这里:多数「在 K8s 上装 Rook」文章停在 StorageClass 与 PVC Bound;本系列追问 Bound 之后 I/O 仍是哪条数据面,以及 Pending / MountFailed / 快照 not ready 各自落在哪一层。深度来自可证伪的阶段划分,而不是更长的安装截图。
本系列刻意不写 cephadm 裸机安装全书、Dashboard 点击路径、未实测跨方案延迟排行。若目标只是「把 PVC 挂上」,官方 Quickstart 已够;若目标是「失败落在 sidecar 还是 Ceph、features 错位为何怪、升级闸门为何拒升」,则必须沿五轴下钻。
二、五条坐标系(后续章节回指)
后面每一篇都落到下面某一条轴上。本篇钉名字、关键锚点与失败表象;具体 RPC、CRD 与源码在对应篇展开。排障口诀:先点名轴,再下钻模块——不要一上来改 StorageClass 参数或重装 Operator。
CSI RPC 轴
定义:一次卷从供给到挂载,分别对应 CSI Controller 与 Node 服务上的哪些 RPC,以及每条 RPC 的幂等与失败语义。
| 可核对锚点 | 含义 |
|---|---|
CreateVolume /
DeleteVolume |
供给与回收;通常由 external-provisioner 触发 |
ControllerPublish /
ControllerUnpublish |
部分驱动的 attach 语义;与 K8s VolumeAttachment 耦合 |
NodeStageVolume /
NodePublishVolume |
节点级准备 vs Pod 级挂载;Stage 通常每节点一次,Publish 每 Pod 一次 |
| CSI Spec Identity / Controller / Node | 驱动必须实现的服务面;见 第 2 篇 |
PVC 长时间 Pending 且 Events 指向 provisioner,优先落本轴;「Pod 已调度但挂载失败」则更可能是 Node 侧 Stage/Publish。不要把两类现象都写成「Ceph 坏了」。
Sidecar 编排轴
定义:K8s 不直接实现全部 CSI 控制逻辑,而是用官方 sidecar 监视 API 对象并调用 CSI endpoint。
| 可核对锚点 | 含义 |
|---|---|
| external-provisioner | 监视 PVC → CreateVolume;创建 PV |
| external-attacher | 与 VolumeAttachment / ControllerPublish 相关 |
| external-resizer | PVC 扩容 → ControllerExpandVolume |
| external-snapshotter | VolumeSnapshot → CreateSnapshot |
| node-driver-registrar | 向 kubelet 注册 Node 插件 |
sidecar 版本与集群 CRD(尤其 VolumeSnapshot)错位时,常见表象是「PVC Bound 但快照 API 报错」或扩容卡住——落本轴,而不是先改 Ceph pool。细节见第 2、9、11 篇。
Operator / CRD 轴
定义:Rook Operator 如何把
CephCluster 等 CR 调和成 mon/mgr/osd Pod,以及
v1.20 起 Ceph-CSI Operator 如何拥有 CSI
配置。
| 可核对锚点 | 含义 |
|---|---|
CephCluster / CephBlockPool /
CephFilesystem /
CephObjectStore |
Rook 核心 CRD;见 第 3–4 篇 |
OperatorConfig /
Driver(csi.ceph.io) |
v1.20 配置 CSI 的唯一支持路径;见 第 5 篇 |
rook-ceph 默认命名空间 |
Operator、集群与 CSI 工作负载的常见共置命名空间 |
| Quickstart 顺序 | crds.yaml + common.yaml +
csi-operator.yaml,再
operator.yaml + cluster.yaml |
新装若漏 csi-operator.yaml 或 Helm 侧漏装
ceph-csi-drivers chart,CSI 控制面会缺
ServiceAccount / Driver CR——表现为 ctrlplugin 起不来,而不是
RADOS 健康问题。
数据面归属轴
定义:编排成功(PVC Bound、Pod Mounted)之后,I/O 仍走哪条路径;本系列不重写该路径内部。
| 路径 | 归属 |
|---|---|
| RBD 默认 | krbd(或驱动配置的 map 路径)→ RADOS 对象 → PG → BlueStore |
| CephFS | 内核客户端 / FUSE(可配置)→ MDS caps + 数据对象 → PG → BlueStore |
| 语义外链 | ceph/12 RBD、ceph/13 CephFS、ceph/07–09 BlueStore |
硬边界:kubectl get pvc
显示 Bound 不证明
延迟问题在编排层。挂载成功但 P99 怪,应先用 ceph/ 五轴(Map
/ 通信 / 一致性 / 本地存储 / 接入代价)归因,再回头查 CSI
features 与节点内核是否错位(第 7、13 篇)。
升级闸门轴
定义:Rook 版本、Ceph 镜像主版本、CSI CRD/sidecar、Driver 名前缀如何耦合;哪些检查会拒绝升级。
| 可核对锚点 | 含义 |
|---|---|
| Rook 官方升级路径 | 仅支持正式 release 之间的相邻主线升级(如 v1.19.x → v1.20.x) |
| Ceph「一次一个主版本」 | Squid → Tentacle 可;跳主版本不在支持面 |
HEALTH_ERR 拒升 |
Operator 在 HEALTH_ERR 时默认拒绝继续 Ceph
daemon 升级(可被显式绕过,风险自负) |
| v1.20 CSI 断裂 | CSI 设置迁出
rook-ceph-operator-config;新装必须走
OperatorConfig/Driver |
升级卡住时先落本轴:是健康闸门、镜像标签不齐、还是 CSI RBAC/Driver 名错位。展开见 第 11 篇(规划篇)。
三、坐标系背后的三个不变量
相对「云托管块把一切藏在黑盒」与「裸机 cephadm 手工装 daemon」,Rook+CSI 同时钉住三条不变量:
- 声明式意图在 CR / PVC,权威执行在 Operator +
CSI:人改的是
CephCluster与 StorageClass;实际 mon/osd/image 由 reconcile 与 RPC 产生。代价是必须能把现象映射回 CR 字段或 RPC 阶段。 - 控制面与数据面分离:PVC Bound 只保证供给契约达成;读写作延迟与一致性仍由 RADOS 不变量决定(见 ceph/ 三不变量:本地放置、PG 协商、Primary 序列化)。
- CSI 驱动名是跨对象契约:StorageClass
provisioner、VolumeSnapshotClassdriver、DriverCRmetadata.name必须一致;默认前缀通常是 Operator 命名空间(如rook-ceph.rbd.csi.ceph.com)。改前缀属于破坏性操作,官方警告仅适合全新部署。
排障时先问「哪条不变量被触碰」,再落到对应轴。例如:Events
里 provisioner 名对不上 → 不变量 3;Bound 后写超时且
ceph -s 显示 peering → 不变量 2(应转
ceph/);改了 ConfigMap 却不生效 → 在 v1.20 上可能是不变量 1
的所有权已迁到 CSI Operator(第 5 篇)。
四、设计谱系:CSI → Rook Operator → Ceph-CSI Operator
K8s in-tree volume plugins(驱动进 kube 树)
→ CSI Spec + K8s CSI GA(1.13,2019-01)
→ 外部 sidecar 编排模式(provisioner/attacher/…)
→ Rook Operator:CephCluster CR → daemon Pod
→ Rook 逐步外置 CSI 配置(约 v1.18 起自动生成 OperatorConfig/Driver)
→ Rook v1.20:Ceph-CSI Operator 为配置 CSI 的必选路径
→ 仍争:规范最小面 vs CSI-Addons;自建 Rook vs 云 CSI / Longhorn
- CSI 规范(container-storage-interface/spec)把存储插件从 kube 树拆出,定义 Identity / Controller / Node 三类 gRPC 服务;幂等与能力协商是后续所有驱动的共同假设。
- Kubernetes CSI GA(v1.13)(Kubernetes Blog, 2019-01-15)把 PVC/PV/StorageClass 接到外部 CSI 驱动,并用 sidecar 补齐「监视 API → 调 RPC」的缺口。
- Rook 把 Ceph 的安装与生命周期收成
Kubernetes Operator:人声明
CephCluster,Operator reconcile mon/mgr/osd 与设备发现。 - Rook v1.20.0 Breaking Changes(GitHub
Release)明确:Ceph-CSI Operator
required;CSI 设置从
rook-ceph-operator-config/rook-cephchart 移除;新装用OperatorConfig与DriverCR;Helm 用户需ceph-csi-driverschart。
| 维度 | 早期 / 过渡 | Rook v1.20.4 默认叙事 | 开放分叉 |
|---|---|---|---|
| CSI 配置入口 | rook-ceph-operator-config 键值 |
OperatorConfig + Driver |
多集群下谁拥有 Driver CR |
| 驱动部署 | Rook Operator 直接拉起 CSI | ceph-csi-operator + drivers chart / 清单 | SA/RBAC 漏装导致 ctrlplugin 起不来 |
| 后端 Ceph | 随镜像标签 | Squid / Tentacle(allowUnsupported
管更新主版本) |
Tentacle+ 特性与 Squid 运维手册混用 |
| 扩展能力 | 驱动内建 + 厂商私货 | CSI-Addons(可选 sidecar) | 规范最小面 vs 扩展面 |
五、开放争论(先立靶,后各章拆)
| 争论 | A 侧 | B 侧 | 本系列落点 |
|---|---|---|---|
| in-tree / Flex → CSI | 统一外置驱动,kube 树减负 | sidecar/CRD 版本耦合税 | 第 2、11 篇 |
| 规范最小面 vs CSI-Addons | 只做 Spec RPC,行为可移植 | 复制、fencing 等需要扩展 API | 第 2、5、15 篇 |
| 自建 Rook+Ceph vs 云 CSI / Longhorn | 可控 CRUSH/PG、统一 RADOS | 运维编制与归因成本 | 第 14–16 篇 |
| Operator 拥有 CSI vs 独立 CSI Operator | 单一入口好装 | 配置所有权清晰、升级面拆分 | 第 5、11 篇 |
不在第 1 篇宣布胜负;每组争论要求后续篇给出可核对机制或选型边界,而不是「看业务场景」空话。
对「自建 vs
托管」额外钉一句:本系列不比较报价,只比较失败模式是否可归因到五轴中的某一层。若托管块把供给与挂载藏在黑盒里,工程师就失去了
CSI RPC 阶段与 Driver CR
这类抓手——这是架构选择,不是性能排名。
六、16 篇路线与阅读建议
flowchart TD
overview["01 Overview"] --> csi["02 CSI Spec"]
csi --> rook["03 Rook Operator"]
rook --> cluster["04 CephCluster Life"]
cluster --> csiop["05 CSI Operator"]
csiop --> rbd["06 RBD Provision"]
rbd --> mount["07 Mount Features"]
csiop --> cephfs["08 CephFS CSI"]
rbd --> snap["09 Snapshot Clone"]
cephfs --> snap
cluster --> obj["10 Object NFS"]
csiop --> upgrade["11 Upgrade Gates"]
mount --> obs["12 Observability"]
snap --> obs
obs --> trouble["13 Troubleshoot"]
trouble --> vs["14 vs Alternatives"]
vs --> secure["15 Tenancy Security"]
secure --> select["16 Selection"]
overview --> select
| 路径 | 篇目 | 适合 |
|---|---|---|
| 必读核心 | 1 → 2 → 5 → 6 → 7 → 9 → 13 | 快速建立坐标系 |
| 控制面 | 3 → 4 → 5 → 11 | Operator / 升级 |
| 文件系统 | 8 → 9 → 15 | CephFS / 快照 / 安全 |
| 对照选型 | 1 → 14 → 16 | 路径选型 |
| 完整通读 | 1 → … → 16 | 系统掌握 |
先修:熟悉 PVC/StorageClass;强烈建议 ceph/ 至少 01、12、13;可选 storage/70。
阅读时建议随身带一张「轴 → 锚点」卡片:PVC Pending 先问 provisioner/RPC;MountFailed 先问 Stage/Publish;改配置不生效先问 v1.20 所有权;Bound 后延迟怪先问数据面归属(转 ceph/)。把现象翻译成轴,比翻译成「重装试试」更接近本系列目标。
五个关键问题到第 1 篇结尾仍然够用:后续每一篇应能把问题收束到某一轴上的可核对锚点。若一篇写完仍只能回答「看场景」,说明证据或机制还不够,应按 WRITING_GUIDE 停写或缩范围——本系列对性能排名与云厂商报价正是如此处理的。
七、PVC Bound 之后:I/O 仍在 RADOS
Quickstart 验证健康时,官方要求 toolbox 里看 mon
quorum、mgr active、OSD
up/in,并期望
HEALTH_OK(见 Rook v1.20
Quickstart)。那是集群就绪判据,不是应用
I/O 路径的终点。
应用写入已挂载的 RBD 卷时,控制面已经退场:kubelet 与 CSI Node 插件完成的是 map/mount;之后字节流进入内核 krbd(或驱动选择的用户态路径),再进入 RADOS 客户端写路径 → PG → BlueStore。CephFS 同理,只是元数据税落在 MDS。
因此本系列与 ceph/ 的读法是:
| 问题形态 | 先读 |
|---|---|
| PVC Pending / MountFailed / 快照 not ready / CSI 配置不生效 | 本系列 |
| 写卡在 epoch / peering / deferred / MDS caps | ceph/ |
| 「挂上但怪」且怀疑 features ↔︎ 内核 | 本系列第 7、13 篇 + ceph/12 |
无真实集群时只保留机制与失败模式,不写延迟数字,也不粘贴伪造的
Events 或 ceph status。
同一停顿表象可能对应多轴:例如 PVC Pending 既可能是
provisioner 名错误(Sidecar / RPC),也可能是 mon endpoint
Secret 未就绪(Operator / CRD),还可能是池不存在(已进入
Ceph,但仍由 CreateVolume
返回)。本系列给的是优先假设顺序,不是唯一诊断。后续篇会把每条优先假设落成对象字段、RPC
名与可检验问题。
把「编排税」说清楚,是为了和 ceph/ 的「RADOS 税」对齐:前者付的是 sidecar 版本、CR 所有权、驱动名契约;后者付的是 epoch、peering、BlueStore 与接入切分。两套税可以叠在同一故障里,但复盘时必须先拆开,否则会在错误的层调参。
八、小结
- 定位:补 ceph/ 之上的 K8s 编排与 CSI 挂载层,不重写 RADOS/BlueStore。
- 五轴:CSI RPC / Sidecar / Operator·CRD / 数据面归属 / 升级闸门;每轴有可核对锚点。
- 三不变量:声明式意图、控制面与数据面分离、驱动名契约。
- 谱系:CSI Spec + K8s 1.13 GA → Rook Operator → v1.20 强制 Ceph-CSI Operator。
- 路线:核心「1→2→5→6→7→9→13」;选型「1→14→16」。
下一篇进入 CSI RPC 轴:没有 CreateVolume / NodeStage / NodePublish 的阶段语言,后面的 Pending 与 MountFailed 都无处锚定。
九、参考资料
规范 / 官方文档(A)
- Rook v1.20 Quickstart —
rook.io/docs/rook/v1.20/Getting-Started/quickstart/(K8s v1.31–v1.36;csi-operator.yaml安装顺序)。 - Rook v1.20 CSI Configuration —
rook.io/docs/rook/v1.20/Storage-Configuration/Ceph-CSI/csi-configuration/(OperatorConfig/Driver;rook-ceph-operator-config不再应用 CSI 设置)。 - Rook v1.20.0 Release Notes — Breaking Changes:Ceph-CSI Operator required。
- Container Storage Interface Spec —
github.com/container-storage-interface/spec。 - Kubernetes Blog: Container Storage Interface (CSI) for Kubernetes GA(2019-01-15;CSI GA in v1.13)。
站内对照
实验台账
- 本篇无命令输出;不写 IOPS / 延迟数字。
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
Rook / CSI:K8s 上的 Ceph 编排内核
补齐站内 Ceph RADOS 内核之上的编排层:CSI 规范与 sidecar、Rook Operator/CRD、Ceph-CSI Operator、RBD/CephFS 供给与挂载、VolumeSnapshot 语义差、升级闸门,以及排障与选型收束。
【Rook / CSI】排障坐标系:Pending、MountFailed、feature 静默失败与升级卡住
按六轴映射 Rook/CSI 常见故障:PVC Pending、MountFailed、RBD feature 静默失败、VolumeSnapshot 未就绪、升级卡住、mon endpoint/Secret 错配;每轴绑定 API/sidecar/CSI/Rook/Ceph 层,并回收 ceph/18 三条编排摩擦。
【Rook / CSI】Rook Operator 与 CRD:CephCluster 所有权边界
把 Rook 写成 Kubernetes Operator:钉 CephCluster、CephBlockPool、CephFilesystem、CephObjectStore 等核心 CRD 的职责;划清 reconcile 所有权与 rook-ceph 默认命名空间;明确 Rook 不重写 RADOS 内核,并讨论 Operator 边界与 Driver CR 所有权争论。
【Rook / CSI】RBD 供给路径:StorageClass 到 CreateVolume 到 image
拆解 Rook 默认 RBD CSI 如何把 StorageClass 参数与 Secret 转成 CreateVolume,再落到 Format 2 image;钉死 provisioner 命名前缀、池与 imageFeatures 边界,并外链 ceph/12 的对象命名——不重写 BlueStore。