1. CSI 概述:定义、发展背景与核心作用
1.1 什么是 CSI?
Container Storage Interface(CSI) 是容器编排系统(如 Kubernetes)与存储系统之间的标准化插件接口。它定义了一组 gRPC 协议和 RPC 调用,使得任意存储厂商(公有云、私有云、本地存储、NFS、分布式文件系统等)只需实现一套 CSI 驱动,即可被 Kubernetes 等平台无缝集成。
核心思想:将存储实现与容器编排平台解耦,让存储插件像“即插即用”的 USB 设备一样接入 Kubernetes。
1.2 发展背景:为什么需要 CSI?
在 CSI 出现之前,Kubernetes 的存储集成存在严重问题:
- In-Tree 插件模式:所有存储驱动的代码必须合入 Kubernetes 主干仓库,导致核心代码膨胀、发布周期长、厂商升级困难。
- FlexVolume 接口:虽为外部插件提供了可执行文件调用方式,但缺乏生命周期管理、快照、扩容等高级能力,且调试困难。
- 生态碎片化:每个容器编排平台(Kubernetes、Mesos、Docker Swarm)都有自己的存储集成方式,厂商需要为每个平台重复开发。
| 对比维度 | In-Tree 插件 | FlexVolume | CSI |
|---|---|---|---|
| 代码位置 | Kubernetes 主干仓库 | 外部可执行文件 | 独立容器/进程 |
| 发布周期 | 随 Kubernetes 版本发布 | 独立发布 | 独立发布 |
| 快照/扩容支持 | 部分支持 | 不支持 | 原生支持 |
| 跨平台兼容 | 仅 Kubernetes | 仅 Kubernetes | Kubernetes / Mesos / Nomad 等 |
| 社区维护成本 | 高(需合入主干) | 中 | 低(厂商自维护) |
CSI 规范由 Kubernetes、Mesos、Docker 等社区于 2017 年共同发起,目标是从根本上解决上述问题。自 Kubernetes v1.13 起,CSI 成为 GA(General Availability)特性,并逐步取代 In-Tree 和 FlexVolume。
1.3 CSI 在 Kubernetes 生态中的核心作用
CSI 在 Kubernetes 中扮演着“存储中间层”的角色,其核心作用体现在以下四个方面:
- 标准化接入:任何存储系统只要实现 CSI 定义的
Identity、Controller、Node三组 gRPC 服务,即可被 Kubernetes 识别和管理。 - 生命周期管理:CSI 驱动负责卷的创建、挂载、格式化、快照、克隆、扩容、删除等全生命周期操作,Kubernetes 只需通过 Sidecar 容器调用 CSI 接口。
- 解耦与可插拔:存储厂商可以独立于 Kubernetes 版本发布驱动更新,用户无需等待 Kubernetes 大版本升级即可获得新存储特性。
- 生态扩展:基于 CSI,社区涌现出大量高级工具,如
csi-snapshotter(快照)、csi-resizer(在线扩容)、csi-attacher(挂载管理)等。
一句话总结:CSI 让 Kubernetes 的存储能力从“内置有限驱动”进化为“无限可扩展的存储市场”,是云原生存储生态的基石。
1.4 CSI 架构总览
下图展示了 CSI 在 Kubernetes 中的整体架构,包含三个核心组件:CSI Controller(控制面)、CSI Node(数据面)以及 Sidecar 容器(Kubernetes 与 CSI 驱动的桥梁)。
1.5 CSI 的核心接口与组件
CSI 规范定义了三个核心 gRPC 服务,每个服务包含一组 RPC 方法:
| 服务名称 | 部署位置 | 关键 RPC 方法 | 功能描述 |
|---|---|---|---|
| Identity | Controller / Node | GetPluginInfo, Probe, GetPluginCapabilities |
插件身份识别、健康检查、能力声明 |
| Controller | Controller 节点 | CreateVolume, DeleteVolume, ControllerPublishVolume, CreateSnapshot, ExpandVolume |
卷的创建/删除、挂载/卸载、快照、扩容等控制面操作 |
| Node | 每个工作节点 | NodePublishVolume, NodeUnpublishVolume, NodeGetCapabilities, NodeGetVolumeStats |
卷在工作节点上的挂载/卸载、状态查询 |
注意:Controller 服务通常运行在集群中的任意一个节点(或独立 Pod),而 Node 服务必须运行在每个需要挂载存储的工作节点上。这种分离设计使得控制面操作(如创建卷)与数据面操作(如挂载卷)可以独立扩展。
1.6 CSI 与 Kubernetes 的集成方式
Kubernetes 通过一组 Sidecar 容器 与 CSI 驱动交互,这些 Sidecar 负责将 Kubernetes 原生资源(如 PVC、StorageClass)转换为 CSI gRPC 调用:
- csi-provisioner:监听
PersistentVolumeClaim创建事件,调用CreateVolume创建后端卷。 - csi-attacher:监听
VolumeAttachment资源,调用ControllerPublishVolume将卷挂载到节点。 - csi-snapshotter:监听
VolumeSnapshot资源,调用CreateSnapshot创建快照。 - csi-resizer:监听 PVC 扩容请求,调用
ExpandVolume扩展卷大小。 - csi-node-driver-registrar:向 Kubelet 注册 CSI Node 驱动,建立 Unix Socket 通信。
这种 Sidecar 模式使得 CSI 驱动本身只需关注存储操作逻辑,无需关心 Kubernetes 资源监听、重试、状态更新等复杂逻辑,大幅降低了驱动开发门槛。