kubectl create -f cluster.yaml
之后,期望看到的是 mon quorum、mgr active、OSD
up/in,而不是「有个叫 Rook 的
Deployment 在跑」。中间隔着设备发现、hostPath
持久化、健康闸门与 Operator
的滚动决策。搞不清这些阶段,就会把「没有 raw
device」误诊成「Operator 坏了」,或在
HEALTH_ERR 时强行改镜像酿成更糟状态。
本文沿 CephCluster CR → daemon Pod → 健康验证 →
升级闸门 走一趟。不粘贴伪造
ceph status;命令只写语义与失败模式。RADOS
内部状态机仍外链 ceph/。
本篇在系列中的位置
篇目 核心内容 第 3 篇 · Rook Operator 与 CRD CRD 地图与所有权边界 第 4 篇 · CephCluster 生命周期 mon/mgr/osd、设备发现、健康闸门 第 5 篇 · Ceph-CSI Operator v1.20 OperatorConfig/Driver
版本锚定:Rook v1.20.4;Ceph 后端 Squid v19.2.x / Tentacle v20.2.1+(
cephVersion.image钉具体标签;机制默认对齐 Squid)。K8s v1.31–v1.36。
一、生命周期总览
flowchart TD
apply["apply_CephCluster"] --> op["rook_ceph_operator_reconcile"]
op --> mon["deploy_mons"]
mon --> quorum["mon_quorum"]
quorum --> mgr["deploy_mgrs"]
mgr --> discover["osd_prepare_discover"]
discover --> osd["deploy_osd_pods"]
osd --> health["HEALTH_OK_gate"]
health --> ready["cluster_usable_for_CSI"]
直觉顺序(细节随模式变化):
- Operator 接受
CephCluster,准备集群命名空间内的配置与密钥材料。 - 拉起 mon(数量由
spec.mon.count等决定;生产常见 3)。 - mon 形成 quorum 后,mgr 进入可用状态(默认常见 2 个 mgr,带 active/standby 标签语义)。
- 按
spec.storage做设备发现 / PVC 供给,跑 osd-prepare,再起 OSD Pod。 - 用 toolbox(或等价管理客户端)确认
HEALTH_OK与基础服务状态。 - 此后块/文件/对象 CR 与 CSI 才能在「有真实后端」的前提下工作。
Quickstart 写明:若 mon/mgr/osd Pod 未出现,应查 common issues,而不是继续堆 StorageClass。CSI ctrl/node plugin 可能在集群创建流程中出现,但不能用「CSI Pod Running」替代「Ceph 健康」。
时间线上还有一个易忽略的并行面:Operator 自身必须先
Ready。若 rook-ceph-operator 镜像拉不下来、RBAC
不足或卡在崩溃循环,后面的 mon 根本不会被创建。排障顺序应是
Operator → CephCluster reconcile 事件 → mon/mgr/osd
Pod → toolbox 健康,而不是从应用命名空间的 PVC
倒推到格式化磁盘。
对于 cluster-test.yaml
一类单节点/允许同节点多 mon
的测试清单:它能缩短实验周期,但会把故障域与生产叙事一起折叠。得出的「安装成功」经验不能直接外推到三节点生产
cluster.yaml。本系列默认读者最终要上生产拓扑;测试清单只作机制验证,不作容量或可用性结论。
二、从 CR 到 mon / mgr
2.1 mon
spec.mon.count 允许 1–9;文档推荐多数场景为
3,并强调奇偶与 quorum 数学:多数 mon
必须存活。allowMultiplePerNode: true
仅适合测试——生产把多个 mon 堆同一节点会削弱故障域。
持久化有两条常见路径:
- hostPath(依赖
dataDirHostPath):配置与 mon 数据落在宿主机路径,重启后仍在。 - volumeClaimTemplate:为 mon 建
PVC;文档要求关联 StorageClass 使用
volumeBindingMode: WaitForFirstConsumer等约束。
mon 还支持 zones / stretchCluster 等拓扑表达(三区 stretch、arbiter 等)。那些是故障域设计,不是「把 count 改成 5 就更安全」的替代品。
失败模式:
dataDirHostPath残留旧集群密钥 → 新 mon 起不来(文档警告:测完删集群必须清路径)。- 节点不足且不允许同节点多 mon → mon 调度失败。
- 网络策略或 hostNetwork 配置错误 → quorum 选不出。
2.2 mgr
spec.mgr.count 为 1–2,默认叙事常为 2。Rook
用 mgr_role=active|standby 一类标签帮助 Service
选中 active mgr。Dashboard、Prometheus mgr
模块等依赖正确指到 active。
mgr 不负责 RADOS 数据面存放;它挂了不会立刻让已挂载 RBD 停止 I/O,但会削弱监控、部分管理 API 与部分编排辅助能力。排障时把「mgr 0/1」与「OSD down」分开。
三、设备发现与 OSD
3.1 前置条件(Quickstart)
集群要消费本地存储时,至少一类可用:
- 未分区/未做文件系统的 raw disk;
- 未做文件系统的 raw partition;
- 未做文件系统的 LVM LV;
- 加密设备(仍须满足「未做文件系统」等约束,按文档);
- multipath;
- 或 block 模式
PVC(
cluster-on-pvc一类云环境叙事)。
永远不要在未理解选择器的宿主机上对生产盘开
useAllDevices: true。
文档明确:该开关会自动消费发现到的设备,存在误格式化风险;LVM
LV 也不会被 useAllDevices 捡起。
3.2 发现与 prepare
Operator 根据 storage.useAllNodes /
nodes / deviceFilter /
devicePathFilter /
storageClassDeviceSets
等决定目标。典型可见:
rook-ceph-osd-prepare-*Job/Pod:探测与准备;rook-ceph-osd-<id>:长期运行的 OSD。
无真实集群时,只记住语义:prepare 失败 → 通常还没有健康 OSD;不要对空集群创建大量 PVC 指望「先 Bound 再说」。
设备过滤字段的工程含义是「白名单/黑名单思维」:deviceFilter、路径过滤、按节点
overrides,都是为了把系统盘与数据盘分开。写过滤器前先在节点上确认盘符稳定策略(尤其云上盘符重排、multipath
名)。过滤器写错时,常见表象是 prepare
成功但选了错误的盘,或反复跳过所有盘导致 OSD
数为零——前者比后者更危险,因为表面上集群「起来了」。
removeOSDsIfOutAndSafeToRemove
一类字段把「盘坏了之后是否自动清理 OSD」交给
CR。默认偏保守是合理的:自动移除减少人工,但也减少「先确认数据已恢复再拆」的停顿点。生产变更应把该开关与告警、值班手册写在一起,而不是只在
YAML 里静默打开。
3.3 PVC 模式 vs host 模式(争论入口)
| 模式 | 优点 | 代价 |
|---|---|---|
| Host raw devices | 路径短、性能叙事直接、运维心智接近传统 Ceph | 节点生命周期与盘绑定;云上裸盘少 |
| OSD on PVC | 适配动态云盘;节点可更不可变 | 多一层块存储;可能「云盘上再做 Ceph」双层税(ceph/18 排除树已警告) |
本系列不在此做延迟排名。选型上:若已在公有云且底层已是云盘,先问是否该直接用云 CSI,而不是默认 Rook(第 14–16 篇)。若必须 Rook,PVC 模式是编排适配,不是免费性能午餐。
四、dataDirHostPath:重启后还在的那份状态
CephCluster CRD 对 dataDirHostPath
的约束可以直接写成运维纪律:
- 宿主机上存放各服务配置与数据的路径;多集群必须互异。
- 禁止使用
/etc/ceph、/rook、/var/log/ceph及其子路径。 - 目录不存在时会创建;Pod 删了路径还在。
- 若为空,则落到与 Pod 生命周期绑定的 emptyDir——不适合要活过重启的生产 mon 数据叙事。
- 测试反复装集群:必须清理该路径,否则旧密钥导致新 mon 失败。
这与「PVC Bound」无关:即使 CSI 全好,mon 因残留目录起不来,整个控制面仍是红的。
五、健康闸门与 toolbox
5.1 Quickstart 健康判据
官方验证清单(语义):
- 全部 mon 在 quorum;
- 至少一个 mgr active;
- 至少三个 OSD
up且in(示例规模;真实规模按设计); - 健康为
HEALTH_OK;否则必须调查 WARN/ERR。
这些检查通过 toolbox(管理客户端 Pod)跑
ceph status / ceph -s
一类命令完成。本篇不粘贴示例输出——那是官方文档示例集群的截图材料,不是你的环境。
5.2 升级时的
HEALTH_ERR 拒绝
Ceph 升级文档写明:当请求更新
cephVersion.image 时,Operator 会检查 Ceph
状态;若处于
HEALTH_ERR,默认拒绝继续升级。Health
Verification 文档补充:可用
skipUpgradeChecks: true 或
continueUpgradeAfterChecksEvenIfNotHealthy: true
强行继续,但被标为潜在不安全。
相关 CR 字段还有:
upgradeOSDRequiresHealthyPGs:为 true 时 OSD 升级等待 PG 健康;skipUpgradeChecks:跳过检查(自负风险)。
本系列立场:HEALTH_ERR
时先修数据面或配置错误,再改镜像。把「升级当修复」是把闸门拆掉。完整滚动顺序、一次一个主版本、Tentacle
注意事项见 第 11
篇。
Squid → Tentacle 属于支持的主版本步进叙事;Tentacle v20.2.0 与 read affinity 的已知风险在系列版本锚定中已标(须 v20.2.1+)。机制正文默认仍按 Squid 讲,Tentacle 特性打「Tentacle+」。
健康闸门与「应用是否可写」之间还有缝:HEALTH_WARN
时集群往往仍可服务,但升级策略可能更保守;HEALTH_OK
也不保证某个具体 RBD image 的 features
与节点内核匹配。后者是 CSI 挂载轴问题,不会被
ceph status 一行消化。把 toolbox 输出当成应用
SLO 的充分条件,是本篇明确反对的读法。
continueUpgradeAfterChecksEvenIfNotHealthy
与 skipUpgradeChecks
的语义也不相同:一个是在检查未通过时仍继续,一个是跳过检查流程。二者都是破窗工具。若因紧急漏洞必须破窗,应在变更窗口记录破窗原因、当时健康明细与回滚镜像,而不是把破窗旗标长期留在
CR 里。
六、集群模式四象限(知道边界即可)
CephCluster 文档开篇列四种模式:
- Host Storage Cluster:宿主机盘/路径;
- PVC Storage Cluster:用 StorageClass 动态盘做 OSD;
- Stretched Storage Cluster:mon 跨三区,OSD 在两区等;
- External Ceph Cluster:接入已有 Ceph,Rook 不管理其 OSD 生命周期。
本篇主线是 1/2 的「Operator 管 daemon」。External 模式下,「健康」可能在集群外;Rook 侧绿灯不代表外部 RADOS 绿灯。Stretch 则把故障域写进 CR,失败模式更接近网络与仲裁,而不是简单少盘。
七、谱系、争论与开放问题
谱系:经典 Ceph 运维是主机上的 systemd/cephadm;Rook 把「装 mon/osd、换镜像、盯健康」收成 CR reconcile。这与 CSI 外置同一时代主题:把存储系统的生命周期嵌进 Kubernetes 控制面。代价是多一层「Operator 误解 CR」的故障类。
争论:自动发现 vs 显式设备清单
| 立场 | 主张 | 风险 |
|---|---|---|
自动(useAllDevices / 宽 filter) |
装得快、节点同构时省事 | 误吞系统盘或数据盘;变更难审计 |
显式 devices / 窄 filter / PVC 模板 |
变更可评审、事故面小 | YAML 变长;扩容要改 CR |
生产默认应偏向显式或严格过滤;自动发现留给可抛掉的实验室。
开放问题:
- OSD prepare 失败的可观测性:能否在 CephCluster status 上稳定区分「无设备」「权限不足」「盘忙」而不必先啃 Operator 日志?(今日常要下钻日志。)
- 健康闸门粒度:
HEALTH_WARN下部分升级可继续、HEALTH_ERR拒绝——边界是否总与数据风险同构?例如某些 WARN 实际已不宜滚动 OSD。第 11 篇回收。
把生命周期读成运维日历也很有用:创建日关注设备与
quorum;稳定日关注 nearfull 与
PDB;变更日关注健康闸门与镜像标签;退役日关注
dataDirHostPath 清理与 OSD 安全移除。Rook
把其中多步自动化了,但日历上的决策点并没有消失——自动化只是把决策从
shell 搬进了 CR 字段与默认策略。
八、与 CSI / 应用的衔接
集群达 HEALTH_OK 之后:
- 才适合创建
CephBlockPool/ StorageClass / PVC(第 6 篇); - CSI 驱动若因第 5 篇所述 RBAC/Driver 问题未就绪,PVC 仍会 Pending——此时不要重装 CephCluster,先查 CSI 控制面;
- 应用已挂载后的 I/O 问题,优先 ceph/ 五轴,而不是反复
reconcile
CephCluster。
toolbox 是排障入口之一,不是长期业务客户端。生产变更仍应回到 CR 与变更评审。
九、小结
CephClusterreconcile 顺序直觉:mon quorum → mgr → 设备发现/prepare → OSD → 健康验证。- 设备前置条件必须满足;
useAllDevices有误格式化风险。 dataDirHostPath决定重启后状态是否还在;残留目录会毒死新集群。HEALTH_OK是使用与升级的实践闸门;HEALTH_ERR时 Operator 默认拒升。- 下一篇专讲 v1.20 强制的 Ceph-CSI Operator 与配置所有权迁移。
十、参考资料
规范 / 官方文档(A)
- Rook v1.20 Quickstart —
健康检查清单、toolbox、
csi-operator.yaml顺序。 - Rook v1.20 CephCluster CRD —
dataDirHostPath、mon/mgr/storage、升级相关字段。 - Rook Ceph Upgrades —
HEALTH_ERR时拒绝升级的叙述(v1.20 文档树Upgrade/ceph-upgrade/)。 - Rook Health Verification —
skipUpgradeChecks/continueUpgradeAfterChecksEvenIfNotHealthy。
站内对照
实验台账
- 本篇无自有集群输出;健康判据引用官方 Quickstart 语义。
→ 上一篇:Rook Operator 与 CRD · 系列目录 · 下一篇:Ceph-CSI Operator
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Rook / CSI】Rook Operator 与 CRD:CephCluster 所有权边界
把 Rook 写成 Kubernetes Operator:钉 CephCluster、CephBlockPool、CephFilesystem、CephObjectStore 等核心 CRD 的职责;划清 reconcile 所有权与 rook-ceph 默认命名空间;明确 Rook 不重写 RADOS 内核,并讨论 Operator 边界与 Driver CR 所有权争论。
【Rook / CSI】升级闸门:Rook、Ceph 主版本纪律与 CSI Operator 迁移
拆解 Rook 升级与 Ceph 滚动升级的闸门:HEALTH_ERR 拒绝、一次一个主版本、Squid/Tentacle 支持矩阵、v1.20 CSI Operator 必选迁移,以及 snapshot sidecar/CRD 错位——回应 ceph/18 点名的自动升级跳版本风险。
【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】编排全景:五轴坐标系与 16 篇路线
相对 ceph/ RADOS 内核与 storage/ 云块选型,钉清 Rook/CSI 编排层缺口;定义 CSI RPC、sidecar、Operator/CRD、数据面归属、升级闸门五条坐标系,给出 16 篇阅读路线与 PVC Bound 之后 I/O 仍走 krbd→PG→BlueStore 的边界。