2. CSI 存储插件架构

2.1 CSI 规范概述

Container Storage Interface(CSI)是 Kubernetes 社区与存储厂商共同定义的行业标准接口,旨在将任意存储系统(块存储、文件存储、对象存储)以统一方式接入容器编排平台。CSI 规范定义了三个核心 gRPC 服务:Identity(插件身份与能力声明)、Controller(控制面操作)、Node(节点本地操作)。

服务 RPC 示例 执行位置 关键职责
Identity GetPluginInfo, Probe Controller / Node 共用 插件元数据、健康检查、能力声明
Controller CreateVolume, DeleteVolume, ControllerPublishVolume 控制面(任意节点或独立 Pod) 卷生命周期管理、挂载/卸载准备
Node NodePublishVolume, NodeUnpublishVolume, NodeGetVolumeStats 每个工作节点 卷在节点上的挂载、格式化、指标采集
关键设计原则:Controller 服务不接触节点文件系统,Node 服务不操作存储后端控制面。这种职责分离使得 CSI 插件可以独立升级 Controller 和 Node 组件,是实现 Helm 回滚安全门禁的基础。

2.2 Node Plugin 与 Controller Plugin 职责

Controller Plugin

  • 卷编排:处理 CreateVolume / DeleteVolume,与存储后端 API 交互完成卷分配与回收。
  • 卷发布:ControllerPublishVolume / ControllerUnpublishVolume,将卷关联到特定节点(如云盘挂载到云主机)。
  • 快照与扩容:CreateSnapshot / DeleteSnapshot / ControllerExpandVolume,管理存储级快照和在线扩容。
  • 拓扑感知:通过 GetCapacity 和拓扑键值,指导调度器将 Pod 调度到卷可达的节点。

Node Plugin

  • 节点级挂载:NodePublishVolume 将卷挂载到 Pod 可访问的路径(如 /var/lib/kubelet/pods/xxx/volumes)。
  • 文件系统操作:格式化、挂载选项、块设备映射。
  • 指标暴露:NodeGetVolumeStats 返回卷使用量、inode 计数,供 Prometheus 采集。
  • 节点级扩容:NodeExpandVolume 在节点侧完成文件系统扩容。
运维启示:Controller Plugin 通常以 Deployment 形式运行(1~3 副本),Node Plugin 以 DaemonSet 形式运行。回滚时需特别注意 DaemonSet 的滚动更新策略,避免节点级挂载中断。

2.3 External 组件交互流程

Kubernetes 社区提供了一组 External 组件(Sidecar 容器),它们与 CSI Driver 的 Controller 服务协作,将 Kubernetes 原生资源(PVC、Pod、VolumeAttachment、VolumeSnapshotContent)转换为 CSI RPC 调用。核心组件包括:

  • External-Provisioner:监听 PVC 创建事件,调用 CreateVolume。
  • External-Attacher:监听 VolumeAttachment 对象,调用 ControllerPublishVolume。
  • External-Resizer:监听 PVC 扩容请求,调用 ControllerExpandVolume。
  • External-Snapshotter:监听 VolumeSnapshot 对象,调用 CreateSnapshot / DeleteSnapshot。

下图展示了 CSI 插件各组件之间的完整交互流程:

CSI 插件组件交互架构图 CSI 插件组件交互流程 Kubernetes API Server External-Provisioner External-Attacher External-Resizer External-Snapshotter CSI Controller Plugin (gRPC Server) 存储后端(SAN / NAS / 云盘) CSI Node Plugin (DaemonSet) Kubelet (NodePublishVolume) External 组件通过 Watch Kubernetes API 资源变化,调用 CSI Controller gRPC 接口;Node Plugin 由 Kubelet 直接调用

2.4 交互流程分步说明

  1. Provision 阶段:用户创建 PVC → External-Provisioner 监听到 PVC 事件 → 调用 CSI Controller CreateVolume → 存储后端分配卷 → 创建 PV 对象绑定 PVC。
  2. Attach 阶段:调度器将 Pod 绑定到节点 → KCM 创建 VolumeAttachment → External-Attacher 调用 ControllerPublishVolume → 存储后端将卷挂载到节点(如云盘挂载)。
  3. Mount 阶段:Kubelet 调用 CSI Node Plugin NodePublishVolume → 格式化(如需)→ 挂载到 Pod 可访问路径。
  4. Resize 阶段:用户修改 PVC size → External-Resizer 调用 ControllerExpandVolume → 存储后端扩容 → Node Plugin NodeExpandVolume 完成文件系统扩容。
  5. Snapshot 阶段:用户创建 VolumeSnapshot → External-Snapshotter 调用 CreateSnapshot → 存储后端创建快照 → 创建 VolumeSnapshotContent 对象。
回滚风险点:External 组件与 CSI Controller 的版本必须兼容。如果 Helm 回滚只回滚了 CSI Driver 而不同步回滚 External Sidecar 版本,可能导致 gRPC 接口不匹配(如新增 RPC 参数缺失),造成 Provision 或 Attach 失败。建议在 Helm Chart 中将 External 组件与 CSI Driver 打包为同一版本号,回滚时整体回退。

2.5 组件版本依赖矩阵

组件 Kubernetes 版本要求 CSI 规范版本 回滚兼容性
External-Provisioner ≥ 1.14 v1.0+ 向下兼容 v1.0 RPC
External-Attacher ≥ 1.14 v1.0+ 需匹配 ControllerPublishVolume 签名
External-Resizer ≥ 1.16 v1.2+ 旧版本不支持 NodeExpandVolume
External-Snapshotter ≥ 1.17 v1.0+ CRD 版本需同步回滚
性能基准测试关联:在 Helm 回滚门禁中,每次变更前应执行 CSI 基准测试(Provision 延迟、Attach 吞吐、Mount 并发),回滚后重新测试并与基线对比。External 组件的版本差异会直接影响基准测试结果,尤其是 Resizer 和 Snapshotter 的 RPC 超时设置。