2. CSI 架构总览:三大核心组件及其职责

Container Storage Interface (CSI) 是 Kubernetes 与外部存储系统之间的标准插件接口。理解 CSI 的架构是进行多集群存储调优的基础。CSI 规范将存储插件的职责拆分为三个独立的组件:Controller Plugin、Node Plugin 和 Sidecar Container。这种解耦设计使得存储插件的开发、部署和升级更加灵活,且不影响集群核心组件。

架构设计原则: CSI 遵循“控制面与数据面分离”的原则。Controller Plugin 处理控制面操作(如创建/删除卷),Node Plugin 处理数据面操作(如挂载/卸载卷),Sidecar Container 则负责将 CSI 接口与 Kubernetes 原生 API 对象(如 PersistentVolumeClaim)进行桥接。

2.1 三大核心组件职责对比

组件 部署位置 核心 gRPC 服务 主要职责 生命周期
Controller Plugin 任意节点(通常作为 Deployment 运行) ControllerServer 卷的创建/删除、快照、克隆、扩容、发布/取消发布到节点 集群级别,全局唯一或少量副本
Node Plugin 每个工作节点(作为 DaemonSet 运行) NodeServer 卷的挂载/卸载、格式化、分区、设备发现、节点级统计 节点级别,每节点一个实例
Sidecar Container 与 Controller/Node Plugin 同 Pod 无(调用 Kubernetes API) 监听 Kubernetes 资源事件、调用 CSI 驱动、管理卷生命周期 与主容器同生命周期

2.2 Controller Plugin:控制面的核心

Controller Plugin 负责所有不需要直接访问节点存储设备的操作。它通常以 Deployment 形式部署,具有集群范围的视图。其核心接口定义在 csi.ControllerServer gRPC 服务中。

  • 卷管理: CreateVolume / DeleteVolume — 在后端存储系统(如 Ceph、NFS、云盘)上实际分配或释放存储资源。
  • 卷发布: ControllerPublishVolume / ControllerUnpublishVolume — 将卷附加(attach)到指定节点,使节点能够访问该卷。
  • 快照与克隆: CreateSnapshot / DeleteSnapshot / CreateVolumeFromSnapshot — 支持数据保护与快速恢复。
  • 容量感知: GetCapacity — 返回存储池的剩余容量,供调度器做容量感知调度。
调优关注点: Controller Plugin 是存储操作的“瓶颈点”。在多集群场景下,如果 Controller Plugin 处理 CreateVolume 请求过慢,会导致 Pod 调度阻塞。建议为 Controller Plugin 配置独立的资源配额(CPU/Memory),并启用 gRPC 连接池复用。

2.3 Node Plugin:数据面的执行者

Node Plugin 运行在每个工作节点上,以 DaemonSet 形式部署。它负责将卷实际挂载到 Pod 的文件系统路径中。其核心接口定义在 csi.NodeServer gRPC 服务中。

  • 节点级卷操作: NodePublishVolume / NodeUnpublishVolume — 执行实际的 mount 操作,将块设备或文件系统挂载到目标路径。
  • 阶段挂载: NodeStageVolume / NodeUnstageVolume — 在全局命名空间(如 /var/lib/kubelet/plugins/)中准备卷,然后进行发布。
  • 节点状态: NodeGetCapabilities / NodeGetInfo — 返回节点支持的卷类型、最大挂载数、拓扑信息等。
  • 卷统计: NodeGetVolumeStats — 提供卷的已用空间、inode 使用量等指标,用于 kubectl top 和 HPA。
常见陷阱: Node Plugin 的 NodePublishVolume 调用是同步的,如果挂载操作超时(默认 30 秒),Kubelet 会重试并可能导致 Pod 启动延迟。务必确保 Node Plugin 的挂载逻辑高效,且后端存储的挂载路径无 I/O 阻塞。

2.4 Sidecar Container:Kubernetes 与 CSI 的桥梁

Sidecar Container 是 Kubernetes CSI 架构中特有的组件。它并不是 CSI 规范的一部分,而是 Kubernetes 社区提供的一组辅助容器,用于将 CSI 驱动与 Kubernetes 原生资源对象(如 PersistentVolumeClaim、VolumeAttachment)进行联动。

常见的 Sidecar 容器包括:

