系列导航
本系列从 K8s 存储模型入手,逐步展开到 CSI 插件实现与云原生存储全景。
① 概念 → ② Volume 生命周期 → ③ CSI 架构 → ④ FlexVolume 演进 → ⑤ 对比 → ⑥ 排障 ‖ ⑦ 开发 → ⑧ 高级特性 → ⑨ 演进展望
| 顺序 | 文章 | 定位 |
|---|---|---|
| ① | 概念与入门 | 基础——K8s 存储模型、PV/PVC/StorageClass、Volume 分类树 |
| ② | Volume 生命周期全解析 | 全貌——两阶段处理、动态/静态供应 |
| ③ | 本篇 - CSI 架构详解 | 标准——gRPC 三服务、Sidecar 模式、External Components |
| ④ | FlexVolume 与 CSI 演进 | 演进——FlexVolume 原理、CSI 设计思想 |
| ⑤ | 存储方案对比与选型 | 选型——主流 CSI 插件横向对比 + 决策树 |
| ⑥ | 排障思路与常用命令 | 运维——工具链 + 场景排查 + 性能 |
| — | 核心路径 ↑ | 扩展展望 ↓ |
| ⑦ | CSI 插件开发指南 | 扩展——从零开发一个 CSI 插件 |
| ⑧ | 高级特性详解 | 进阶——快照、克隆、扩容、拓扑感知 |
| ⑨ | 云原生存储演进与展望 | 展望——容器原生存储、DPU 卸载、未来方向 |
重要
CSI(Container Storage Interface)是跨容器编排器的存储接口标准。核心设计:用 gRPC 定义三组服务(Identity / Controller / Node),通过 Sidecar 模式与 K8s 解耦,使存储插件独立于 K8s 主版本发布和升级。
1. CSI 是什么
CSI 是由 Kubernetes、Mesos、Cloud Foundry 联合制定的容器存储接口标准。它定义了一套 gRPC 接口,存储厂商只需实现一次,即可适配所有容器编排平台。
| 维度 | CNI(网络) | CSI(存储) |
|---|---|---|
| 接口形式 | 可执行文件 + 环境变量 + stdin/stdout | gRPC |
| 调用方 | kubelet 直接 fork | kubelet + Sidecar 组件 |
| 生命周期 | Pod 创建/销毁 | Volume 创建/删除/挂载/卸载/快照/扩容 |
| 插件部署 | 二进制 + DaemonSet | 容器化(Deployment + DaemonSet) |
2. 三组 gRPC 服务
CSI 规范定义了三组服务,分别处理不同层级的操作:
2.1 Identity Service(身份服务)
| 接口 | 说明 |
|---|---|
GetPluginInfo | 返回插件名称和版本 |
GetPluginCapabilities | 返回插件支持的能力(Controller 服务、Topology) |
Probe | 健康检查 |
Identity Service 由 CSI 插件本身实现,无论是 Controller 还是 Node 组件都需要响应。
2.2 Controller Service(控制器服务)
在集群级别运行(Deployment),负责 Volume 的创建、删除、挂接/卸接:
| 接口 | 说明 | 触发方 |
|---|---|---|
CreateVolume | 创建底层存储资源 | external-provisioner |
DeleteVolume | 删除底层存储资源 | external-provisioner |
ControllerPublishVolume | Attach:将存储挂接到节点 | external-attacher |
ControllerUnpublishVolume | Detach:从节点卸接存储 | external-attacher |
ControllerExpandVolume | 在线扩容底层存储 | external-resizer |
CreateSnapshot | 创建快照 | external-snapshotter |
DeleteSnapshot | 删除快照 | external-snapshotter |
2.3 Node Service(节点服务)
在每个节点上运行(DaemonSet),负责 Volume 的挂载/卸载:
| 接口 | 说明 | 触发方 |
|---|---|---|
NodeStageVolume | 将块设备格式化并挂载到全局目录 | kubelet |
NodeUnstageVolume | 从全局目录卸载 | kubelet |
NodePublishVolume | bind mount 到 Pod 容器目录 | kubelet |
NodeUnpublishVolume | 从 Pod 容器目录卸载 | kubelet |
NodeExpandVolume | 扩容文件系统 | kubelet |
NodeGetCapabilities | 返回 Node 服务能力 | kubelet |
Controller Service 管的是"存储资源"(创建/删除/Attach),Node Service 管的是"节点上的挂载"(Stage/Publish/Mount)。两阶段处理 = ControllerPublish(Attach)+ NodeStage+NodePublish(Mount)。
3. Sidecar 模式
CSI 插件不直接与 K8s API 交互。K8s 社区提供了一组 External Components(Sidecar),负责监听 K8s API 并调用 CSI gRPC 接口:
K8s API Server ↓ 监听 PVC/VolumeAttachment/VolumeSnapshot 等 CRD External Components(Sidecar) ├── external-provisioner → 监听 PVC,调 CreateVolume/DeleteVolume ├── external-attacher → 监听 VolumeAttachment,调 ControllerPublish/Unpublish ├── external-snapshotter → 监听 VolumeSnapshot,调 CreateSnapshot/DeleteSnapshot ├── external-resizer → 监听 PVC 扩容请求,调 ControllerExpandVolume └── node-driver-registrar → 向 kubelet 注册 CSI 插件 ↓ gRPC CSI Plugin(Identity + Controller + Node) ↓ 底层存储(Ceph / NFS / 云盘 / ...)
3.1 各 Sidecar 职责
| Sidecar | 监听对象 | 调用 CSI 接口 | 部署位置 |
|---|---|---|---|
| external-provisioner | PVC | CreateVolume / DeleteVolume | Controller Pod |
| external-attacher | VolumeAttachment | ControllerPublish / Unpublish | Controller Pod |
| external-snapshotter | VolumeSnapshot | CreateSnapshot / DeleteSnapshot | Controller Pod |
| external-resizer | PVC(容量变更) | ControllerExpandVolume | Controller Pod |
| node-driver-registrar | kubelet 注册 | NodeGetInfo / NodeGetCapabilities | Node Pod(DaemonSet) |
| liveness-probe | 健康检查 | Probe | 两个 Pod 都有 |
4. 部署模式
CSI 插件通常部署为两个组件:
4.1 Controller 组件(Deployment)
| |
4.2 Node 组件(DaemonSet)
| |
Controller Pod 跑在任意节点,负责集群级操作(创建/删除/Attach)。Node Pod 跑在每个节点上(DaemonSet),负责本地操作(Mount/Unmount)。两者通过同一镜像不同启动参数实现。
5. 完整调用链
以动态供应一个云盘 Volume 为例:
1. 用户创建 PVC(storageClassName=fast) 2. external-provisioner 监听到 PVC → 调 CSI CreateVolume 3. CSI 插件调用云 API 创建云盘 → 返回 Volume ID 4. external-provisioner 创建 PV 对象 → PVC 绑定 5. Pod 被调度到 Node-A 6. AD Controller 创建 VolumeAttachment 对象 7. external-attacher 监听到 → 调 CSI ControllerPublishVolume(Attach) 8. CSI 插件将云盘挂接到 Node-A → 返回成功 9. kubelet 调 CSI NodeStageVolume(格式化 + 挂载到全局目录) 10. kubelet 调 CSI NodePublishVolume(bind mount 到容器目录) 11. Pod Ready,容器可读写 Volume
6. CSI 与 K8s 版本兼容
| CSI Spec | K8s 版本 | 主要特性 |
|---|---|---|
| v0.3 | 1.13+ | 基础供应、Attach/Mount |
| v1.0 | 1.13+ | GA,稳定接口 |
| v1.1 | 1.14+ | 拓扑感知、卷扩容 |
| v1.2 | 1.15+ | 快照 GA |
| v1.3 | 1.16+ | 卷克隆 |
| v1.5+ | 1.18+ | 单节点多卷 |