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

【Rook / CSI】Rook Operator 与 CRD:CephCluster 所有权边界

文章导航

分类入口
storagekubernetes
标签入口
#rook#operator#crd#cephcluster#reconcile#kubernetes#v1.20.4

目录

CSI 解决「PVC 如何变成后端卷」;Rook 解决「Ceph 守护进程如何在 Kubernetes 里被声明式地养活」。把两者混成一句「Rook 就是 Ceph 的 CSI」,会在排障时找不到负责人:是 Operator 没调和出 OSD,还是 CSI CreateVolume 失败?

本文钉 Rook 作为 Operator 的工作方式、核心 CRD 分工、reconcile 所有权边界,以及 Rook 明确不做什么(RADOS 内核语义仍在 ceph/)。v1.20 的 Ceph-CSI Operator 专篇见下一篇之后的第 5 篇;本篇先把 Rook 自己的控制面说清。

本篇在系列中的位置

篇目 核心内容
第 2 篇 · CSI 规范与 K8s 接线 Controller/Node、sidecar、PVC→RPC
第 3 篇 · Rook Operator 与 CRD 核心 CRD、reconcile 边界、命名空间
第 4 篇 · CephCluster 生命周期 mon/mgr/osd、设备发现、健康闸门

版本锚定:Rook v1.20.4;文档树 rook.io/docs/rook/v1.20/。K8s v1.31–v1.36。Ceph 镜像线为 Squid / Tentacle(见 CephCluster cephVersion)。


一、Rook 是什么:Operator,不是另一套 RADOS

Kubernetes Operator 模式的直觉是:用自定义资源表达期望状态,用控制器循环把集群调到该状态。 Rook 的 Ceph 运算符(rook-ceph-operator)监视 ceph.rook.io(及关联)CRD,创建并更新 Deployment/DaemonSet/Job、Service、ConfigMap/Secret、以及 Ceph 守护进程 Pod。

对运维的直接含义:

Rook 文档的 Quickstart 把最小安装拆成:CRD 与公共资源 → csi-operator → Rook operator → CephCluster。顺序本身就在强调:编排控制面与 CSI 控制面是两条线,只是常共置在 rook-ceph 命名空间。


二、核心 CRD 地图

下表按「你声明什么意图」组织。字段全集见官方 CRD 文档;此处只钉所有权与后续篇入口

CRD 意图 Operator 侧后果(直觉) 后续
CephCluster 要一个(或外部接入的)Ceph 集群 mon/mgr/osd(及 crash/exporter 等)生命周期;设备发现;升级编排 第 4、11 篇
CephBlockPool 块池(副本或 EC 等池参数) 在 Ceph 中创建/更新 pool;供 RBD StorageClass 引用 第 6 篇
CephFilesystem CephFS(MDS + 数据/元数据池) MDS 部署与 FS 管理 第 8 篇;语义 ceph/13
CephObjectStore RGW 对象网关入口 RGW 部署与对象存储用户/桶相关资源 第 10 篇;语义 ceph/14
CephObjectStoreUser 对象用户/桶策略等 在 ObjectStore 之上的细粒度资源 第 10、15 篇
CephBlockPoolRadosNamespace 多租户命名空间等 隔离与连接信息 第 15 篇
CephClient / CephRBDMirror 客户端能力、镜像等 按文档启用的专项能力 按需;非本篇展开

CSI 侧另有 OperatorConfig / Drivercsi.ceph.io:在 v1.20 上它们是 CSI 设置的权威入口,但所有权叙事属于 Ceph-CSI Operator(第 5 篇),不要再默认「改 rook-ceph-operator-config 就等于改 CSI」。

还有一批「周边 CR」会在生产清单里出现,但不改变本篇边界:例如监控相关的 ServiceMonitor 是否由 CephCluster.spec.monitoring 触发、是否单独 apply monitoring/rbac.yaml。它们属于可观测面(第 12 篇),不应塞进「不会装 Rook」的焦虑里,但升级时漏掉 RBAC 更新会造成「集群好、指标无」的假象。

对象存储用户、桶通知、NFS 导出(experimental)等 CR 同样遵循「先有集群健康,再有高阶 CR」的依赖:CephObjectStore 依赖可用的 RADOS 与(通常)专用池;在 mon 都没 quorum 时 apply 这些资源,只会制造一长串 reconcile 错误。第 10 篇再展开对象与 NFS 边界。

静态示例结构(字段以你使用的 v1.20.4 示例为准,此处仅示意层级):

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: quay.io/ceph/ceph:v19.2.3
  dataDirHostPath: /var/lib/rook
  mon:
    count: 3
  mgr:
    count: 2
  storage:
    useAllNodes: true
    useAllDevices: false

