CSI 架构总览:CO、Sidecar、Driver 三层职责与交互关系
CSI(Container Storage Interface)采用清晰的三层架构设计,将存储控制面与数据面解耦,使容器编排平台(CO)无需绑定特定存储厂商的客户端库。理解这三层的职责划分与交互流程,是掌握 CSI 通信机制的基础。
2.1 三层架构总览
CSI 架构从上到下依次为:容器编排平台(CO)、Sidecar 容器、CSI Driver。CO 负责发起存储生命周期操作,Sidecar 负责将 CO 的原生存储 API 转换为 CSI 标准 gRPC 调用,Driver 负责与后端存储系统交互并执行实际存储操作。
2.2 各层职责详解
2.2.1 容器编排平台(CO)
CO 是存储操作的发起者,负责管理容器化应用的生命周期。在 Kubernetes 中,CO 通过 PV/PVC 体系 声明存储需求,并调用 CSI 的 CreateVolume、ControllerPublishVolume、NodeStageVolume、NodePublishVolume 等操作。CO 不直接与 CSI Driver 通信,而是通过 Sidecar 容器进行桥接。
2.2.2 Sidecar 容器
Sidecar 是 CO 与 Driver 之间的适配层,每个 Sidecar 负责一类 CSI 操作。Kubernetes 官方维护了多个标准 Sidecar:
| Sidecar 名称 | 负责的 CSI 操作 | 对应 CO 组件 |
|---|---|---|
| external-provisioner | 卷创建/删除(CreateVolume / DeleteVolume) | PV Controller |
| external-attacher | 卷挂载/卸载(ControllerPublishVolume / ControllerUnpublishVolume) | AttachDetach Controller |
| external-resizer | 卷扩容(ControllerExpandVolume) | PVC 扩容控制器 |
| external-snapshotter | 快照创建/删除(CreateSnapshot / DeleteSnapshot) | VolumeSnapshot Controller |
| node-driver-registrar | Driver 注册与健康检查(NodeGetInfo / NodeGetCapabilities) | Kubelet 插件注册 |
CreateVolume gRPC 调用发送给 Driver。
2.2.3 CSI Driver
CSI Driver 是存储厂商实现的二进制进程,通常以 DaemonSet 形式部署在每个节点上。Driver 必须实现以下三个 gRPC 服务:
- Identity 服务:提供 Driver 名称、版本、能力声明(如是否支持卷扩容、快照、拓扑感知等)。
- Controller 服务:运行在控制面,负责卷的创建/删除、挂载/卸载、快照、扩容等控制面操作。
- Node 服务:运行在每个节点上,负责将卷挂载到节点本地文件系统,并最终提供给 Pod 使用。
2.3 交互关系与通信流程
CSI 的交互分为 控制面流程 和 数据面流程。控制面流程涉及 CO、Sidecar 和 Driver 的 Controller 服务;数据面流程仅涉及 Kubelet 和 Driver 的 Node 服务。
2.4 关键交互规则
- Sidecar 不参与数据面:所有数据面操作(如格式化、挂载到 Pod 命名空间)由 Kubelet 直接调用 Driver Node 服务完成,Sidecar 只处理控制面逻辑。
- gRPC 是唯一通信协议:CO 与 Driver 之间不传递 HTTP REST 请求,所有 CSI 操作均通过 Unix Socket 上的 gRPC 调用完成。
- Driver 无状态设计:CSI Driver 不维护持久化状态,所有状态由 CO(如 PV 对象)和后端存储系统共同管理。
2.5 部署拓扑示例
在 Kubernetes 中,CSI Driver 通常以 DaemonSet 形式部署在每个节点上,Sidecar 以 Deployment 形式运行在控制面节点。以下是一个典型的部署清单结构:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: csi-driver-node
spec:
template:
spec:
containers:
- name: csi-driver # 主 Driver 容器
image: registry.example.com/csi-driver:v1.0
volumeMounts:
- mountPath: /csi
name: socket-dir
- name: node-driver-registrar # Sidecar:注册 Driver 到 Kubelet
image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.8.0
volumeMounts:
- mountPath: /csi
name: socket-dir
volumes:
- name: socket-dir
hostPath:
path: /var/lib/kubelet/plugins/csi-driver.example.com
type: DirectoryOrCreate
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: csi-driver-controller
spec:
replicas: 2
template:
spec:
containers:
- name: csi-driver # 同一 Driver 镜像,运行 Controller 服务
image: registry.example.com/csi-driver:v1.0
- name: external-provisioner # Sidecar:处理卷创建
image: registry.k8s.io/sig-storage/csi-provisioner:v3.5.0
- name: external-attacher # Sidecar:处理卷挂载
image: registry.k8s.io/sig-storage/csi-attacher:v4.1.0
- name: external-resizer # Sidecar:处理卷扩容
image: registry.k8s.io/sig-storage/csi-resizer:v1.8.0