1. 课程导入

在 OpenShift 上运行无状态应用时,Pod 可以随时被删除、重建、漂移,因为容器本身不保存任何需要长期留存的数据。但一旦业务变成有状态,例如 MySQL、PostgreSQL、Kafka、Elasticsearch、MinIO、Redis 持久化实例,问题立刻变得复杂:数据必须跨 Pod 生命周期存活,Pod 重建后必须重新挂载到原来的数据,多个副本之间还要保证身份稳定、顺序稳定、访问互斥。本课程要解决的,正是“有状态业务如何在 OpenShift 上获得可靠、可运维、可扩展的存储能力”这一核心问题。

一、学习目标:从“能跑起来”到“能长期稳定运行”

本课程不是简单介绍几个存储概念,而是围绕一条完整的能力链展开。学完之后,你应当能够独立完成以下任务:

  • 理解 OpenShift 中 PV、PVC、StorageClass、VolumeMode、AccessMode 之间的绑定关系,并能根据业务读写特征选择正确的访问模式。
  • 掌握 StatefulSet 的稳定网络标识、有序部署/扩缩容、VolumeClaimTemplate 机制,能够为数据库类业务设计可预测的 Pod 与存储对应关系。
  • 能够对接至少一种真实存储后端,例如 Ceph RBD/CephFS、NFS、iSCSI、云盘或本地 LVM,并完成 StorageClass 参数配置与动态供给验证。
  • 能够识别有状态业务在 OpenShift 上的典型故障:PVC 一直 Pending、Pod 卡在 ContainerCreating、多副本同时写同一卷、节点故障后卷无法重新挂载等,并给出排查路径。
  • 能够设计备份、恢复、扩容、快照与数据迁移方案,使有状态业务具备生产可运维性。

换句话说,学习目标分为三层:第一层是“对象关系清楚”,第二层是“配置与操作正确”,第三层是“故障可判断、数据可恢复”。这三层缺一不可。

二、核心挑战:有状态业务为什么比无状态难

有状态业务的难点并不在于“启动一个容器”,而在于数据与计算分离之后,如何重新建立稳定关联。具体挑战可以归纳为以下几类。

第一,身份稳定性。无状态应用通常不关心自己叫什么名字,但数据库主从复制、Kafka broker、ZooKeeper 节点都依赖固定身份。Pod 名、DNS 名、存储卷必须一一对应,否则重启后可能挂错数据目录。

第二,数据持久性与生命周期。容器删除后数据不能丢,PVC 删除后数据是否保留取决于回收策略。Retain、Delete、Recycle 三种策略在真实环境中影响巨大,误删 PVC 可能导致数据不可恢复。

第三,访问模式与并发控制。ReadWriteOnce 表示同一时刻只能被一个节点以读写方式挂载,ReadOnlyMany 表示多节点只读,ReadWriteMany 表示多节点可同时读写。数据库通常需要 RWO 且单副本写入;共享文件场景才考虑 RWX。选错访问模式,轻则 Pod 调度失败,重则多副本同时写坏数据。

第四,存储后端差异。块存储、文件存储、对象存储的能力边界不同。Ceph RBD 适合数据库单节点读写,CephFS 适合共享目录,对象存储适合备份与归档。OpenShift 只提供抽象接口,真正性能、快照、扩容能力由后端决定。

第五,故障恢复与数据一致性。节点宕机后,卷需要重新挂载到新节点;如果旧节点未完全释放,就会出现 Multi-Attach 错误。此时必须判断是卷仍被占用,还是后端残留映射,处理方式完全不同。

有状态业务最危险的误区是:把无状态应用的“删了重建”习惯直接套用。对有状态业务,删除 PVC、强制删除 Pod、随意修改 StorageClass 都可能造成数据丢失或卷无法回收。

三、整体知识框架:四层结构

本课程的知识框架可以理解为四层:最上层是业务负载,中间是 OpenShift 编排对象,下面是存储抽象接口,最底层是真实存储后端。四层之间通过声明式对象连接,任何一层配置错误都会导致业务无法启动或数据异常。

OpenShift 有状态业务与存储集成知识框架 业务负载层 MySQL / PostgreSQL Kafka / ZooKeeper Elasticsearch MinIO / Redis 持久化中间件 OpenShift 编排层 StatefulSet Headless Service VolumeClaimTemplate Pod 身份 / 有序调度 存储抽象层 StorageClass PV PVC AccessMode / VolumeMode 回收策略 / 快照 / 扩容 真实存储后端层 Ceph RBD / CephFS NFS / iSCSI 云盘 / 本地 LVM 对象存储 / 备份库 快照与复制

这张框架图说明了一个关键事实:有状态业务的稳定性不是由某一层单独决定的。业务层选错访问模式,编排层再正确也无法启动;编排层配置正确,但存储后端不支持快照,备份方案就要另做设计。因此本课程会沿着“业务需求 → 编排对象 → 存储抽象 → 后端能力”的顺序逐层展开。

四、实战路线图:从单实例到生产可运维

为了让学习路径清晰,本课程按能力递进组织为四个阶段。

阶段一:打通最小闭环。先部署一个单副本 MySQL StatefulSet,使用 VolumeClaimTemplate 自动创建 PVC,验证 Pod 重建后数据仍然存在。这个阶段的关键不是“跑起来”,而是观察三件事:PVC 是否 Bound、Pod 是否挂载到正确卷、删除 Pod 后数据是否保留。示例中可以使用 10Gi 的 RWO 卷,StorageClass 选择集群默认动态供给类。

阶段二:掌握存储对象与后端对接。深入 PV/PVC 绑定机制、StorageClass 参数、AccessMode 选择、回收策略差异。此时需要实际查看存储后端中的卷映射,例如 Ceph RBD 的 image 名称、NFS 的导出路径,确认 OpenShift 中的 PVC 与后端真实卷一一对应。

阶段三:处理多副本与故障场景。部署三副本 etcd 或 Kafka,观察有序启动、稳定 DNS、卷与 Pod 的固定对应关系。然后人为制造节点故障、PVC Pending、Multi-Attach 等异常,练习从事件、日志、后端状态三个方向定位问题。

阶段四:生产化运维。设计备份与恢复流程、卷扩容、快照回滚、跨节点迁移。此阶段关注的是数据可恢复性和操作安全性,而不是单次部署成功。

建议在学习每个阶段时都保留一份“操作前状态”和“操作后状态”的记录,例如 PVC 的 Bound 状态、Pod 所在节点、后端卷 ID。有状态业务的排查高度依赖前后对比,单看当前状态往往无法判断问题根源。

五、贯穿课程的关键判断原则

最后给出三条贯穿全课程的原则,后续章节会反复用到。

  1. 先确定访问模式,再选存储后端。单写数据库优先 RWO 块存储;共享读多写少可考虑 RWX 文件存储;备份归档再考虑对象存储。顺序反了,后面很难补救。
  2. PVC 不是临时对象。对有状态业务,PVC 的生命周期通常长于 Pod。删除 Pod 是常规操作,删除 PVC 必须经过确认,必要时先做快照或备份。
  3. 故障判断要看三层。OpenShift 对象状态、Pod 事件与日志、存储后端实际状态,三层信息交叉验证,才能避免误判。例如 PVC Pending 可能是 StorageClass 不存在,也可能是后端容量不足,还可能是访问模式不匹配。