3. PersistentVolume 与 PersistentVolumeClaim:PV/PVC 解耦模型、静态供给与动态供给、StorageClass 入门
3.1 存储解耦的核心思想:从“硬编码”到“声明式绑定”
在 Kubernetes 出现之前,应用与存储的关系通常是“硬编码”的:开发者在配置文件中直接写入存储服务器的 IP、挂载路径或卷 ID。这种模式导致应用配置与基础设施强耦合,运维人员无法在不修改应用 YAML 的前提下更换存储后端或调整容量。
PV(PersistentVolume)与 PVC(PersistentVolumeClaim)的引入,将存储的“供给”与“消费”彻底分离:
- PV:由集群管理员预先创建或通过 StorageClass 动态创建,代表一块真实的存储资源(如 NFS 导出、Ceph RBD 块设备、云磁盘)。
- PVC:由应用开发者(或命名空间管理员)创建,描述对存储的需求(容量、访问模式、性能等级)。
Kubernetes 控制平面中的 PersistentVolumeController 负责将匹配的 PV 与 PVC 进行绑定,绑定完成后,Pod 即可通过 PVC 名称引用该存储。这种模型实现了“存储资源定义”与“存储使用声明”的解耦,使得应用 YAML 可以在不同集群间移植,而无需修改存储细节。
3.2 PV 与 PVC 的生命周期与状态机
PV 和 PVC 各自拥有独立的状态机,理解这些状态是排查存储绑定问题的关键。
| 资源 | 状态 | 含义 |
|---|---|---|
| PV | Available |
空闲,尚未被任何 PVC 绑定 |
Bound |
已绑定到某个 PVC | |
Released |
绑定的 PVC 已被删除,但 PV 尚未回收 | |
Failed |
自动回收失败 | |
| PVC | Pending |
尚未绑定到 PV(等待匹配或动态供给完成) |
Bound |
已绑定到某个 PV | |
Lost |
绑定的 PV 丢失或删除 |
绑定过程遵循 匹配规则:PVC 中声明的 accessModes(ReadWriteOnce / ReadOnlyMany / ReadWriteMany)和 resources.requests.storage 必须与 PV 提供的属性兼容。此外,PVC 可以通过 selector 字段按标签精确匹配 PV,或通过 storageClassName 指定使用某个 StorageClass。
3.3 静态供给 vs 动态供给:两种供给模式对比
Kubernetes 支持两种 PV 供给方式,适用于不同的运维场景。
| 维度 | 静态供给(Static Provisioning) | 动态供给(Dynamic Provisioning) |
|---|---|---|
| 操作者 | 集群管理员手动创建 PV | StorageClass 自动创建 PV |
| 适用场景 | 已有外部存储(如 NFS、iSCSI)需要接入 | 云环境或支持 API 的存储后端(如 AWS EBS、GCE PD) |
| 容量规划 | 需提前预分配,容易造成碎片或浪费 | 按需创建,PVC 删除后 PV 自动回收 |
| 运维复杂度 | 高,需手动管理 PV 生命周期 | 低,由 Provisioner 插件自动处理 |
| 绑定速度 | 取决于 PV 是否提前就绪 | PVC 创建后即时触发创建 |
3.4 StorageClass:动态供给的“配方”
StorageClass 是动态供给的核心抽象,它定义了如何创建 PV 的“模板”。每个 StorageClass 包含以下关键字段:
- provisioner:指定存储后端插件,如
kubernetes.io/aws-ebs、kubernetes.io/gce-pd、nfs.csi.k8s.io。 - parameters:传递给 provisioner 的配置参数,如
type: gp3、replication: 3。 - reclaimPolicy:PV 被释放后的处理策略,可选
Delete(默认)或Retain。 - allowVolumeExpansion:是否允许后续扩容。
- mountOptions:挂载时附加的选项。
以下是一个 AWS EBS 动态供给的 StorageClass 示例:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
iopsPerGB: "10"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
当 PVC 引用 storageClassName: fast-ssd 时,Kubernetes 会调用 AWS EBS 的 API 自动创建一个 20Gi 的 gp3 卷,并生成对应的 PV 对象。整个过程无需管理员介入。
3.5 PV/PVC 绑定与使用流程(含 SVG 架构图)
下图展示了从 PVC 创建到 Pod 挂载的完整数据流,涵盖静态供给与动态供给两条路径:
3.6 回收策略与数据安全
当 PVC 被删除后,PV 的回收行为由 reclaimPolicy 决定:
- Delete:自动删除底层存储资源(如云磁盘、Ceph RBD 镜像),数据不可恢复。适用于临时数据或可重建环境。
- Retain:保留 PV 及其底层存储,PV 状态变为
Released。管理员可以手动恢复数据或重新使用该 PV。适用于需要数据保留的场景。 - Recycle(已弃用):执行基础清理(如
rm -rf)后重新变为Available。不推荐使用。
Delete 策略。如果 PVC 被误删除,底层数据会立即丢失。对于有状态应用(如数据库),务必在 StorageClass 中设置 reclaimPolicy: Retain,或使用快照/备份机制。
3.7 访问模式与多节点共享
PV 的 accessModes 决定了存储可以被如何挂载:
| 访问模式 | 缩写 | 说明 | 典型后端 |
|---|---|---|---|
| ReadWriteOnce | RWO | 单节点读写 | 云块存储(EBS、GCE PD)、Ceph RBD |
| ReadOnlyMany | ROX | 多节点只读 | NFS、CephFS、GlusterFS |
| ReadWriteMany | RWX | 多节点读写 | NFS、CephFS、Longhorn |
PVC 在声明时必须指定至少一种访问模式,Kubernetes 会优先匹配完全一致的 PV。如果 PV 支持多种模式(如 NFS 同时支持 RWO 和 RWX),则 PVC 只需声明其中一种即可绑定。
3.8 本章小结
- PV/PVC 解耦模型将存储资源定义与使用声明分离,是 Kubernetes 存储架构的基石。
- 静态供给适合已有存储设备接入,动态供给通过 StorageClass 实现自动化,是云原生推荐方式。
- StorageClass 是动态供给的“配方”,包含 provisioner、参数、回收策略等关键配置。
- 理解 PV/PVC 状态机、回收策略和访问模式,是正确管理有状态工作负载的前提。