Kubernetes存储架构与CSI接口调用实战 - 第3节

3.1 PersistentVolume(PV)与 PersistentVolumeClaim(PVC)定义

在 Kubernetes 存储体系中,PersistentVolume(PV) 和 PersistentVolumeClaim(PVC) 是一对核心抽象,将存储的供给与消费彻底解耦。PV 由管理员预先配置或通过 StorageClass 动态供给,PVC 则是用户对存储资源的请求。这种设计让应用开发者无需关心底层存储实现,而存储管理员可以集中管理存储资源池。

3.1.1 PersistentVolume(PV)—— 存储资源

PV 是集群中的一块存储资源,独立于任何 Pod 存在。它可以是 NFS、iSCSI、Ceph RBD、GCE Persistent Disk、AWS EBS 等任意存储后端。PV 的生命周期由集群管理员管理,包含容量、访问模式、回收策略、存储类等关键属性。

属性 说明 常见值
capacity.storage PV 的存储容量 10Gi, 100Gi, 1Ti
accessModes 支持的访问模式 ReadWriteOnce, ReadOnlyMany, ReadWriteMany
persistentVolumeReclaimPolicy PVC 释放后的回收行为 Retain, Recycle, Delete
storageClassName 关联的 StorageClass 名称 fast, slow, ssd
mountOptions 挂载时附加选项 ro, hard, nfsvers=4.1
PV 示例(NFS 后端):
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-01
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs-storage
  nfs:
    path: /data/k8s-volumes
    server: 192.168.1.100

3.1.2 PersistentVolumeClaim(PVC)—— 存储请求

PVC 是用户对存储资源的请求声明。用户只需声明所需容量、访问模式和存储类,Kubernetes 控制平面会自动寻找或动态创建满足条件的 PV 并完成绑定。PVC 是 Pod 与 PV 之间的中间层,Pod 通过 PVC 挂载存储,无需感知 PV 的具体后端类型。

属性 说明 示例值
resources.requests.storage 请求的存储容量 10Gi
accessModes 期望的访问模式 ReadWriteOnce
storageClassName 指定 StorageClass(可选) fast
selector 通过标签选择 PV(可选) matchLabels: { tier: ssd }
PVC 示例:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-app-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs-storage

3.2 PV 与 PVC 的绑定关系

当用户创建 PVC 后,Kubernetes 控制平面中的 PersistentVolumeController 会持续扫描集群中的 PV,寻找满足 PVC 条件的 PV 进行绑定。绑定过程遵循以下匹配规则:

  • 容量匹配:PV 的容量必须 大于等于 PVC 请求的容量。
  • 访问模式匹配:PV 必须支持 PVC 声明的访问模式。
  • StorageClass 匹配:PVC 指定 storageClassName 时,PV 必须具有相同的类名;PVC 未指定时,仅匹配未设置 storageClassName 的 PV。
  • 标签选择器匹配:如果 PVC 设置了 selector,PV 必须满足所有标签条件。
  • 状态约束:PV 必须处于 Available 状态。
绑定原则: 一个 PV 同一时间只能绑定到一个 PVC。绑定完成后,PV 状态变为 Bound,PVC 状态也变为 Bound。如果找不到匹配的 PV,PVC 将保持 Pending 状态,直到有合适的 PV 出现或动态供给完成。
PV 与 PVC 绑定关系流程 PV 与 PVC 绑定关系流程 用户创建 PVC PersistentVolumeController 扫描 匹配可用 PV? 绑定 PV → PVC 状态 Bound PVC 保持 Pending 匹配规则:容量 ≥ PVC 请求 · 访问模式兼容 · StorageClass 一致 · 标签选择器匹配

3.3 PV 生命周期管理

PV 的生命周期包含五个阶段:Provisioning → Available → Bound → Released → Reclaim。理解每个阶段的状态转换和回收策略,是生产环境中存储管理的关键。

3.3.1 生命周期阶段

