2. Kubernetes 存储基础:PV、PVC、StorageClass、CSI 驱动原理回顾
在深入 Rook Ceph 与 Velero 协同方案之前,必须重新夯实 Kubernetes 存储的核心抽象层。PV(PersistentVolume)、PVC(PersistentVolumeClaim)、StorageClass 与 CSI(Container Storage Interface)共同构成了声明式存储供给与消费的完整链路。理解这四层的关系,是后续拓扑设计与故障恢复剧本的前提。
2.1 四层抽象模型与数据流
Kubernetes 将存储的供给与消费彻底解耦:集群管理员负责 PV(存储资源),应用开发者负责 PVC(存储需求),StorageClass 提供动态供给模板,CSI 驱动则作为真正的存储操作执行层。下图展示了从 PVC 创建到 Pod 挂载的完整数据流。
2.2 核心概念对比
下表从定义、生命周期、创建者、访问模式四个维度对比 PV、PVC、StorageClass 与 CSI 驱动,帮助运维人员快速区分职责边界。
| 概念 | 定义 | 生命周期 | 创建者 | 访问模式示例 |
|---|---|---|---|---|
| PV | 集群中的存储资源卷,独立于 Pod 存在 | 由管理员创建,直到被删除或回收策略生效 | 集群管理员 | ReadWriteOnce / ReadOnlyMany / ReadWriteMany |
| PVC | 用户对存储资源的请求声明(大小、访问模式) | 与 Pod 生命周期绑定,Pod 删除后 PVC 可保留 | 应用开发者 | 与匹配的 PV 一致 |
| StorageClass | 动态供给的模板,定义存储类型、参数、回收策略 | 集群级资源,长期存在 | 集群管理员 | 由 provisioner 决定 |
| CSI 驱动 | 实现 CSI 接口的插件,负责实际存储操作 | 以 DaemonSet + Controller 形式运行 | 集群管理员 / 云厂商 | 由后端存储决定 |
2.3 PVC 与 PV 的绑定机制
PVC 与 PV 的绑定遵循精确匹配与容量优先原则。当 PVC 创建后,Kubernetes 控制面会遍历集群中所有可用 PV,筛选出满足以下条件的 PV:
- 容量匹配:PV 的容量必须大于或等于 PVC 请求的容量。
- 访问模式匹配:PV 的访问模式必须包含 PVC 请求的模式。
- StorageClass 匹配:如果 PVC 指定了 StorageClass,PV 的 StorageClass 必须一致;未指定时只匹配未设置 StorageClass 的 PV。
- 标签选择器:如果 PVC 定义了 selector,PV 的标签必须完全匹配。
运维要点: 绑定是独占的——一个 PV 同一时间只能绑定一个 PVC。绑定后 PV 的状态从 Available 变为 Bound。如果 PVC 被删除,PV 的回收策略(Retain / Delete / Recycle)决定后续行为。在 Rook Ceph 场景中,推荐使用 Retain 策略防止数据被意外清理。
2.4 StorageClass 动态供给原理
StorageClass 使得 PVC 无需预先创建 PV,而是由集群按需自动生成。其核心字段包括:
| 字段 | 说明 | Rook Ceph 典型值 |
|---|---|---|
| provisioner | 指定 CSI 驱动的名称 | rook-ceph.rbd.csi.ceph.com |
| parameters | 传递给 CSI 驱动的参数,如池名称、文件系统类型 | clusterID: rook-ceph / pool: replicapool |
| reclaimPolicy | PVC 删除后 PV 的处理方式 | Retain 或 Delete |
| allowVolumeExpansion | 是否允许在线扩容 | true |
| mountOptions | 挂载时附加的选项 | discard / noatime |
动态供给的触发流程如下:
- 用户创建 PVC 并指定
storageClassName。 - Kubernetes 控制面找到对应的 StorageClass 对象。
- 调用 StorageClass 中定义的 provisioner(即 CSI 驱动控制器)。
- CSI 驱动调用后端存储接口创建卷(如 Ceph RBD 镜像)。
- 生成的 PV 自动与 PVC 绑定,状态变为 Bound。
最佳实践: 在 Rook Ceph 环境中,建议为不同性能需求(如 SSD 池、HDD 池、EC 池)分别创建独立的 StorageClass,并通过 PVC 的 storageClassName 字段选择。这可以在不修改应用 YAML 的前提下灵活切换存储后端。
2.5 CSI 驱动架构与操作流程
CSI 驱动是 Kubernetes 存储生态的标准化插件接口。一个完整的 CSI 驱动包含三个核心组件:
- Controller Plugin:以 Deployment 形式运行,负责卷的创建、删除、快照、扩容等控制面操作。
- Node Plugin:以 DaemonSet 形式运行在每个节点上,负责卷的挂载、格式化、卸载等数据面操作。
- Sidecar 容器:与 CSI 驱动容器同 Pod 运行,负责将 Kubernetes 的存储请求转换为 CSI 标准 gRPC 调用。
下图展示了 CSI 驱动在 Kubernetes 集群中的部署架构与调用链路。
2.6 常见运维场景与避坑指南
常见陷阱:
- PVC 一直 Pending:检查 StorageClass 是否存在、provisioner 是否正确、后端存储池是否有剩余容量。使用
kubectl describe pvc <name>查看事件。 - PV 回收策略误配:如果使用 Delete 策略,PVC 删除后 PV 和后端卷会被直接删除,数据不可恢复。生产环境建议统一使用 Retain。
- CSI 驱动版本不匹配:Rook Ceph 的 CSI 驱动版本必须与 Kubernetes 版本兼容,否则可能出现挂载超时或卷操作失败。
- 节点重启后挂载丢失:检查 CSI Node Plugin 是否正常运行,以及
/var/lib/kubelet/plugins目录下的 CSI socket 文件是否存在。