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 插件各组件之间的完整交互流程:
2.4 交互流程分步说明
- Provision 阶段:用户创建 PVC → External-Provisioner 监听到 PVC 事件 → 调用 CSI Controller
CreateVolume→ 存储后端分配卷 → 创建 PV 对象绑定 PVC。 - Attach 阶段:调度器将 Pod 绑定到节点 → KCM 创建 VolumeAttachment → External-Attacher 调用
ControllerPublishVolume→ 存储后端将卷挂载到节点(如云盘挂载)。 - Mount 阶段:Kubelet 调用 CSI Node Plugin
NodePublishVolume→ 格式化(如需)→ 挂载到 Pod 可访问路径。 - Resize 阶段:用户修改 PVC size → External-Resizer 调用
ControllerExpandVolume→ 存储后端扩容 → Node PluginNodeExpandVolume完成文件系统扩容。 - 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 超时设置。