1. CSI 架构总览:规范发展史、Kubernetes 存储架构演进与驱动生命周期

1.1 从 in-tree 到 out-of-tree:Kubernetes 存储架构的两次跃迁

Kubernetes 存储架构经历了从“内置驱动”到“FlexVolume 插件”,再到“CSI 标准接口”的演进。理解这一过程,是掌握 CSI 驱动变更门禁的基础。

阶段 代表版本 核心机制 运维痛点
In-tree 时代 v1.0 – v1.12 存储驱动代码直接编译进 kube-controller-manager 和 kubelet 驱动 Bug 导致控制面崩溃;升级驱动必须升级集群;厂商代码合入周期长
FlexVolume 过渡 v1.2 – v1.15 通过 kubelet 插件目录调用外部可执行文件(flexvol) 仅支持 attach/detach/mount/unmount;无卷快照、扩容等能力;依赖宿主机文件系统
CSI 标准时代 v1.13+(GA) 容器化 sidecar 组件 + gRPC 接口,完全解耦核心组件 运维复杂度转移到驱动部署与参数调优;变更门禁成为刚需
关键认知: CSI 不是一种存储实现,而是一个接口契约。它定义了存储提供商(SP)与 Kubernetes 之间的通信协议,使得任何符合 CSI 规范的驱动都可以被 Kubernetes 原生调度。

1.2 CSI 规范发展史:从 v0.1 到 v1.x 的里程碑

CSI 规范由 Kubernetes、Mesos、Cloud Foundry 等社区联合制定,目前由 CNCF SIG Storage 维护。以下为关键版本节点:

  • v0.1(2017.12):初始草案,定义 Identity、Controller、Node 三大 gRPC 服务。
  • v0.2(2018.03):引入 NodeStageVolume 和 NodePublishVolume 分离,支持多路径挂载。
  • v1.0(2018.10):GA 版本,Kubernetes v1.13 正式集成 CSI 作为 alpha 特性。
  • v1.1(2019.03):增加 VolumeStats 和 ExpandVolume 能力。
  • v1.5(2021.04):引入 VolumeGroupSnapshot 和 ReadWriteOncePod 访问模式。
  • v1.9(2023.10):增加 MountOptions 参数校验与 NodeGetVolumeStats 增强。
实践建议: 在 CSI 驱动变更门禁中,应至少要求驱动支持 CSI v1.5+,以确保卷组快照和单 Pod 独占读写(RWO Pod)等关键特性可用。

1.3 CSI 驱动在 Kubernetes 中的角色与组件架构

一个完整的 CSI 驱动由三个核心 gRPC 服务和一组 Kubernetes sidecar 容器组成。下图展示了驱动在集群中的部署拓扑:

CSI 驱动组件架构与 Kubernetes 集成关系 CSI 驱动组件架构与 Kubernetes 集成关系 Kubernetes 控制面 kube-controller-manager kube-scheduler API Server CSI Sidecar 容器(Pod 内) external-provisioner external-attacher external-resizer external-snapshotter node-driver-registrar CSI Driver 容器 Identity 服务 Controller 服务 Node 服务 Watch / Informer gRPC (Unix Socket) Node 节点(kubelet) NodePublishVolume / NodeUnpublishVolume 挂载传播 注册 / 健康检查 架构要点 1. Sidecar 容器负责与 Kubernetes API 交互,Driver 容器只实现存储逻辑,职责分离。 2. 所有 gRPC 通信通过 Unix Domain Socket 在 Pod 内部完成,不经过网络。

1.4 CSI 驱动的生命周期:从注册到销毁

CSI 驱动在 Kubernetes 集群中的完整生命周期包含以下阶段:

  1. 注册(Registration):node-driver-registrar sidecar 通过 NodeGetInfo RPC 获取驱动信息,并向 kubelet 注册 Unix Socket 路径。
  2. 探测(Probe):kubelet 定期调用 Probe RPC 检查驱动健康状态,若连续失败则标记驱动不可用。
  3. 卷创建(Provision):external-provisioner 监听 PersistentVolumeClaim 创建事件,调用 CreateVolume RPC。
  4. 卷挂载(Attach & Mount):external-attacher 调用 ControllerPublishVolume;kubelet 调用 NodeStageVolume 和 NodePublishVolume。
  5. 卷扩容(Expand):external-resizer 监听 PVC 扩容请求,调用 ControllerExpandVolume 和 NodeExpandVolume。
  6. 卷快照(Snapshot):external-snapshotter 调用 CreateSnapshot / DeleteSnapshot。
  7. 卷销毁(Teardown):kubelet 调用 NodeUnpublishVolume → NodeUnstageVolume → ControllerUnpublishVolume → DeleteVolume。
变更门禁关注点: 在驱动升级或参数调优时,Probe 和 NodeGetInfo 的响应变化会直接影响 kubelet 的调度决策。建议在门禁中增加对这两个 RPC 返回值的差异对比,防止因驱动版本变更导致节点存储拓扑标签丢失。

1.5 关键 RPC 接口与参数调优映射

CSI 规范定义了三个服务共 15+ 个 RPC。以下列出与卷挂载参数调优最相关的接口:

服务 RPC 名称 关键参数 调优影响
Identity Probe ready 字段 驱动健康状态,影响 kubelet 是否继续调用后续 RPC
Controller CreateVolume capacity_range, parameters 卷大小、IOPS、吞吐量等 QoS 参数
Controller ControllerPublishVolume node_id, volume_context 节点亲和性、多路径配置
Node NodeStageVolume staging_target_path, mount_flags 文件系统挂载选项(如 noatime, data=ordered)
Node NodePublishVolume target_path, readonly, mount_flags Pod 内挂载点参数,直接影响应用 IO 性能
Node NodeGetVolumeStats volume_id, volume_path 卷容量和 inode 使用量,用于监控与告警
门禁策略示例: 在 CSI 驱动变更时,自动对比新旧版本的 NodeStageVolume 中 mount_flags 的默认值。若新增了 noexec 或 nosuid 等安全选项,需触发人工审批,防止影响已有应用的挂载行为。

1.6 本章小结

  • Kubernetes 存储架构从 in-tree 演进到 CSI,实现了驱动与核心组件的完全解耦。
  • CSI 规范 v1.5+ 提供了卷组快照、RWO Pod 等关键能力,是驱动变更门禁的最低版本要求。
  • CSI 驱动由 Sidecar 容器 + Driver 容器 组成,通过 gRPC 和 Unix Socket 通信,职责清晰。
  • 驱动生命周期包含注册、探测、卷创建、挂载、扩容、快照、销毁七个阶段,其中 Probe 和 NodeGetInfo 是变更门禁的第一道防线。
  • 挂载参数调优的核心 RPC 是 NodeStageVolume 和 NodePublishVolume,门禁系统应重点监控其 mount_flags 变化。