2. K8s 存储基础:PersistentVolume (PV) 与 PersistentVolumeClaim (PVC) 核心概念、StorageClass 动态供给

在 Kubernetes 集群中,Pod 是 ephemeral(临时)的,其内部存储会随 Pod 销毁而丢失。为了持久化保存数据,K8s 引入了 PV(PersistentVolume) 和 PVC(PersistentVolumeClaim) 抽象层,将存储的供给与使用解耦。本章将深入剖析这三个核心组件,为后续的存储变更门禁检查奠定基础。

2.1 核心概念:PV 与 PVC

PV 是集群中的存储资源,由管理员预先创建或通过 StorageClass 动态供给;PVC 是用户对存储资源的请求,类似于“申请单”。Pod 通过声明使用 PVC 来挂载存储,无需关心底层存储实现细节。

核心原则:PV 是资源,PVC 是请求。PVC 与 PV 通过 spec 中的 storageClassName、accessModes 和 resources.requests.storage 进行匹配绑定。
组件 角色 生命周期 创建者
PV 集群存储资源(如 NFS、Ceph、云盘) 独立于 Pod,可持久存在 集群管理员 / StorageClass 自动创建
PVC 用户存储请求(容量、访问模式) 与 Pod 生命周期关联,但数据可保留 应用开发者 / 用户
Pod 使用 PVC 挂载存储的工作负载 临时,销毁后 PVC 可被其他 Pod 复用 应用开发者

2.2 PV 与 PVC 的绑定与生命周期

PVC 创建后,K8s 控制平面会尝试寻找满足条件的 PV 进行绑定。绑定过程遵循以下规则:

  • 匹配条件:PVC 的 accessModes、storageClassName 必须与 PV 一致,且 PVC 请求的存储容量 ≤ PV 的容量。
  • 绑定模式:默认是 Immediate(立即绑定),也可设置为 WaitForFirstConsumer(延迟到第一个 Pod 调度时绑定)。
  • 回收策略:PVC 被删除后,PV 的回收行为由 persistentVolumeReclaimPolicy 决定:Retain(保留数据)、Delete(自动删除底层存储)、Recycle(已弃用)。
生产建议:对于有状态应用(如数据库),建议使用 Retain 策略,防止误删 PVC 导致数据丢失。对于临时测试环境,可使用 Delete 策略自动清理。
PV-PVC-Pod 绑定关系与生命周期 PV (PersistentVolume) 集群存储资源 容量: 100Gi / 模式: ReadWriteOnce PVC (PersistentVolumeClaim) 存储请求 请求: 50Gi / 模式: ReadWriteOnce Pod 工作负载 挂载 PVC 到容器路径 绑定 (Bind) 挂载 (Mount) 生命周期流程: 1. 管理员创建 PV 或 StorageClass 动态供给 → 2. 用户创建 PVC 声明需求 → 3. K8s 控制平面匹配并绑定 PV → 4. Pod 引用 PVC 挂载存储 → 5. Pod 删除后 PVC 可保留,PV 按回收策略处理 回收策略对比: • Retain(保留):PVC 删除后 PV 保留,需管理员手动清理 • Delete(删除):PVC 删除后自动删除底层存储(如云盘) • Recycle(回收):已弃用,建议使用动态供给替代

2.3 StorageClass 动态供给

手动创建 PV 的方式在规模化场景下难以维护。StorageClass 实现了存储的动态供给:当用户创建 PVC 时,K8s 根据 PVC 指定的 storageClassName 自动调用对应的存储插件(Provisioner)创建 PV 并绑定。

动态供给优势:无需管理员预先准备 PV;PVC 按需创建,自动匹配;支持多种后端存储(AWS EBS、GCE PD、NFS、Ceph RBD 等)。

2.4 StorageClass 关键参数

参数 说明 示例值
provisioner 存储后端插件名称 kubernetes.io/aws-ebs、nfs.csi.k8s.io
parameters 后端存储的特定配置(如类型、区域) type: gp3、fsType: ext4
reclaimPolicy 动态创建的 PV 默认回收策略 Delete(默认)、Retain
allowVolumeExpansion 是否允许后续扩容 PVC 容量 true、false
mountOptions 挂载时附加的选项 ["noatime","nodiratime"]

2.5 动态供给工作流程

  1. 定义 StorageClass:管理员创建 StorageClass 对象,指定 provisioner 和参数。
  2. 创建 PVC:用户创建 PVC 时设置 storageClassName 指向该 StorageClass。
  3. 自动供给:K8s 控制平面检测到未绑定的 PVC,调用对应 provisioner 创建底层存储(如云盘)。
  4. 创建 PV:provisioner 自动生成 PV 对象,并与 PVC 绑定。
  5. Pod 使用:Pod 引用 PVC,挂载存储到容器路径。
注意:如果 PVC 未指定 storageClassName,K8s 会使用集群默认的 StorageClass(如果存在)。在生产环境中,建议显式指定 storageClassName 以避免意外绑定到错误的存储后端。
StorageClass 动态供给工作流程 用户创建 PVC storageClassName: "fast-storage" K8s 控制平面 检测未绑定 PVC StorageClass provisioner: ebs.csi.aws.com Provisioner 创建底层存储 如 AWS EBS 卷 / GCE PD 自动创建 PV 绑定到 PVC Pod 挂载使用 容器内路径: /data 调用 provisioner 关键点: • 动态供给无需管理员预先创建 PV,大幅降低运维成本 • 每个 StorageClass 对应一种存储后端,支持多种配置(如 SSD/HDD、不同区域)

2.6 实战:定义 StorageClass 与 PVC 示例

以下是一个完整的动态供给示例,使用 AWS EBS CSI 驱动创建 gp3 类型的存储卷:

# storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  fsType: ext4
  iops: "3000"
  throughput: "125"
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
  - noatime
  - nodiratime
---
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi
  storageClassName: fast-storage
---
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: nginx:latest
    volumeMounts:
    - mountPath: /data
      name: data-volume
  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: data-pvc
验证命令:
kubectl get sc — 查看 StorageClass 列表
kubectl get pv — 查看自动创建的 PV
kubectl get pvc — 查看 PVC 绑定状态
kubectl describe pvc data-pvc — 查看 PVC 详细信息,包括绑定的 PV 名称

2.7 本章小结

PV 与 PVC 是 K8s 持久化存储的基石,StorageClass 则实现了存储资源的自动化供给。理解这三者的关系与生命周期,是后续实现存储变更门禁检查(如 PVC 容量变更、StorageClass 切换、回收策略校验)的前提。在 Helm Chart 中,我们通常将 StorageClass 和 PVC 定义为模板变量,通过 values.yaml 控制存储配置,从而实现环境间的灵活切换。