1. 课程导入与存储挑战
在传统虚拟化或物理机时代,存储通常以集中式阵列、SAN 或 NAS 的形式存在,运维人员通过 LUN 映射、NFS 挂载等方式把容量交付给应用。应用对存储的假设相对固定:块设备路径稳定、文件系统由操作系统管理、扩容往往以“换盘、扩柜、迁移”为主。进入 Kubernetes 之后,这些假设被彻底打破。Pod 会被调度到任意节点、随时重建,容器生命周期可能只有几分钟,而应用却要求数据在 Pod 漂移后仍然可用、可挂载、可扩容。存储从“静态资源”变成了“跟随工作负载移动的动态能力”。
云原生存储要解决的核心矛盾可以归纳为四点。第一是生命周期解耦:Pod 与数据卷的生命周期不再绑定,Pod 删除后 PVC 与底层数据仍需保留或按策略回收。第二是声明式交付:用户不直接操作磁盘,而是通过 StorageClass、PVC 声明“我需要 20Gi、ReadWriteOnce、延迟敏感”的存储,由控制器完成供给。第三是可移植与可扩展:同一套存储能力应能在自建机房、公有云、边缘节点上以一致方式使用,并能随节点增加而横向扩展。第四是可观测与自愈:副本降级、OSD 掉线、磁盘故障必须能被自动检测并恢复,而不是依赖人工巡检。
Rook 与 Ceph 的组合正是为应对这些矛盾而设计的。Ceph 是分布式存储系统,提供 RADOS 对象存储底座,并在其上构建 RBD 块存储、CephFS 文件存储和 RGW 对象网关三种接口。它通过 CRUSH 算法把数据分布到多个 OSD 上,通过 Monitor 维护集群地图,通过 Manager 提供监控与编排能力。Ceph 的能力很强,但原生部署与运维复杂度高:需要手工规划 OSD、维护 mon 仲裁、处理 PG 状态、调优参数。Rook 的定位是 Kubernetes 原生的存储编排器,它把 Ceph 的守护进程以 Pod 形式运行在集群中,用 CRD(如 CephCluster、CephBlockPool、CephFilesystem)描述期望状态,由 Rook Operator 持续调谐,使 Ceph 集群的部署、扩容、升级、故障恢复都纳入 Kubernetes 的声明式体系。
理解二者关系时,可以这样定位:Ceph 提供存储能力,Rook 提供生命周期管理。Rook 不替代 Ceph,而是把 Ceph 的组件、配置、密钥、监控、升级流程封装为 Kubernetes 资源。用户通过 kubectl 创建 CR,Rook 负责生成 Ceph 配置、启动 mon/mgr/osd/mds/rgw、准备 OSD 设备、管理 CRUSH 规则与池。CSI 插件再把 RBD 与 CephFS 暴露为 Kubernetes 的 PV,供 Pod 挂载。整条链路可以概括为下图。
上图把整条链路分成四层:用户声明层、Rook 控制层、CSI 接口层和 Ceph 集群层,最下面是真实磁盘。学习本课程时,建议始终沿着这条链路定位问题:PVC 一直 Pending,先看 StorageClass 与 CSI Provisioner;Pod 挂载失败,看 CSI Attach 与 RBD 映射;集群 HEALTH_WARN,看 MON 仲裁、OSD 状态与 PG 分布。这样就不会在大量组件中迷失方向。
本课程的整体学习地图按“由外到内、由部署到运维”组织。第一阶段建立全局认知与实验环境,理解 Rook、Ceph、CSI 的职责边界,并准备好多节点 Kubernetes 集群与可用磁盘。第二阶段完成 Rook 部署与 CephCluster 初始化,观察 mon、mgr、osd 的 Pod 如何被创建,理解 OSD 准备流程与设备选择。第三阶段进入块存储与文件存储实践,创建 CephBlockPool、StorageClass、PVC,验证 RBD 与 CephFS 的挂载、扩容与快照。第四阶段覆盖对象存储、监控告警、故障注入与恢复、升级与容量规划。每一阶段都以“可观察的结果”收尾,例如 PVC 是否 Bound、Pod 是否成功写入数据、集群是否回到 HEALTH_OK。
实验环境规划建议采用 3 个 Kubernetes 节点,每个节点至少 2 核 4GiB 内存、2 块可被 Rook 使用的裸盘或未格式化云盘。示例参数如下:节点名 node1、node2、node3;数据盘 /dev/sdb 与 /dev/sdc 各 100GiB;Ceph 副本数设为 3,min_size 设为 2;MON 数量为 3,MGR 开启 active/standby;OSD 使用 raw 模式直接管理整块设备。若使用虚拟机,务必为数据盘使用独立虚拟磁盘,避免与系统盘混用。网络方面,管理流量与存储流量可以共用,但在生产环境中建议分离 public network 与 cluster network,本课程实验为简化起见先共用,后续章节再讨论分离方案。
为了便于后续章节对照,这里给出一份最小化的环境检查清单,可直接在实验前逐项确认:
| 检查项 | 示例期望值 | 观察命令或方式 |
|---|---|---|
| 节点数量与状态 | 3 个节点均为 Ready | kubectl get nodes -o wide |
| 可用数据盘 | 每节点 2 块 100GiB 未格式化盘 | lsblk -f |
| 磁盘挂载状态 | 数据盘无挂载点 | findmnt /dev/sdb |
| 内核模块 | rbd 模块可加载 | modprobe rbd |
| 时间同步 | 节点间偏差小于 1 秒 | chronyc sources 或 timedatectl |
| 默认 StorageClass | 实验前无冲突默认类 | kubectl get sc |
最后需要明确一个学习心态:Rook 与 Ceph 的复杂度是真实存在的,但复杂度并不等于不可掌握。只要把“声明—调谐—供给—挂载—落盘—恢复”这条主线抓住,再逐层深入每个组件的状态与日志,就能把看似庞杂的存储系统拆解为可验证、可排障的工程对象。接下来的章节将沿着这条主线逐步展开,从集群准备开始,进入 Rook 的部署与 Ceph 集群的初始化。