3、CSI架构详解:CSI规范、Node Plugin与Controller Plugin职责

Container Storage Interface(CSI)是 Kubernetes 与存储系统之间的标准接口规范。理解 CSI 架构是进行卷挂载参数调优和性能基准测试的前提。本节将深入剖析 CSI 规范的核心理念,并详细拆解 Node Plugin 与 Controller Plugin 的职责边界。

3.1 CSI 规范概述

CSI 规范定义了一组 gRPC 接口,使得存储供应商(如 EBS、Ceph、NFS)只需实现一个插件,即可被任何支持 CSI 的容器编排系统(Kubernetes、Mesos、Nomad)调用。其核心设计原则是解耦控制面与数据面:

  • 控制面(Controller):负责卷的创建、删除、快照、扩容等生命周期管理操作,通常运行在 Kubernetes 控制节点上。
  • 数据面(Node):负责将卷挂载到具体的工作节点,并暴露给 Pod 使用,运行在每个工作节点上。

CSI 规范将插件拆分为三个核心组件,其中两个是本节重点:

组件 身份标识 部署位置 核心职责
Controller Plugin CSI 控制器服务 控制平面(通常以 Deployment 运行) 卷生命周期管理(创建/删除/快照/扩容)、卷拓扑感知
Node Plugin CSI 节点服务 每个工作节点(以 DaemonSet 运行) 卷挂载/卸载、设备格式化、Stage/Publish 操作
Identity Plugin CSI 身份服务 随 Controller 或 Node 部署 插件信息查询、能力宣告(如是否支持卷扩容)
关键概念: CSI 规范中,Controller Plugin 和 Node Plugin 通过 gRPC 协议与 Kubernetes 的 external-provisioner 和 node-driver-registrar 等 sidecar 容器通信,而非直接与 kubelet 交互。

3.2 Controller Plugin 职责详解

Controller Plugin 是存储系统的大脑,负责所有不涉及具体节点挂载路径的操作。它通常以 Deployment 形式部署,并具备高可用性。

3.2.1 核心 RPC 接口

Controller Plugin 必须实现以下关键 gRPC 方法:

  • CreateVolume:在存储后端创建指定大小的卷,并返回卷 ID 和属性。
  • DeleteVolume:根据卷 ID 删除存储后端的卷。
  • ControllerPublishVolume:将卷附加(Attach)到指定节点。对于块存储(如 EBS),这一步对应云 API 的 AttachVolume 操作。
  • ControllerUnpublishVolume:将卷从节点上分离(Detach)。
  • CreateSnapshot / DeleteSnapshot:创建和删除卷快照。
  • ControllerExpandVolume:在线扩容卷(需 Identity Plugin 宣告支持)。

3.2.2 职责边界

职责 说明 性能影响
卷创建/删除 调用存储后端 API 分配或释放存储空间 高延迟操作,通常涉及网络 IO 和存储分配
卷附加/分离 将块设备映射到指定节点的操作系统 影响 Pod 调度延迟,是调优重点之一
卷拓扑管理 确保卷创建在 Pod 所在可用区(如 AWS AZ) 影响调度成功率,不直接影响 IO 性能
快照管理 创建时间点拷贝,用于备份或恢复 快照创建期间可能影响卷 IO 性能
调优提示: Controller Plugin 的 ControllerPublishVolume 操作是卷挂载路径中的关键瓶颈。如果存储后端 API 响应慢,会导致 Pod 启动延迟。建议监控该操作的 P99 延迟,并考虑使用异步附加模式(如果存储支持)。

3.3 Node Plugin 职责详解

Node Plugin 是存储系统的双手,负责在具体的工作节点上执行卷的挂载、格式化、卸载等底层操作。它以 DaemonSet 形式运行在每个节点上,确保 kubelet 可以调用本地 CSI 节点服务。

3.3.1 核心 RPC 接口

  • NodeStageVolume:在节点上执行卷的全局挂载(Stage)。对于块设备,这一步通常包括:格式化(如果未格式化)、挂载到全局 staging 路径(如 /var/lib/kubelet/plugins/kubernetes.io/csi/pv/<volume-id>/globalmount)。
  • NodeUnstageVolume:卸载全局 staging 路径。
  • NodePublishVolume:将卷从 staging 路径绑定挂载到 Pod 的容器路径。这一步创建最终的挂载点,并应用挂载参数(如 mountOptions)。
  • NodeUnpublishVolume:卸载 Pod 路径的绑定挂载。
  • NodeGetVolumeStats:返回卷的容量使用情况(已用/可用空间)。

