2. K8s 存储对象基础:PV / PVC / StorageClass 的核心概念、存储版本与 API 组的关系

在 Kubernetes 存储体系中,PV(PersistentVolume)、PVC(PersistentVolumeClaim) 和 StorageClass 是三个核心对象,它们共同实现了存储的声明式供给与生命周期管理。理解这三者的定义、交互方式以及它们与 API 组、版本的关系,是校准存储版本漂移的前提。

2.1 核心概念与职责划分

对象 作用域 核心职责 生命周期
PV 集群级 代表底层存储资源(NFS、Ceph、云盘等),由管理员或动态供给程序创建 独立于 Pod,即使 Pod 删除,PV 仍可保留或回收
PVC 命名空间级 用户对存储资源的请求(大小、访问模式),绑定到满足条件的 PV 与使用它的 Pod 关联,Pod 删除后 PVC 默认保留
StorageClass 集群级 定义存储的“类”(如 SSD 或 HDD),实现动态 PV 供给 由管理员创建,持久存在
关键原则: PVC 是用户与存储之间的“请求单”,PV 是“资源池”,StorageClass 是“自动生产车间”。三者通过 spec 字段中的 storageClassName 和 selector 进行匹配。

2.2 三对象交互流程(绑定与供给)

下图展示了从 PVC 创建到 PV 绑定的完整路径,以及 StorageClass 在动态供给中的角色。

PV / PVC / StorageClass 交互流程 PV / PVC / StorageClass 交互流程 用户 / 工作负载 PVC 匹配 / 绑定 PV StorageClass 说明: • 静态供给:管理员预先创建 PV,PVC 通过 spec 匹配(大小、访问模式、标签)绑定到已有 PV。 • 动态供给:PVC 指定 storageClassName,StorageClass 根据 provisioner 自动创建 PV 并完成绑定。
版本漂移关注点: 在集群升级或 API 版本废弃过程中,PV / PVC / StorageClass 的 apiVersion 字段可能从 v1 变为 v1beta1 或 v1alpha1,导致存储对象无法被新版 kube-apiserver 正确解析。这是“存储版本漂移”的核心场景之一。

2.3 存储版本与 API 组的关系

Kubernetes 存储对象属于 核心 API 组(core API group),其 API 版本演进路径如下:

  • 核心组(v1): PV、PVC、StorageClass 在 v1 版本中稳定可用,apiVersion: v1。
  • 历史版本: 早期版本(如 v1beta1)已被废弃,但部分旧集群或迁移场景中仍可能残留。
  • API 组标识: 存储对象属于 storage.k8s.io 组(StorageClass)和核心组(PV/PVC)。
对象 API 组 稳定版本 废弃版本(示例) 版本漂移风险
PV core(空) v1 v1beta1(已移除) 低(稳定版本长期支持)
PVC core(空) v1 v1beta1(已移除) 低
StorageClass storage.k8s.io v1 v1beta1(1.17+ 移除) 中(需检查集群版本兼容性)
版本漂移校准提示: 当集群从 1.16 以下版本升级时,StorageClass 的 apiVersion 必须从 storage.k8s.io/v1beta1 迁移到 storage.k8s.io/v1。如果未校准,kube-apiserver 将拒绝解析旧版本对象,导致动态供给失败。

2.4 存储对象版本漂移的典型场景

在发布窗口节点排空回归检查中,存储版本漂移可能表现为以下问题:

  1. PVC 绑定失败: 旧版 PVC 的 apiVersion 不被新版 apiserver 识别,PVC 处于 Pending 状态。
  2. StorageClass 动态供给中断: 旧版 StorageClass 无法触发 provisioner,新 Pod 无法获取存储卷。
  3. PV 回收策略异常: 版本不匹配导致 PV 的 persistentVolumeReclaimPolicy 字段解析错误,回收行为偏离预期。
回归检查要点: 在节点排空前,使用 kubectl get pv,pvc,sc -A -o yaml 导出所有存储对象,检查 apiVersion 字段是否与目标集群版本兼容。重点关注 StorageClass 的 storage.k8s.io/v1 格式。

2.5 版本漂移校准命令示例

以下命令用于检测和修复存储对象的版本漂移:

# 检查所有 StorageClass 的 apiVersion
kubectl get sc -o jsonpath='{range .items[*]}{.apiVersion}{"\t"}{.metadata.name}{"\n"}{end}'

# 将旧版 StorageClass 转换为新版(示例:v1beta1 -> v1)
kubectl get sc my-storage-class -o yaml | \
  sed 's/storage.k8s.io\/v1beta1/storage.k8s.io\/v1/' | \
  kubectl apply -f -

# 验证 PV/PVC 的版本一致性
kubectl get pv -o json | jq '.items[].apiVersion' | sort -u
kubectl get pvc -A -o json | jq '.items[].apiVersion' | sort -u
最佳实践: 在 CI/CD 流水线中加入存储对象版本校验步骤,确保所有 YAML 清单中的 apiVersion 与目标集群的可用版本一致。使用 kubectl convert 命令(已弃用,推荐 kubectl apply --server-side)或手动更新清单。