CSI 驱动架构基础:规范核心概念与通信流程

在深入 CSI 驱动的变更门禁与灾备方案之前,必须首先理解 CSI 规范定义的三大核心组件及其交互方式。CSI(Container Storage Interface)是 Kubernetes 与存储系统之间的标准协议,它通过 gRPC 接口将存储生命周期管理解耦为三个独立的服务角色:Identity、Controller 和 Node。每个角色负责不同的功能域,共同构成一个可插拔、可升级的存储插件体系。

2.1 三大核心服务角色

CSI 规范将存储驱动的职责划分为三个独立的 gRPC 服务,每个服务运行在独立的 gRPC 端点上,但通常由同一个二进制程序提供。下表总结了每个角色的核心职责与关键接口:

服务角色 核心职责 关键 gRPC 接口 部署位置
Identity 插件自描述、版本协商、能力声明 GetPluginInfo, GetPluginCapabilities, Probe 与 Controller/Node 同进程
Controller 卷的创建/删除、快照、克隆、挂载/卸载控制面操作 CreateVolume, DeleteVolume, ControllerPublishVolume, CreateSnapshot 控制面 Pod(通常为 StatefulSet)
Node 卷在节点上的挂载、格式化、卸载、阶段挂载 NodeStageVolume, NodePublishVolume, NodeUnpublishVolume, NodeGetCapabilities 每个工作节点上的 DaemonSet
架构要点:Controller 服务负责集群级别的存储编排(不依赖具体节点),而 Node 服务负责节点本地的存储操作。这种分离使得控制面操作与数据面操作可以独立扩缩容和升级,是 CSI 驱动变更门禁设计的基础。

2.2 Identity 服务:插件身份与能力声明

Identity 服务是 CSI 驱动的“自我介绍”接口。Kubernetes 在加载 CSI 驱动时,首先调用 GetPluginInfo 获取驱动名称和版本,然后调用 GetPluginCapabilities 确认驱动支持哪些功能(如卷扩展、快照、拓扑感知等)。Probe 接口用于健康检查,确保驱动处于可用状态。

Identity 服务的返回值直接影响 Kubernetes 外部组件(如 external-provisioner、external-attacher)的行为。例如,如果驱动声明不支持 VOLUME_EXPAND 能力,Kubernetes 将不会向该驱动发送卷扩展请求。

2.3 Controller 服务:卷生命周期管理

Controller 服务是 CSI 驱动的“大脑”,负责所有不依赖具体节点的存储操作。它通常运行在控制面 Pod 中,与 Kubernetes 的 external-provisioner、external-attacher 等 sidecar 容器协同工作。核心接口包括:

  • CreateVolume / DeleteVolume:在存储后端创建或删除持久卷,支持指定容量、参数、拓扑约束。
  • ControllerPublishVolume / ControllerUnpublishVolume:将卷附加到指定节点(如云盘挂载到虚拟机),返回设备路径。
  • CreateSnapshot / DeleteSnapshot:创建或删除卷的快照,用于备份与恢复。
  • ListVolumes / ListSnapshots:列举存储后端上的卷或快照,用于容量管理和审计。
变更门禁关注点:Controller 服务的接口变更(如新增参数、修改返回格式)会直接影响 external-provisioner 的调用逻辑。在驱动升级时,必须确保新旧版本的 Controller 接口兼容,否则可能导致卷创建失败或数据丢失。

2.4 Node 服务:节点本地存储操作

Node 服务运行在每个 Kubernetes 工作节点上,负责将卷挂载到 Pod 的文件系统。它通过以下接口实现分阶段挂载:

  1. NodeStageVolume:将卷挂载到节点上的“暂存路径”(staging path),通常执行格式化、挂载文件系统等操作。
  2. NodePublishVolume:将卷从暂存路径绑定挂载到 Pod 的容器路径。
  3. NodeUnpublishVolume / NodeUnstageVolume:逆操作,卸载卷并清理暂存路径。
  4. NodeGetCapabilities:声明节点服务支持的能力(如是否支持卷扩展、是否支持多节点挂载)。

Node 服务的稳定性直接影响 Pod 的调度与运行。如果 Node 服务在挂载过程中崩溃,可能导致 Pod 无法启动或数据损坏。

2.5 gRPC 通信流程与接口调用链

CSI 驱动与 Kubernetes 组件之间通过 gRPC 进行双向通信。下图展示了从 PVC 创建到 Pod 使用卷的完整调用链:

CSI 驱动 gRPC 通信流程(PVC → Pod 挂载) Kubernetes API external-provisioner external-attacher CSI Controller 存储后端 kubelet CSI Node Pod 容器路径 Watch PVC CreateVolume API 调用 Watch VA ControllerPublish Pod 调度 NodeStage/Publish 绑定挂载 说明: gRPC 调用使用 Protocol Buffers 序列化,通过 Unix Domain Socket 或 TCP 通信。Identity 服务在驱动启动时被调用,用于能力协商。

2.6 接口调用时序与关键参数

以下是一个典型的 CSI 卷挂载时序,展示了 Controller 与 Node 服务之间的协作关系:

  1. PVC 创建:用户创建 PVC,Kubernetes 调度 external-provisioner 监听。
  2. CreateVolume:external-provisioner 调用 CSI Controller 的 CreateVolume 接口,传入容量、参数、拓扑约束。
  3. ControllerPublishVolume:external-attacher 调用 ControllerPublishVolume,将卷附加到目标节点,返回设备路径。
  4. NodeStageVolume:kubelet 调用 CSI Node 的 NodeStageVolume,在节点上格式化并挂载卷到暂存路径。
  5. NodePublishVolume:kubelet 调用 NodePublishVolume,将卷从暂存路径绑定挂载到 Pod 的容器路径。
关键参数传递:每个 gRPC 调用都包含 volume_id、node_id、capability 等上下文信息。在变更门禁设计中,必须验证这些参数的兼容性,避免因参数结构变化导致调用失败。

2.7 接口版本协商与兼容性

CSI 规范要求驱动在 Identity 服务中声明支持的 CSI 版本(如 1.5.0、1.6.0)。Kubernetes 的 sidecar 组件会根据驱动声明的版本选择调用对应的接口。如果驱动升级后不再支持旧版本接口,可能导致 sidecar 无法正常工作。

CSI 版本 新增关键接口 变更影响
1.0 基础 CreateVolume、NodePublishVolume 初始版本
1.1 CreateSnapshot、ListSnapshots 新增快照能力,需 sidecar 支持
1.2 ControllerExpandVolume 卷在线扩展,需 external-resizer
1.5 NodeGetVolumeStats 卷用量监控,需 kubelet 支持
1.6 ControllerModifyVolume 卷参数修改,需 external-modifier
变更门禁关键点:在驱动升级时,必须检查新旧版本之间的接口差异。如果新驱动移除了某个接口或修改了参数结构,需要确保所有 sidecar 组件也同步升级,否则可能导致卷操作失败。

2.8 架构总结:三大服务的协作关系

下图展示了 Identity、Controller、Node 三大服务在 Kubernetes 集群中的部署位置与协作关系:

CSI 三大服务部署架构 控制面(Control Plane) Identity 服务 GetPluginInfo / Probe Controller 服务 CreateVolume / Publish Sidecar 组件 provisioner/attacher 数据面(Data Plane) Node 服务 NodeStage / NodePublish kubelet CSI 调用发起者 Pod 容器 卷挂载目标 gRPC