Kubernetes 存储基础回顾:PV、PVC、StorageClass、VolumeSnapshotClass 的核心概念与关系
在深入 CSI 快照与拓扑回退演练之前,必须重新夯实 Kubernetes 存储的四个核心抽象:PV(PersistentVolume)、PVC(PersistentVolumeClaim)、StorageClass 以及 VolumeSnapshotClass。它们构成了从静态供给到动态供给、从普通卷到快照卷的完整声明式存储体系。
1. 核心概念定义
| 概念 | 缩写 | API 版本(稳定) | 核心职责 |
|---|---|---|---|
| PersistentVolume | PV | v1 | 集群管理员预置或动态创建的存储资源,独立于 Pod 生命周期 |
| PersistentVolumeClaim | PVC | v1 | 用户对存储的请求(大小、访问模式、存储类),绑定到 PV |
| StorageClass | SC | storage.k8s.io/v1 | 定义动态供给的“存储模板”,包含 Provisioner、参数、回收策略 |
| VolumeSnapshotClass | VSC | snapshot.storage.k8s.io/v1 | 定义快照动态供给的“快照模板”,指定 CSI 快照驱动与参数 |
关键认知:PVC 是用户与存储之间的“声明层”,PV 是“资源层”,StorageClass 是“自动化工厂”,VolumeSnapshotClass 则是“快照工厂”。四者共同支撑起 Kubernetes 存储的声明式生命周期管理。
2. 核心关系:绑定、供给与生命周期
下图展示了 PV、PVC、StorageClass 之间的静态与动态供给关系,以及 VolumeSnapshotClass 在快照链路中的位置。
3. 绑定与供给流程详解
Kubernetes 存储的绑定与供给遵循严格的声明式匹配逻辑,分为静态供给与动态供给两条路径。
3.1 静态供给流程
- 管理员预置 PV:手动创建 PV 对象,指定容量、访问模式、存储类型及后端连接信息。
- 用户创建 PVC:声明所需容量、访问模式,不指定 storageClassName 或指定为 ""(空字符串)。
- 控制平面匹配:Kubernetes 遍历所有 Available 状态的 PV,寻找满足 PVC 容量 >= 请求容量、访问模式兼容、StorageClass 一致的 PV。
- 绑定:匹配成功后,PVC 与 PV 进入 Bound 状态,PV 的
claimRef指向 PVC。
3.2 动态供给流程
- 用户创建 PVC:声明容量、访问模式,并指定
storageClassName: "fast-storage"。 - 控制平面检测:发现 PVC 引用了 StorageClass,且该 StorageClass 的
provisioner为 CSI 驱动。 - 调用 CSI Provisioner:根据 StorageClass 中的参数(如
type: pd-ssd、replication: 3)调用 CSI 驱动的CreateVolume接口。 - 创建 PV 并绑定:后端存储返回卷信息后,系统自动创建对应的 PV 对象,并与 PVC 完成绑定。
动态供给最佳实践:生产环境强烈建议使用动态供给。通过 StorageClass 的
allowVolumeExpansion: true 和 reclaimPolicy: Delete 实现存储的弹性伸缩与自动清理,避免手动管理 PV 带来的运维负担。
4. VolumeSnapshotClass 与快照生命周期
VolumeSnapshotClass 是 Kubernetes 1.20 起 GA 的快照管理核心抽象,其结构与 StorageClass 类似,但职责完全不同。
| 属性 | StorageClass | VolumeSnapshotClass |
|---|---|---|
| API 组 | storage.k8s.io | snapshot.storage.k8s.io |
| 核心字段 | provisioner, parameters, reclaimPolicy | driver, deletionPolicy, parameters |
| 驱动类型 | CSI Provisioner(创建卷) | CSI 快照驱动(创建/删除快照) |
| 回收策略 | Delete / Retain(针对 PV) | Delete / Retain(针对 VolumeSnapshotContent) |
| 绑定对象 | PVC → PV | VolumeSnapshot → VolumeSnapshotContent |
VolumeSnapshotClass 的典型工作流程如下:
- 用户创建
VolumeSnapshot对象,指定volumeSnapshotClassName和源 PVC。 - 控制平面根据 VolumeSnapshotClass 的
driver字段找到对应的 CSI 快照驱动。 - 调用 CSI
CreateSnapshot接口,后端存储生成快照。 - 系统自动创建
VolumeSnapshotContent对象(类似 PV 的角色),并与 VolumeSnapshot 绑定。 - 用户可通过
PVC的dataSource字段引用 VolumeSnapshot,实现从快照恢复卷。
重要限制:VolumeSnapshotClass 与 StorageClass 是独立的资源。即使 StorageClass 支持动态供给,也不代表其对应的 CSI 驱动支持快照。必须确认 CSI 驱动实现了
CreateSnapshot / DeleteSnapshot 接口,并部署了对应的 VolumeSnapshotClass 对象。
5. 四者协作的完整声明式模型
下图从更高维度展示 PV、PVC、StorageClass、VolumeSnapshotClass 在 Kubernetes 声明式存储模型中的协作关系,突出“声明”与“资源”的分离。
6. 常见误区与避坑指南
- 误区一:StorageClass 与 VolumeSnapshotClass 可以共用同一个 CSI 驱动。 正确:两者需要不同的 CSI 能力集,StorageClass 需要
CreateVolume,VolumeSnapshotClass 需要CreateSnapshot。即使驱动相同,也必须分别创建对应的 Class 对象。 - 误区二:PVC 绑定 PV 后无法修改 StorageClass。 正确:PVC 一旦创建,
storageClassName不可修改。如需迁移,需通过克隆或快照恢复的方式创建新 PVC。 - 误区三:VolumeSnapshot 可以直接作为 Pod 的卷使用。 正确:VolumeSnapshot 不能直接挂载,必须通过 PVC 的
dataSource字段恢复为新的 PV 后才能使用。 - 误区四:动态供给的 PV 回收策略只能为 Delete。 正确:StorageClass 的
reclaimPolicy可设置为Retain,此时 PVC 删除后 PV 保留,需要管理员手动清理。