1. CSI 架构基础:存储插件与 Kubernetes 的桥梁

Container Storage Interface (CSI) 是 Kubernetes 生态中存储插件的标准接口规范。它定义了存储系统(如 SAN、NAS、云硬盘)与容器编排平台之间的通信协议,使得存储厂商只需实现一套 CSI 驱动,即可被 Kubernetes、Mesos、Docker Swarm 等平台统一调用。本章聚焦 CSI 在 Kubernetes 中的实现,剖析其核心组件、交互流程以及与 Kubernetes 存储体系的集成关系。

1.1 CSI 规范概述

CSI 规范由 Kubernetes SIG-Storage 与存储厂商共同推动,目前已成为容器存储的事实标准。其核心设计原则包括:

  • 解耦:存储逻辑与编排平台分离,驱动独立部署。
  • 可移植:同一驱动可跨 Kubernetes、Mesos 等平台运行。
  • 声明式:通过 gRPC 接口实现卷的生命周期管理。
版本 关键特性 Kubernetes 支持版本
v0.3 基础卷管理、节点挂载 v1.10+ (Alpha)
v1.0 稳定 GA,支持拓扑感知 v1.13+ (GA)
v1.5 卷快照、卷克隆 v1.20+
v1.9 卷组快照、可恢复性增强 v1.28+
性能调优视角: CSI 规范定义了 30+ 个 gRPC 方法,其中 ControllerPublishVolume、NodeStageVolume、NodePublishVolume 是压测重点。这些方法的延迟直接决定 Pod 启动速度和卷挂载效率。

1.2 CSI 组件角色与交互流程

CSI 驱动在 Kubernetes 中由三个核心组件构成:Controller、Node、Identity。每个组件负责不同的 RPC 服务,协同完成卷的创建、挂载、卸载等操作。

1.2.1 组件角色定义

组件 部署形态 核心 RPC 方法 职责
Controller Deployment / StatefulSet CreateVolume, DeleteVolume, ControllerPublishVolume, ControllerUnpublishVolume, CreateSnapshot 管理卷的创建、删除、挂载到节点、快照等控制面操作
Node DaemonSet NodeStageVolume, NodePublishVolume, NodeUnstageVolume, NodeUnpublishVolume, NodeGetVolumeStats 在节点上执行卷的格式化、挂载、卸载、状态查询
Identity 与 Controller/Node 同进程 GetPluginInfo, GetPluginCapabilities, Probe 提供驱动元数据、能力声明、健康检查

1.2.2 交互流程:从 PVC 创建到 Pod 挂载

下图展示了 CSI 驱动在 Kubernetes 中处理一个 PVC 创建并挂载到 Pod 的完整流程:

CSI 驱动交互流程:PVC 创建 → Pod 挂载 Kubernetes API Server External Provisioner CSI Controller External Attacher Kubelet CSI Node 存储后端 ① PVC 创建 ② CreateVolume ③ 创建卷 ④ ControllerPublishVolume ⑤ NodeStageVolume ⑥ 挂载卷 说明:External Provisioner 和 External Attacher 是 Kubernetes CSI Sidecar 容器,负责监听 API Server 事件并调用 CSI 驱动。 Controller 组件通常部署在控制节点,Node 组件以 DaemonSet 运行在每个工作节点。

1.2.3 关键交互步骤详解

  1. PVC 创建:用户创建 PVC,API Server 持久化对象。
  2. Provisioner 调用 CreateVolume:External Provisioner 监听到 PVC 事件,调用 CSI Controller 的 CreateVolume 方法。
  3. Controller 创建卷:CSI Controller 与存储后端交互,创建实际存储卷。
  4. Attacher 调用 ControllerPublishVolume:Pod 调度到节点后,External Attacher 调用 ControllerPublishVolume 将卷附加到节点。
  5. Kubelet 调用 NodeStageVolume:Kubelet 调用 CSI Node 的 NodeStageVolume 方法,在节点上格式化并挂载卷到全局目录。
  6. Node 挂载卷:CSI Node 执行 NodePublishVolume,将卷绑定挂载到 Pod 的容器路径。
压测关注点: 步骤 ② 和 ④ 是控制面操作,延迟受存储后端性能影响;步骤 ⑤ 和 ⑥ 是数据面操作,涉及文件系统格式化、mount 系统调用,是节点 I/O 瓶颈的高发区。

1.3 CSI 与 Kubernetes 存储体系的关系

CSI 驱动是 Kubernetes 存储体系中的“执行层”,它与上层的存储抽象(PV、PVC、StorageClass)以及下层的存储后端紧密协作。下图展示了 CSI 在 Kubernetes 存储架构中的位置:

CSI 在 Kubernetes 存储体系中的位置 Kubernetes 存储抽象层 PVC (PersistentVolumeClaim) → PV (PersistentVolume) → StorageClass CSI 驱动层 CSI Controller (控制面) | CSI Node (数据面) | CSI Identity (元数据) Sidecar: Provisioner / Attacher / Resizer / Snapshotter / Health Monitor 存储后端层 云硬盘 (EBS/PDD) | 分布式存储 (Ceph/GlusterFS) | 本地存储 (LVM/RAID) CSI 驱动层是 Kubernetes 存储抽象与存储后端之间的适配层,通过 gRPC 协议实现标准化调用。

1.3.1 与 Kubernetes 原生存储的对比

特性 Kubernetes 原生 In-Tree 驱动 CSI 驱动 (Out-of-Tree)
部署方式 内嵌在 kube-controller-manager / kubelet 中 独立容器,通过 DaemonSet / Deployment 部署
升级影响 需升级 Kubernetes 版本 独立升级,不影响集群核心组件
存储厂商适配 需提交 Kubernetes 社区 PR,周期长 厂商自行开发,快速迭代
性能隔离 与核心组件共享资源,故障影响面大 独立资源限制,故障隔离性好
功能扩展 受 Kubernetes 版本限制 支持快照、克隆、拓扑感知等高级特性

1.3.2 CSI 与 StorageClass 的绑定

StorageClass 是 Kubernetes 中定义存储“类”的抽象,CSI 驱动通过 provisioner 字段与 StorageClass 绑定:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-csi
provisioner: csi.example.com  # 与 CSI 驱动的 Identity 服务返回的 driver name 一致
parameters:
  type: ssd
  iopsPerGB: "10"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer  # 拓扑感知延迟绑定
allowVolumeExpansion: true
性能调优陷阱: volumeBindingMode: WaitForFirstConsumer 会延迟卷创建直到 Pod 调度完成,这有助于拓扑感知调度,但会增加首次 Pod 启动延迟。在压测时需区分“卷创建延迟”和“Pod 启动延迟”。

1.4 本章小结

  • CSI 规范通过 gRPC 接口标准化了存储插件与编排平台的交互,Controller/Node/Identity 三个组件各司其职。
  • 交互流程从 PVC 创建开始,经过 Provisioner、Attacher、Kubelet 的协调,最终由 CSI Node 完成卷挂载。
  • CSI 驱动作为 Kubernetes 存储抽象与存储后端之间的适配层,相比 In-Tree 驱动具有更好的可移植性、隔离性和扩展性。
  • 理解 CSI 架构是后续进行驱动压测和故障排查的基础,尤其是控制面与数据面的延迟分布。