不要把上面的镜像标签当成你环境的已验证版本;生产应钉具体 vRELNUM.Y.Z(或带 build 日期的标签),避免浮动 v19 造成节点间异构——CephCluster CRD 文档明确警告一般主版本标签不适合生产。


三、reconcile 所有权边界

把「谁负责什么」写成可检验命题,避免事故复盘时互相甩锅。

3.1 Rook Operator 拥有

3.2 Ceph-CSI Operator 拥有(v1.20)

3.3 Ceph 守护进程拥有

3.4 用户 / GitOps 拥有

reconcile 循环的失败模式值得单独点名:Operator 会持续重试把状态拉向期望。因此「临时手工改了 Deployment 环境变量」通常会被下一轮调和覆盖;反之,「CR 写错了设备过滤器」会表现为 prepare Job 反复失败,而不是一次性报错后停止。GitOps 与手工 hotfix 混用时,要以 CR 为权威,把热修回写进仓库,否则会出现「昨晚修好、今早又坏」的假故障。

另一个边界是 状态字段 vs 规范字段:看 CephCluster 的 status(条件、ceph 版本标签、消息)是观察,改 spec 才是意图。不要把 status 里的短暂消息理解成需要复制进 spec 的配置。升级观察时,官方示例用 Deployment 上的 rook-version / ceph-version 标签看滚动是否结束——那是状态观察技巧,仍不替代 toolbox 健康检查。

flowchart LR
  user["User_GitOps"] --> cr["Ceph_CRs"]
  user --> sc["StorageClass_PVC"]
  cr --> rookop["rook_ceph_operator"]
  rookop --> daemons["mon_mgr_osd_pods"]
  daemons --> rados["RADOS_truth"]
  user --> csiop["ceph_csi_operator"]
  csiop --> drivers["CSI_ctrl_node"]
  sc --> drivers
  drivers --> rados

四、命名空间与多集群约束

默认示例把 Operator 与集群都放在 rook-ceph。这不是硬性唯一选择,但偏离时必须改:

CephCluster CRD 写明:同一命名空间内通常不支持多个集群;多集群时必须避免设备与 hostPath 冲突dataDirHostPath 必须每集群唯一,且不要使用 /etc/ceph/rook/var/log/ceph 及其子路径。

对「一个 K8s 集群接多个 Ceph」的场景,还有 external mode:spec.external.enable: true 时 Rook 不管理该 Ceph 的 OSD 生命周期,只消费外部集群(并可能部署部分网关类守护进程,条件见文档)。那是另一条所有权边界:RADOS 健康在外部,Rook 只对接入与可选守护进程负责。


五、Rook 明确不做什么

写出否定句,是为了防止系列膨胀成「第二套 Ceph 内核教程」。

Rook 不做 应去哪里
解释 PG peering / last_epoch_started ceph/05
解释 BlueStore deferred / WAL ceph/07–09
解释 RBD 对象命名与 features 语义本体 ceph/12;编排侧 features 错位见本系列第 7 篇
解释 CephFS caps / MDS 平衡 ceph/13
云厂商块 API 教程 storage/70
替代 Ceph「一次一个主版本」升级纪律 第 11 篇 + 官方 Ceph Upgrades

一句话:Rook 编排的是「Ceph 在 K8s 上的生命周期与接线」;Ceph 仍对自己的一致性与本地存储负责。

这也解释了系列拆分:ceph/18 停在编排层,是因为再往下写 CRD 字段不会让 last_epoch_started 更好懂;本系列往上写 Operator,是因为只懂 RADOS 的人仍会在 PVC Pending 时空手。两边互相外链,而不是互相吞并。

若有人把 Rook 理解成「Ceph 的发行版」,会期待它内置一套与 cephadm 对等的 Day-2 百科。Rook 的 Day-2 重点其实是:声明式升级、PDB/disruption、与 K8s 节点生命周期对齐。磁盘更换、CRUSH 细则、深度 scrub 策略,仍要回到 Ceph 自身工具与站内 ceph/ 篇章。Toolbox 提供的是进入 Ceph CLI 的桥,不是把所有 Ceph 运维知识搬进 Kubernetes API。


六、谱系与争论:Operator 边界画在哪

CoreOS / CNCF Operator 模式(CRD + controller)
  → Rook:Ceph 的声明式生命周期
  → CSI 外置:驱动不进 kube 树
  → Rook 内部再拆:Ceph 运算符 vs Ceph-CSI 运算符(v1.20 强化)

