Kubernetes存储版本容量清单与跨团队交接 - 第2节

2.1 CSI 驱动架构回顾

Container Storage Interface (CSI) 是 Kubernetes 与存储系统之间的标准插件接口。自 Kubernetes 1.13 进入 GA 以来,CSI 已成为集群存储扩展的唯一推荐方式,替代了原有的 in-tree 存储插件。

CSI 架构核心组件

CSI 驱动以一组 DaemonSet 和 StatefulSet 的形式部署在集群中,通过 gRPC 与 kubelet 及外部控制器通信。其核心组件包括:

组件 部署形态 职责
CSI Controller StatefulSet / Deployment 处理卷的创建、删除、快照、扩容等控制面操作
CSI Node DaemonSet 在每个节点上执行卷挂载、格式化、卸载等数据面操作
External Provisioner Sidecar 容器 监听 PVC 创建事件,调用 CSI Controller 创建卷
External Attacher Sidecar 容器 监听 VolumeAttachment 对象,调用 CSI Controller 附加卷
External Resizer Sidecar 容器 监听 PVC 扩容请求,调用 CSI Controller 扩展卷
External Snapshotter Sidecar 容器 监听 VolumeSnapshot 对象,调用 CSI Controller 创建/删除快照
架构要点: CSI 驱动本身不直接与 kubelet 交互,而是通过 kubelet 内部的 CSI 注册机制和 Unix Socket 通信。Sidecar 容器模式使得 CSI 驱动的控制面逻辑与 Kubernetes 控制器框架解耦,每个 Sidecar 只负责一个特定的 CSI 功能。
CSI 驱动架构组件关系图 Kubernetes API Server External Provisioner External Attacher External Resizer CSI Controller CreateVolume DeleteVolume ControllerPublishVolume CreateSnapshot 存储后端 SAN / NAS 云存储 API 分布式存储 kubelet CSI Node NodePublishVolume NodeUnpublishVolume NodeGetVolumeStats Pod 挂载点 /var/lib/kubelet/pods/... CSI 驱动通过 Unix Socket 与 kubelet 通信,Sidecar 容器监听 Kubernetes API 事件并调用 CSI Controller 的 gRPC 接口

2.2 驱动版本与 K8s 版本兼容矩阵

CSI 驱动的版本与 Kubernetes 版本之间存在严格的兼容性约束。每个 CSI 驱动版本都针对特定范围的 Kubernetes 版本进行测试和验证。升级 Kubernetes 控制面而不升级 CSI 驱动,或反之,都可能导致 PV/PVC 操作失败。

兼容性维度

  • CSI 规范版本: CSI 1.x 与 CSI 2.x 的 gRPC 接口存在差异,驱动必须与 kubelet 支持的 CSI 规范版本匹配。
  • Sidecar 版本: External Provisioner、Attacher 等 Sidecar 容器与 Kubernetes API 版本绑定,旧版 Sidecar 可能无法处理新版 API 对象。
  • Kubernetes 特性门控: 某些 CSI 功能(如卷快照、卷克隆)依赖特定的 Kubernetes 特性门控,驱动版本必须与集群特性门控状态一致。

典型兼容矩阵示例

CSI 驱动版本 兼容 K8s 版本 CSI 规范版本 Sidecar 最低版本 备注
v1.0.x 1.13 – 1.16 1.0 provisioner v1.0 仅支持基本卷管理
v1.5.x 1.17 – 1.20 1.3 provisioner v2.0 支持卷快照 beta
v2.0.x 1.21 – 1.24 1.5 provisioner v3.0 支持卷克隆、卷扩容 GA
v2.5.x 1.25 – 1.27 1.6 provisioner v3.5 支持卷组快照 alpha
v3.0.x 1.28 – 1.30 1.9 provisioner v4.0 支持卷健康监测 GA
版本漂移风险: 当集群从 Kubernetes 1.24 升级到 1.28 时,如果 CSI 驱动仍停留在 v2.0.x,而 Sidecar 未同步升级,则可能出现 External Provisioner 无法解析新版 PVC API 的情况,导致 PVC 一直处于 Pending 状态。

2.3 驱动升级导致 PV/PVC 版本不一致的典型场景

CSI 驱动升级过程中,PV/PVC 对象可能因为版本不匹配而出现状态异常。以下三个场景是生产环境中最高频的故障模式。

场景一:Sidecar 版本滞后导致 PVC 无法绑定

升级 Kubernetes 控制面后,PVC 的 API 版本从 v1 升级到 v1beta1(或反之),但 External Provisioner 仍使用旧版 API 监听事件。Provisioner 无法识别新版 PVC 对象,导致 PVC 一直处于 Pending 状态。

# 查看 PVC 状态
kubectl get pvc my-pvc -o wide
NAME     STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-pvc   Pending                                      fast-storage   5m

# 查看 Provisioner 日志
kubectl logs -n kube-system csi-provisioner-xxxxx
E0825 10:23:45.123456       1 controller.go:789] 
  failed to provision volume: 
  storageclass.storage.k8s.io "fast-storage" not found
  # 实际 StorageClass 存在,但 Provisioner 无法解析新版 API

场景二:CSI Controller 与 Node 版本不一致导致挂载失败

升级 CSI Controller 到 v3.0.x 但未升级 CSI Node DaemonSet,导致 Controller 创建的卷元数据格式与 Node 端解析逻辑不兼容。Pod 调度到节点后,Node 端无法正确挂载卷。

# Pod 事件显示挂载失败
kubectl describe pod my-app
Events:
  Type     Reason       Age   From               Message
  ----     ------       ----  ----               -------
  Warning  FailedMount  12s   kubelet            MountVolume.SetUp failed 
    for volume "pvc-xxxxx" : 
    rpc error: code = Internal desc = 
    staging target path is not mounted:
    /var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-xxxxx/globalmount

场景三:CSI 规范版本不匹配导致卷操作超时

Kubernetes 1.28 默认启用 CSI 规范 v1.9 的某些特性(如卷健康监测),但 CSI 驱动仍使用 v1.5 规范。Controller 返回的卷状态字段格式与 kubelet 期望的不一致,导致卷操作超时。

故障阶段 现象 根因 影响范围
PVC 创建 PVC 一直 Pending Provisioner 无法解析新版 PVC API 新应用部署受阻
Pod 启动 Pod 一直 ContainerCreating Node 端 CSI 驱动版本与 Controller 不匹配 已有应用无法恢复
卷扩容 Resize 失败,PVC 显示 FileSystemResizePending Resizer 与 CSI Controller 的 gRPC 接口版本不一致 存储容量无法扩展
卷快照 VolumeSnapshot 一直 ReadyToUse=False Snapshotter 无法调用新版 CSI 快照接口 备份恢复流程中断
驱动升级导致 PV/PVC 版本不一致的故障链路 K8s 控制面升级 Sidecar 版本滞后 Controller/Node 版本不一致 CSI 规范版本不匹配 PVC 一直 Pending Provisioner 无法解析 新版 PVC API Pod 一直 ContainerCreating Node 端挂载失败 gRPC 接口不兼容 卷操作超时/失败 字段格式不一致 特性门控不匹配 PV/PVC 版本漂移 → 存储服务中断 升级前必须检查 CSI 驱动、Sidecar、CSI 规范三者的版本兼容性
最佳实践: 在升级 Kubernetes 控制面前,先查阅 CSI 驱动的兼容矩阵,确保驱动版本在目标 K8s 版本的兼容范围内。升级顺序应为:先升级 CSI 驱动(Controller + Node + Sidecar),再升级 Kubernetes 控制面,最后升级节点。