3. Rook架构与Operator模式
Rook 并不是把 Ceph 的安装脚本包装成容器,而是把 Ceph 集群本身变成 Kubernetes 中的一种“可声明资源”。理解这一点,是掌握 Rook 全部运维行为的前提。Rook 的核心由四部分组成:一组自定义资源定义(CRD)描述期望状态,一个 Rook Operator 负责调谐,若干控制器循环持续比对期望与实际,以及由 Operator 动态创建的一批 Ceph 守护进程 Pod。用户只写 YAML,Operator 负责把 YAML 变成真实运行的 Ceph 集群。
CRD:把 Ceph 集群变成 Kubernetes 对象
Rook 安装时会注册多个 CRD,其中最关键的是 cephclusters.ceph.rook.io。它定义了 CephCluster 这种资源类型,使得 kubectl get cephcluster 成为合法命令。除它之外,还有 CephBlockPool、CephFilesystem、CephObjectStore、CephClient 等,分别描述块存储池、文件系统、对象存储和客户端凭据。CRD 只定义“字段长什么样”,真正的行为由 Operator 中的控制器实现。
一个最小化的 CephCluster 示例(教学示例,非实测结果)如下:
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
name: rook-ceph
namespace: rook-ceph
spec:
cephVersion:
image: quay.io/ceph/ceph:v18.2.2
dataDirHostPath: /var/lib/rook
mon:
count: 3
allowMultiplePerNode: false
mgr:
count: 2
dashboard:
enabled: true
storage:
useAllNodes: false
useAllDevices: false
nodes:
- name: node-1
devices:
- name: sdb
- name: node-2
devices:
- name: sdb
- name: node-3
devices:
- name: sdb
这份 YAML 没有描述“先装 mon、再装 mgr、然后装 osd”的步骤,它只声明了最终应该存在 3 个 mon、2 个 mgr、3 个 OSD 节点,以及每个节点使用 sdb 设备。如何达到这个状态,是 Operator 的职责。
Operator 与控制器循环
Rook Operator 是一个长期运行的 Pod,内部包含多个控制器(controller)。每个控制器监听一类资源的事件:创建、更新、删除。事件到达后,控制器不会直接“执行命令”,而是进入调谐(reconcile)循环:读取该资源的期望状态,读取集群中的实际状态,计算差异,然后执行最小必要的动作来消除差异。这个过程反复发生,直到实际状态收敛到期望状态,或遇到无法自动解决的错误并写入事件与状态字段。
调谐循环的关键特征是幂等。同一个 CephCluster 被处理多次,结果应当一致。例如 Operator 发现 mon 数量应为 3、实际为 2,就会创建第 3 个 mon;如果实际已经是 3,则不做任何变更。这种“比对—修正”的循环,使 Rook 能够自动处理 Pod 被驱逐、节点重启、镜像升级等场景,而不需要人工重新执行安装流程。
CephCluster 资源与声明式管理机制
CephCluster 是 Rook 中粒度最粗、也最核心的资源。它描述整个 Ceph 集群的形态:Ceph 版本、mon 与 mgr 数量、数据目录、存储设备选择方式、网络配置、Dashboard 开关等。Operator 读取它之后,会依次创建 mon、mgr、osd 等守护进程,并把进展写回 status 字段。用户通过 kubectl -n rook-ceph get cephcluster rook-ceph -o yaml 可以看到 status.ceph 中的版本、健康状态,以及 status.phase 是否达到 Ready。
声明式管理的关键在于“只描述结果,不描述过程”。当需要扩容时,用户不需要登录节点执行 ceph osd add,而是修改 CephCluster 中的 storage.nodes 列表,再 kubectl apply。Operator 检测到期望状态变化,自动创建新的 OSD。缩容同理:从列表中移除节点,Operator 会安全地销毁对应 OSD 并清理设备。这种机制把“集群变更”统一收敛为对 YAML 的修改,使变更可审计、可回滚、可版本化。
CephCluster 的 status.phase 是否为 Ready,以及 status.ceph.health 是否为 HEALTH_OK。若长时间停留在 Progressing,应查看 Operator 日志与相关 Pod 事件。一次典型调谐过程
以新增一个 OSD 节点为例,实际发生的过程是:用户编辑 CephCluster,在 storage.nodes 中追加 node-4 及其设备 sdc;API Server 更新对象并触发 watch 事件;Cluster Controller 收到事件后进入 reconcile,读取到期望节点数由 3 变为 4;Operator 在 node-4 上启动 rook-ceph-osd-prepare Job,探测 sdc 是否可用、是否已有分区或文件系统;探测通过后创建 osd Deployment 或直接管理 OSD 进程,并更新 CRUSH map;最后把新的 OSD 数量与状态写回 CephCluster.status。整个过程不需要人工介入 Ceph 命令行。
如果设备已被占用或不可用,Operator 不会强行覆盖,而是把失败原因记录到事件和 status 中,调谐循环会以退避方式重试。这正是控制器循环与一次性安装脚本的本质区别:它持续存在,持续观察,持续修正。
Operator 模式带来的运维变化
在传统部署中,Ceph 的升级、扩容、故障恢复依赖人工执行命令并判断结果。在 Rook 中,这些动作被抽象为对 CRD 对象的修改,由 Operator 自动执行。运维人员的主要工作从“执行命令”转变为“声明期望、观察状态、处理异常”。这也意味着,理解 CephCluster 的字段含义、理解调谐循环的收敛条件、理解 status 字段的判读方式,比记住某条 Ceph 命令更重要。Rook 把 Ceph 的复杂性封装在 Operator 内部,但把控制权通过 CRD 完整地交还给用户。