Sidecar 名称 监听资源 调用的 CSI 方法 核心功能
csi-provisioner PersistentVolumeClaim CreateVolume / DeleteVolume 自动创建/删除 PersistentVolume
csi-attacher VolumeAttachment ControllerPublishVolume / ControllerUnpublishVolume 将卷附加/分离到节点
csi-resizer PersistentVolumeClaim (修改容量) ControllerExpandVolume 在线扩容卷
csi-snapshotter VolumeSnapshot / VolumeSnapshotContent CreateSnapshot / DeleteSnapshot 创建/删除卷快照
csi-node-driver-registrar 无(通过 Unix Socket 注册) NodeGetInfo 向 Kubelet 注册 Node Plugin 的 Unix Socket 路径

2.5 组件交互流程与架构图

下图展示了 CSI 三大组件在 Kubernetes 集群中的部署位置与交互关系。Controller Plugin 与 Sidecar 容器运行在同一个 Pod 中(通常作为 Deployment),Node Plugin 与 csi-node-driver-registrar 运行在另一个 Pod 中(作为 DaemonSet)。

CSI 三大核心组件架构图 CSI 三大核心组件架构与交互 Kubernetes Master API Server Scheduler Controller Manager (监听 PVC/VolumeAttachment) Controller Plugin Pod csi-provisioner csi-attacher csi-resizer Controller Plugin 存储后端 Ceph / NFS / 云盘 iSCSI / FC / NVMe-oF (实际存储介质) 监听 PVC CreateVolume Node Plugin Pod (DaemonSet) csi-node-driver-registrar Node Plugin (每节点一个实例) Kubelet (节点代理) Pod 生命周期管理 卷挂载/卸载调度 (调用 Node Plugin) NodePublishVolume 挂载/格式化操作 架构要点: 1. Controller Plugin 与 Sidecar 容器同 Pod,通过 localhost gRPC 通信。 2. Node Plugin 通过 Unix Socket 与 Kubelet 通信,Socket 路径由 csi-node-driver-registrar 注册。 3. 存储后端可以是集中式(如 Ceph)或分布式(如每个节点本地 NVMe),CSI 屏蔽了底层差异。

2.6 接口调用流程示例

以创建一个 PVC 并挂载到 Pod 为例,三大组件的完整调用链如下:

  1. 用户创建 PVC → API Server 写入 etcd。
  2. csi-provisioner (Sidecar) 监听到 PVC 事件,调用 Controller Plugin 的 CreateVolume gRPC 方法。
  3. Controller Plugin 向存储后端发送创建卷请求,返回卷 ID 和属性。
  4. csi-provisioner 创建 PersistentVolume 对象,绑定到 PVC。
  5. 调度器 将 Pod 调度到某个节点,创建 VolumeAttachment 对象。
  6. csi-attacher (Sidecar) 监听到 VolumeAttachment,调用 ControllerPublishVolume 将卷附加到节点。
  7. Kubelet 在节点上调用 Node Plugin 的 NodeStageVolume 和 NodePublishVolume,完成最终挂载。
性能关键路径: 步骤 2-3 和步骤 6-7 是延迟敏感路径。在多集群场景下,如果 Controller Plugin 部署在集群 A 而存储后端在集群 B,网络延迟会显著增加 CreateVolume 和 ControllerPublishVolume 的耗时。建议将 Controller Plugin 部署在离存储后端最近的集群中,或使用 gRPC 长连接减少握手开销。

2.7 多集群环境下的组件部署策略

组件 单集群部署 多集群部署(推荐) 说明
Controller Plugin 1 个 Deployment,1-2 副本 每个集群独立部署,或集中部署在管理集群 集中部署可减少存储后端连接数,但增加网络延迟
Node Plugin DaemonSet,每节点 1 个 每个集群的每个节点独立部署 必须本地部署,因为挂载操作需要访问节点设备
Sidecar Container 与 Controller/Node Plugin 同 Pod 与 Controller/Node Plugin 同 Pod 部署策略跟随主容器
最佳实践: 在跨集群存储场景中,建议将 Controller Plugin 部署在“存储管理集群”中,该集群与存储后端网络延迟最低。工作负载集群只运行 Node Plugin,通过 VolumeAttachment 的拓扑约束确保卷被附加到正确的节点。