1. CSI 架构总览:规范演进、核心组件与集成原理

Container Storage Interface(CSI)是 Kubernetes 生态中接入外部存储系统的标准协议。本章从规范演进、核心组件职责、与 Kubernetes 的集成原理三个维度,建立 CSI 架构的整体认知。

1.1 CSI 规范演进历史

CSI 规范由 Kubernetes SIG-Storage 与 CNCF 社区共同推动,旨在终结各存储厂商各自为战的 in-tree 插件模式。下表梳理了关键里程碑:

版本 发布时间 核心变化
CSI 0.0 2017.03 社区提出 CSI 概念,定义 gRPC 接口雏形
CSI 0.1 2017.06 发布首个 Alpha 草案,包含 Identity/Controller/Node 三大 RPC 组
CSI 0.2 2017.09 引入 VolumeCapability、MountOptions 等关键字段
CSI 1.0 2018.04 正式 GA,Kubernetes 1.10 开始 Alpha 集成
CSI 1.1 2018.07 增加 Volume Expansion(扩容)支持
CSI 1.2 2018.10 引入 Volume Snapshot(快照)基础接口
CSI 1.3 2019.03 增加 Topology(拓扑感知调度)能力
CSI 1.5 2020.01 完善 Volume Group Snapshot、Volume Clone
CSI 1.6+ 2021+ 持续优化:Secrets 管理、NodeStage 细化、多平台支持
关键趋势:CSI 从 1.0 到 1.6+ 的演进,核心围绕“功能完备性”与“生产稳定性”两条主线。Kubernetes 自 1.13 起将 CSI 作为存储插件默认集成方式,in-tree 插件逐步冻结。

1.2 核心组件职责

CSI 规范将存储插件拆分为三个独立的 gRPC 服务(Service),每个服务运行在独立的容器中,通过 Unix Domain Socket 或 TCP 通信。三者职责严格分离:

组件 部署位置 核心 RPC 接口 职责说明
Identity Service 与 Controller/Node 同 Pod GetPluginInfo, GetPluginCapabilities, Probe 插件身份声明、能力通告、健康检查
Controller Service 控制面(通常为 Deployment) CreateVolume, DeleteVolume, ControllerPublishVolume, CreateSnapshot, ListVolumes 等 存储资源生命周期管理(创建/删除/挂载/快照/扩容)
Node Service 每个工作节点(DaemonSet) NodePublishVolume, NodeUnpublishVolume, NodeStageVolume, NodeGetVolumeStats 节点级卷挂载、卸载、阶段挂载、指标采集
设计原则:Controller 与 Node 分离,使得存储控制面操作(如创建卷)与数据面操作(如挂载卷)可以独立扩缩容、独立升级,且 Controller 可以运行在任意节点上,不依赖具体工作节点。

1.3 与 Kubernetes 的集成原理

Kubernetes 通过 CSI Sidecar 容器 模式实现与 CSI 驱动的无缝集成。Sidecar 容器与 CSI 驱动容器运行在同一个 Pod 中,负责将 Kubernetes 原生 API 对象(PersistentVolumeClaim、StorageClass、VolumeAttachment)转换为 CSI gRPC 调用。

下图展示了 CSI 驱动在 Kubernetes 集群中的完整部署架构与数据流:

CSI 与 Kubernetes 集成架构图 CSI 与 Kubernetes 集成架构 Kubernetes 控制面 API Server PV / PVC / StorageClass VolumeAttachment AttachDetach Controller PV Controller Controller Pod (Deployment) CSI-Provisioner CSI-Attacher CSI-Resizer CSI-Snapshotter CSI Driver (Controller) Node Pod (DaemonSet) CSI-Node-Driver-Registrar CSI-Node-Driver-Registrar CSI Driver (Node) kubelet Watch / Informer VolumeAttachment 集成原理说明 Sidecar 容器监听 Kubernetes API 对象变化 → 调用 CSI Driver 的 gRPC 接口 → 完成存储生命周期操作 1. 用户创建 PVC 2. CSI-Provisioner 监听 3. 调用 CreateVolume 4. 返回 PV 5. Pod 调度到节点 6. kubelet 调用 NodeStage 7. kubelet 调用 NodePublish 8. 卷挂载完成

1.4 集成关键流程:从 PVC 到 Pod 挂载

一个典型的 CSI 卷从创建到挂载,经历以下核心步骤:

  1. 用户创建 PVC:指定 StorageClass,StorageClass 中引用 CSI 驱动名称(provisioner)。
  2. CSI-Provisioner Sidecar 监听:发现未绑定的 PVC,调用 CSI Driver 的 CreateVolume RPC。
  3. CSI Driver 创建存储资源:在存储后端创建卷,返回卷 ID 和属性。
  4. Kubernetes 创建 PV:将返回的卷信息绑定为 PersistentVolume 对象。
  5. Pod 调度到工作节点:kubelet 根据 VolumeAttachment 对象,调用 CSI Driver 的 ControllerPublishVolume(将卷挂载到节点)。
  6. NodeStageVolume:kubelet 调用 CSI Driver 的 NodeStageVolume,执行全局阶段挂载(如格式化、挂载到全局路径)。
  7. NodePublishVolume:kubelet 调用 NodePublishVolume,将卷绑定到 Pod 的挂载点。
  8. Pod 启动:卷就绪,Pod 开始读写。
常见误区:很多初学者认为 CSI 驱动直接与 kubelet 通信。实际上,kubelet 通过 Unix Domain Socket 与 CSI Driver 的 Node Service 通信,而 Controller Service 由 Sidecar 容器通过 gRPC 调用。两者路径不同,职责分离。

1.5 核心组件交互时序

下图以“创建并挂载卷”为例,展示 Identity、Controller、Node 三大服务在完整生命周期中的交互顺序:

CSI 三大服务交互时序图 CSI 三大服务交互时序(创建 + 挂载) Identity Controller Node Kubelet Probe 健康检查 GetCapabilities 能力通告 CreateVolume 创建卷 ControllerPublish 节点级挂载 NodeStage 阶段挂载 NodePublish Pod 挂载点 卷就绪

1.6 架构设计要点总结

维度 设计要点 生产建议
组件分离 Identity / Controller / Node 三服务独立部署,职责单一 Controller 使用 Deployment 保证高可用;Node 使用 DaemonSet 保证每节点覆盖
Sidecar 模式 Kubernetes 通过 Sidecar 容器将 API 对象转换为 CSI gRPC 调用 Sidecar 版本需与 CSI Driver 版本兼容,避免接口不匹配
通信协议 gRPC over Unix Domain Socket(本地通信,高性能) 确保 Socket 路径不冲突,使用 hostPath 卷共享
生命周期 创建 → 挂载 → 使用 → 卸载 → 删除,每个阶段有明确 RPC 对应 实现幂等性:所有 RPC 必须支持重复调用不产生副作用
错误处理 gRPC 返回标准错误码(OK/NotFound/AlreadyExists/FailedPrecondition 等) Sidecar 根据错误码决定重试或报错,避免死循环
学习路径建议:理解 CSI 架构后,下一步应深入每个 RPC 的请求/响应结构(protobuf 定义),以及 Sidecar 容器(provisioner、attacher、resizer、snapshotter)的源码逻辑。这是后续章节“多后端适配”与“性能优化”的基础。