Operator 模式没有单一「OSDI 论文」可替代全部工程经验,但其问题定义是清楚的:把人工 runbook 收成可调和的期望状态。Rook 的分叉点在于 Ceph 自身已是重型分布式系统——Operator 若既管 daemon 又细管每一处 CSI 键值,升级面与所有权会缠死。v1.20 把 CSI 设置权威交给 Ceph-CSI Operator,可以读成对这一缠死的工程回应。

争论 A 侧 B 侧 本系列态度
单一 Rook 入口 vs 拆出 CSI Operator 安装步骤少、心智简单 配置所有权清晰、CSI 可独立演进 接受 v1.20 现实:拆出;用第 5 篇写清迁移
谁拥有 Driver CR Rook 自动生成/覆盖 管理员 / Helm ceph-csi-drivers 权威 升级前导出 CR;避免盲目 apply 默认清单冲掉定制
多 CephCluster 共用一套 CSI 节省控制面 provisioner 前缀与密钥/mon 路由易混 开放问题:多集群下前缀与 Secret 设计仍易踩坑

开放问题(可检验):在同一 K8s 上运行两个 Rook 命名空间、两套 CephCluster 时,CSI provisioner 前缀与 mon endpoint Secret 的组合是否能在「只看 PVC Events」的情况下唯一归因到正确集群?若不能,平台层是否需要额外的策略控制器?第 5、15 篇会回到相关约束,但不假装今天已有完美标准答案。

与 ceph/ 三不变量对照,有助于记住分工:ceph/ 的不变量约束数据面正确性;本篇的所有权边界约束控制面归因。两者同时成立,系统才既「存得对」又「坏得可查」。只满足前者,会出现「Ceph 很健康但谁也不知道 PVC 卡在哪」;只满足后者,会出现「K8s 对象都很绿但 PG 正在 incomplete」。系列交叉阅读不是客套,是排障必要条件。


七、实践注意(无集群也可先记住)

  1. 先看 Operator Ready,再看 CephCluster Ready,再看 CSI Driver Ready——三层任一失败,应用 PVC 故事都讲不完。
  2. 改 CR 期望,而不是手删 Pod 当长期手段;手删可能被 reconcile 立即拉回,或掩盖真正的设备/健康问题。
  3. v1.20 新装:确认 csi-operator.yaml(或 Helm 等价物)与 drivers 所需 RBAC/SA 已就位,再纠结 StorageClass。
  4. 文档与示例必须同 tag:Quickstart 明确要求示例 YAML 来自 tagged release(如 v1.20.4),不要混 master。

需真实集群才能粘贴的验证命令语义:kubectl -n rook-ceph get cephclusterkubectl -n rook-ceph get pods、toolbox 内 ceph status。本篇不伪造输出。

把「所有权」写成事故复盘模板,会更有用:

  1. 现象落在哪一类对象(CR / Pod / PVC / Ceph 状态)?
  2. 该类对象的权威控制器是谁(Rook Operator / Ceph-CSI Operator / kubelet+CSI Node / Ceph 本身)?
  3. 最近一次变更是改了 spec、chart values,还是手工 hotfix?
  4. 若变更在错误的权威对象上,期望行为是「无效果」还是「短暂有效后被 reconcile 打回」?

能回答这四问,就不必在群里同时重启 Operator、重建 Pool 与重装节点。第 13 篇排障坐标系会把此模板展开成 Pending / MountFailed 等具体树;本篇只把所有权钉子钉牢。


八、小结

  1. Rook 是 Ceph 的 Kubernetes Operator:CR 表期望,reconcile 出 daemon 与接线。
  2. 核心 CRD 以 CephCluster 为根,块/文件/对象分别由 BlockPool、Filesystem、ObjectStore 等表达。
  3. v1.20 起 CSI 调谐权威在 Ceph-CSI Operator;Rook 不再通过旧 ConfigMap 键值拥有 CSI 设置。
  4. Rook 不解释 RADOS 内核;数据面问题转 ceph/。
  5. 下一篇沿 CephCluster 走完 mon/mgr/osd 生命周期、设备发现与健康闸门。

九、参考资料

规范 / 官方文档(A)

设计脉络(B)

站内对照

实验台账


上一篇:CSI 规范与 K8s 接线 · 系列目录 · 下一篇:CephCluster 生命周期

读完这篇,下一步读什么

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

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 争论。

2026-08-15 · storage / kubernetes

【Rook / CSI】CephCluster 生命周期:从 CR 到 mon/mgr/osd

沿 CephCluster CR 追踪 mon/mgr/osd Pod 如何被调和出来;钉设备发现前置条件、dataDirHostPath、HEALTH_OK 验证与 toolbox;说明 Rook 在 HEALTH_ERR 时默认拒绝 Ceph 升级,并对照 host 设备与 PVC 模式争论。


By .