1. CSI 概述:规范发展史、生态位置与 FlexVolume 对比
Container Storage Interface(CSI)是 Kubernetes 生态中接入第三方存储系统的标准接口规范。本章从发展历程、架构定位和与旧方案对比三个维度,帮助开发者建立对 CSI 的全局认知。
1.1 CSI 规范发展史
CSI 由 Kubernetes、Mesos、Docker 等社区联合制定,旨在统一容器编排平台的存储接入协议。其发展关键节点如下:
| 版本 | 发布时间 | 核心变化 |
|---|---|---|
| CSI 0.0 | 2017 年 3 月 | 社区提出草案,定义基础 RPC 接口 |
| CSI 0.1 | 2017 年 6 月 | 引入 NodePublish/NodeUnpublish 卷挂载原语 |
| CSI 0.2 | 2017 年 9 月 | 增加 ControllerPublish/ControllerUnpublish 接口 |
| CSI 0.3 | 2017 年 12 月 | 完善快照、拓扑、卷扩容能力 |
| CSI 1.0 | 2018 年 10 月 | GA 发布,成为 CNCF 孵化项目 |
| CSI 1.1+ | 2019 年至今 | 持续迭代,增加卷组、卷迁移、卷健康等特性 |
关键里程碑:CSI 1.0 的发布标志着容器存储接口从社区实验走向生产就绪。Kubernetes 1.13 开始默认启用 CSI 功能,并逐步弃用内置 in-tree 存储插件。
1.2 CSI 在 Kubernetes 生态中的位置
CSI 位于 Kubernetes 控制平面与外部存储系统之间,作为标准化的“中间层”解耦存储厂商与编排平台。其核心组件与交互关系如下图所示:
CSI 在 Kubernetes 生态中承担以下职责:
- 标准化接口:定义 Identity、Controller、Node 三组 gRPC 服务,覆盖卷生命周期管理。
- 解耦存储厂商:存储厂商只需实现 CSI 规范,无需修改 Kubernetes 核心代码。
- Sidecar 模式:Kubernetes 社区提供通用 Sidecar 容器(如 external-provisioner),降低驱动开发成本。
- 数据平面独立:卷挂载、格式化等操作在节点本地执行,不依赖控制平面。
1.3 CSI 与 FlexVolume 对比
FlexVolume 是 Kubernetes 早期提供的存储扩展机制,通过可执行文件(如 /usr/libexec/kubernetes/kubelet-plugins/volume/exec/)实现卷操作。CSI 作为其继任者,在架构、安全、功能等方面有显著优势。两者对比如下:
| 对比维度 | FlexVolume | CSI |
|---|---|---|
| 接口形式 | 可执行文件(JSON stdout) | gRPC 服务(protobuf) |
| 部署方式 | 节点级二进制文件 | DaemonSet + Sidecar 容器 |
| 卷生命周期 | 仅支持挂载/卸载 | 创建、删除、挂载、快照、扩容、克隆 |
| 拓扑感知 | 不支持 | 原生支持(AccessibleTopology) |
| 安全模型 | 以 root 运行,无隔离 | 容器化,最小权限原则 |
| 错误处理 | 返回码 + 字符串 | gRPC 状态码 + 详细错误 |
| 社区维护 | 已冻结(K8s 1.25+ 弃用) | 活跃演进(CNCF 孵化项目) |
迁移建议:对于仍在运行 FlexVolume 驱动的集群,建议尽快迁移至 CSI。Kubernetes 1.25 已移除 FlexVolume 的 in-tree 代码,但通过 CSI 迁移机制(CSIMigration)可平滑过渡。
1.4 为什么选择 CSI 开发自定义存储驱动
从 FlexVolume 到 CSI 的演进,本质上是容器存储接口从“脚本化”走向“服务化”的过程。选择 CSI 开发自定义存储驱动,具备以下优势:
- 接口完备:CSI 定义了 20+ RPC 方法,覆盖卷的完整生命周期,包括创建、删除、挂载、卸载、快照、扩容、拓扑调度等。
- 容器化部署:驱动以容器形式运行,便于版本管理、资源隔离和灰度发布。
- 社区生态:Kubernetes 社区提供 Sidecar 容器(如 external-provisioner、external-attacher),开发者只需关注核心存储逻辑。
- 生产就绪:CSI 驱动已在 AWS、GCP、Azure、Ceph、NFS 等主流存储系统中验证,稳定性有保障。