3.3.2 职责边界

职责 说明 性能影响
设备格式化 在 NodeStageVolume 中执行 mkfs 操作 格式化大容量卷(如数 TB)耗时较长
全局挂载(Stage) 将块设备挂载到节点级 staging 目录 影响 Pod 启动时间,但通常较快
绑定挂载(Publish) 将 staging 路径绑定到 Pod 的容器路径 极快,主要受 mount 系统调用影响
挂载参数应用 应用 mountOptions(如 noatime, nodelalloc) 直接影响运行时 IO 性能,是调优核心
常见误区: 很多工程师误以为挂载参数调优只需修改 StorageClass 的 mountOptions 即可。实际上,Node Plugin 的 NodeStageVolume 和 NodePublishVolume 实现中,可能硬编码了某些参数,或者忽略了用户传入的参数。必须验证 CSI 驱动是否真正透传了挂载选项。

3.4 CSI 架构总览图

下图展示了 CSI 架构中 Controller Plugin 与 Node Plugin 的协作关系,以及它们与 Kubernetes 核心组件(kubelet、external-provisioner、external-attacher)的交互流程:

CSI 架构总览:Controller Plugin 与 Node Plugin 协作 CSI 架构总览:Controller Plugin 与 Node Plugin 协作 Kubernetes 控制面 API Server external-provisioner external-attacher Controller Plugin (Deployment) 存储后端 工作节点 (Node) kubelet node-driver-registrar Node Plugin (DaemonSet) 节点级存储 Pod 挂载路径 Watch PVC/PV gRPC 通信(卷拓扑/状态) 数据路径(网络/FC/iSCSI) Controller Plugin Node Plugin Sidecar 容器 存储后端/节点存储

3.5 卷挂载流程:Controller 与 Node 的协作

一个完整的卷挂载流程(从 PVC 创建到 Pod 使用)涉及 Controller Plugin 和 Node Plugin 的紧密协作。以下是标准流程:

  1. 卷创建(Controller):external-provisioner 监听到 PVC 创建,调用 Controller Plugin 的 CreateVolume 在存储后端创建卷。
  2. 卷附加(Controller):external-attacher 监听到 PV 与 Pod 的调度绑定,调用 Controller Plugin 的 ControllerPublishVolume 将卷附加到目标节点。
  3. 节点阶段挂载(Node):kubelet 调用 Node Plugin 的 NodeStageVolume,在节点上格式化并挂载卷到全局 staging 路径。
  4. 节点发布挂载(Node):kubelet 调用 Node Plugin 的 NodePublishVolume,将卷从 staging 路径绑定挂载到 Pod 的容器路径,并应用挂载参数。
性能基准测试关注点: 步骤 2(ControllerPublishVolume)和步骤 3(NodeStageVolume)是卷挂载延迟的主要贡献者。步骤 4(NodePublishVolume)虽然快,但挂载参数(如 noatime、data=ordered)在此步骤生效,直接影响后续 IO 性能。

3.6 职责对比总结

维度 Controller Plugin Node Plugin
部署模式 Deployment(通常 1-3 副本) DaemonSet(每个节点 1 副本)
核心操作 Create/Delete/Attach/Detach/Snapshot Stage/Unstage/Publish/Unpublish
与存储后端交互 通过管理 API(如 AWS SDK、Ceph mgr) 通过数据路径(如 iSCSI、NFS 客户端)
性能敏感度 影响 Pod 调度和卷创建延迟 影响 Pod 启动延迟和运行时 IO 性能
挂载参数控制 不直接控制挂载参数 在 NodePublishVolume 中应用挂载参数
故障域 控制面故障影响所有卷操作 单节点故障仅影响该节点 Pod
学习路径建议: 在后续章节中,我们将重点围绕 Node Plugin 的 NodePublishVolume 进行挂载参数调优实验,并使用 fio 等工具对 Controller Plugin 的附加延迟和 Node Plugin 的挂载延迟进行基准测试。理解本节架构是后续所有调优操作的基础。