阶段 状态 说明
Provisioning — PV 的创建过程,可以是静态(管理员手动创建)或动态(StorageClass 自动创建)
Available Available PV 已就绪,等待 PVC 绑定
Bound Bound PV 已绑定到某个 PVC,可以被 Pod 使用
Released Released PVC 被删除,PV 上的数据保留,但尚未回收
Reclaim Available / Failed 根据回收策略处理 PV 中的数据,完成后可重新使用或废弃

3.3.2 回收策略(Reclaim Policy)

当 PVC 被删除后,PV 的回收策略决定了后续行为:

  • Retain(保留):PV 进入 Released 状态,数据保留,管理员可以手动恢复或清理数据后重新使用。这是最安全的策略,适合生产环境。
  • Delete(删除):PV 及其关联的后端存储资源(如 AWS EBS 卷、GCE PD)会被自动删除。适合动态供给场景。
  • Recycle(回收):已废弃,Kubernetes 1.20+ 不再推荐。执行 rm -rf /volume/* 清空数据后 PV 回到 Available 状态。
生产环境建议: 对于有状态应用(数据库、消息队列等),始终使用 Retain 策略。误删 PVC 后,数据仍保留在 PV 中,管理员可以手动恢复绑定。对于临时或可重建的数据,可以使用 Delete 策略以简化运维。
PV 生命周期状态转换 PV 生命周期状态转换 Provisioning Available Bound Released Reclaim 策略执行 Retain(手动恢复)/ Recycle Delete → 资源释放 回收策略:Retain(保留数据)| Delete(自动删除)| Recycle(已废弃,清空数据)

3.4 绑定模式与动态供给

Kubernetes 支持两种 PV 供给模式:

  • 静态供给(Static Provisioning):管理员预先创建一批 PV,PVC 创建时从中匹配绑定。适合存储资源固定、容量可预估的场景。
  • 动态供给(Dynamic Provisioning):通过 StorageClass 定义存储模板,PVC 创建时自动触发后端存储卷的创建和 PV 的生成。适合云环境或需要按需分配的场景。
最佳实践: 生产环境推荐使用动态供给 + StorageClass 管理存储。管理员只需定义好 StorageClass 的配置(如性能类型、副本数、回收策略),用户通过 PVC 指定 storageClassName 即可自动获得匹配的存储卷,大幅减少运维工作量。

3.5 Pod 使用 PVC 的完整流程

Pod 通过 volumes 字段引用 PVC,Kubernetes 将 PVC 对应的 PV 挂载到容器的指定路径。以下是完整的声明式配置示例:

apiVersion: v1
kind: Pod
metadata:
  name: app-with-storage
spec:
  containers:
  - name: app
    image: nginx:latest
    volumeMounts:
    - name: data-volume
      mountPath: /usr/share/nginx/html
  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: pvc-app-data

当 Pod 调度到某个节点后,kubelet 会执行以下步骤:

  1. 读取 Pod 的 volume 定义,找到 PVC pvc-app-data。
  2. 通过 API Server 查询 PVC 的绑定状态,获取对应的 PV 信息。
  3. 根据 PV 的存储后端类型(如 NFS、Ceph、AWS EBS),调用相应的卷插件或 CSI 驱动。
  4. 在节点上执行挂载操作,将远程存储映射到宿主机路径。
  5. 将宿主机路径绑定到容器内的 mountPath。
常见问题: 如果 PVC 处于 Pending 状态,Pod 将无法启动。排查时使用 kubectl describe pvc <pvc-name> 查看事件信息,常见原因包括:没有匹配的 PV、StorageClass 不存在、存储后端资源不足、访问模式冲突。

3.6 核心概念总结

概念 角色 创建者 生命周期 关键属性
PV 存储资源 管理员 / StorageClass 独立于 Pod 容量、访问模式、回收策略、存储类
PVC 存储请求 用户 与 Pod 关联 容量请求、访问模式、存储类、选择器
StorageClass 存储模板 管理员 持久存在 Provisioner、参数、回收策略、绑定模式