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 策略自动清理。
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 动态供给工作流程
- 定义 StorageClass:管理员创建 StorageClass 对象,指定 provisioner 和参数。
- 创建 PVC:用户创建 PVC 时设置
storageClassName指向该 StorageClass。 - 自动供给:K8s 控制平面检测到未绑定的 PVC,调用对应 provisioner 创建底层存储(如云盘)。
- 创建 PV:provisioner 自动生成 PV 对象,并与 PVC 绑定。
- Pod 使用:Pod 引用 PVC,挂载存储到容器路径。
注意:如果 PVC 未指定
storageClassName,K8s 会使用集群默认的 StorageClass(如果存在)。在生产环境中,建议显式指定 storageClassName 以避免意外绑定到错误的存储后端。
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 — 查看自动创建的 PVkubectl get pvc — 查看 PVC 绑定状态kubectl describe pvc data-pvc — 查看 PVC 详细信息,包括绑定的 PV 名称
2.7 本章小结
PV 与 PVC 是 K8s 持久化存储的基石,StorageClass 则实现了存储资源的自动化供给。理解这三者的关系与生命周期,是后续实现存储变更门禁检查(如 PVC 容量变更、StorageClass 切换、回收策略校验)的前提。在 Helm Chart 中,我们通常将 StorageClass 和 PVC 定义为模板变量,通过 values.yaml 控制存储配置,从而实现环境间的灵活切换。