3. CSI 基础概念:Container Storage Interface 规范、驱动架构与 PV/PVC 关系
在 Kubernetes 生态中,存储接入一直是一个复杂且碎片化的领域。每个云厂商或存储供应商都需要为 Kubernetes 编写特定的 in-tree(树内) 卷插件,这些插件与 kubelet 和 kube-controller-manager 的代码深度耦合,导致升级困难、维护成本高。Container Storage Interface(CSI)的出现,正是为了解决这一痛点,将存储驱动从 Kubernetes 核心代码中解耦,形成一个标准化的插件体系。
3.1 CSI 规范:存储插件的标准化契约
CSI 是由 CNCF(Cloud Native Computing Foundation) 主导的行业标准,定义了存储提供商(SP)实现存储插件的统一接口。它本质上是一个 gRPC 协议 的规范集合,Kubernetes 作为容器编排系统(CO),通过调用这些 gRPC 接口来管理存储的生命周期。
CSI 规范定义了三大类 gRPC 服务,每类服务包含若干 RPC 方法:
| 服务类别 | 主要 RPC 方法 | 功能描述 |
|---|---|---|
| Identity Service | GetPluginInfo, GetPluginCapabilities, Probe |
用于 CO 发现插件的身份、能力(如是否支持卷扩展、快照)以及健康检查。 |
| Controller Service | CreateVolume, DeleteVolume, ControllerPublishVolume, ControllerUnpublishVolume, CreateSnapshot, DeleteSnapshot |
在存储后端(如云磁盘、SAN/NAS 阵列)上执行卷的创建、删除、挂载到节点、快照等操作。这些操作通常由集群级别的控制器执行。 |
| Node Service | NodeStageVolume, NodeUnstageVolume, NodePublishVolume, NodeUnpublishVolume, NodeGetVolumeStats |
在单个节点上执行卷的格式化、挂载到 Pod 目录、卸载等操作。这些操作由运行在节点上的 kubelet 触发。 |
3.2 CSI 驱动架构:Controller 与 Node 组件
一个标准的 CSI 驱动通常由两个核心组件构成:Controller Plugin 和 Node Plugin。它们以 DaemonSet 或 Deployment 的形式运行在 Kubernetes 集群中,并通过 Unix Domain Socket 与 kubelet 或外部控制器通信。
3.3 CSI 与 PV/PVC 的关系:从声明到绑定的完整链路
在 Kubernetes 中,用户通过 PersistentVolumeClaim(PVC) 声明存储需求,系统通过 PersistentVolume(PV) 提供实际的存储资源。CSI 驱动是连接 PVC 与 PV 的“执行者”,它负责将 PVC 的声明转化为对存储后端的真实操作。
下图展示了从用户创建 PVC 到 Pod 使用存储的完整流程:
3.4 核心概念对比:In-tree 插件 vs CSI 驱动
为了更直观地理解 CSI 带来的变革,我们将传统的 in-tree 卷插件与 CSI 驱动进行对比:
| 对比维度 | In-tree 卷插件 | CSI 驱动 |
|---|---|---|
| 代码位置 | Kubernetes 核心仓库(k8s.io/kubernetes) | 独立仓库,由存储供应商维护 |
| 升级方式 | 必须跟随 Kubernetes 版本升级 | 独立升级,不依赖 Kubernetes 版本 |
| 部署方式 | 编译在 kubelet 二进制中 | 以 DaemonSet/Deployment 形式部署在集群内 |
| 接口标准 | 内部接口,无标准化 | gRPC 标准接口,跨平台兼容 |
| 功能扩展 | 困难,需要修改 Kubernetes 核心代码 | 容易,通过实现 CSI 规范中的可选 RPC 方法 |
| 典型场景 | 早期 Kubernetes 版本(v1.13 之前) | Kubernetes v1.13+ 推荐方式 |