CSI存储变更门禁:自动化性能基准测试与故障排查 - 第2节
CSI 规范概述:从 in-tree 到标准接口的演进
Kubernetes 早期通过 in-tree 存储插件直接与存储后端通信。每个存储厂商都需要将代码合入 Kubernetes 主干,导致发布周期长、二进制膨胀、厂商锁定风险高。CSI(Container Storage Interface)规范由 Kubernetes、Mesos、Cloud Foundry 等社区联合制定,旨在将存储驱动从容器编排平台中解耦,形成一个标准化的插件接口。
核心目标:CSI 定义了一组 gRPC 接口,让存储厂商只需实现一个符合规范的驱动程序,即可被任何支持 CSI 的容器编排平台(Kubernetes、Mesos、Nomad 等)直接调用,无需修改平台核心代码。
CSI 规范版本与关键里程碑
| 版本 | 发布时间 | 关键特性 |
|---|---|---|
| v0.1.0 | 2017-06 | 初始草案,定义 Identity、Controller、Node 三大 RPC 服务 |
| v1.0.0 | 2018-12 | GA 版本,Kubernetes v1.13 默认启用 CSI 功能 |
| v1.5.0 | 2021-06 | 引入 Volume Group Snapshot、Volume Clone 等高级特性 |
| v1.9.0 | 2023-12 | 增强拓扑感知调度、多挂载能力、健康监控 |
SRE 视角:CSI v1.0 是生产可用的分水岭。如果你的集群版本低于 v1.13,需要升级 Kubernetes 才能原生支持 CSI。当前主流 CSI 驱动(如 AWS EBS CSI、Ceph RBD CSI)均要求 CSI spec ≥ v1.1。
Container Storage Interface 核心概念
CSI 规范围绕三个核心 RPC 服务构建,每个服务对应不同的职责域:
三大 RPC 服务
| 服务名称 | 端点 | 核心方法 | 职责 |
|---|---|---|---|
| Identity | CSI- |
GetPluginInfo, Probe, GetPluginCapabilities | 驱动身份识别、能力声明、健康探测 |
| Controller | CSI- |
CreateVolume, DeleteVolume, ControllerPublishVolume, CreateSnapshot, ListSnapshots | 卷的生命周期管理(创建/删除/快照/扩容) |
| Node | CSI- |
NodePublishVolume, NodeUnpublishVolume, NodeGetVolumeStats, NodeExpandVolume | 节点级卷挂载/卸载、状态上报、在线扩容 |
关键概念术语
- Volume(卷):存储单元,对应块设备或文件系统。CSI 支持静态预置和动态预置两种模式。
- Volume Capability(卷能力):声明卷的访问模式(单节点读写、多节点只读、多节点读写)和挂载类型(块设备、文件系统)。
- Topology(拓扑):描述存储后端在集群中的物理/逻辑位置(如 zone、rack),用于指导调度器将 Pod 调度到离存储最近的节点。
- Secrets(密钥):CSI 规范允许在 RPC 请求中传递 Kubernetes Secret,用于存储后端认证(如 Ceph 的 keyring、NFS 的认证凭据)。
- Volume Attributes(卷属性):创建卷时传递的键值对参数,由 CSI 驱动自行解析(如文件系统类型、副本数、性能 tier)。
常见误区:CSI 规范本身不定义数据面加密、压缩、去重等特性。这些功能由存储后端实现,CSI 驱动仅负责将 Kubernetes 的请求转换为后端 API 调用。不要期望 CSI 驱动能“自动”提供存储后端不具备的能力。
CSI 驱动与 Kubernetes 集成原理
Kubernetes 通过 CSI Sidecar 容器 模式实现与 CSI 驱动的集成。每个 CSI 驱动 Pod 通常包含多个容器:CSI 驱动主容器 + 若干 Kubernetes 官方提供的 Sidecar。Sidecar 负责将 Kubernetes 的存储操作(如 PVC 创建、Pod 调度)转换为 CSI RPC 调用。
集成架构总览
Sidecar 容器职责详解
| Sidecar 名称 | 监听资源 | 调用的 CSI 方法 | 典型场景 |
|---|---|---|---|
| external-provisioner | PersistentVolumeClaim | CreateVolume, DeleteVolume | 动态预置:PVC 创建时自动调用后端创建卷 |
| external-attacher | VolumeAttachment | ControllerPublishVolume, ControllerUnpublishVolume | 将卷挂载到指定节点(如 iSCSI 登录、FC 映射) |
| external-resizer | PersistentVolumeClaim (spec.resources.requests.storage) | ControllerExpandVolume | 在线扩容:PVC 修改存储大小后触发后端扩容 |
| external-snapshotter | VolumeSnapshot / VolumeSnapshotContent | CreateSnapshot, DeleteSnapshot, ListSnapshots | 创建/删除卷快照,用于备份和恢复 |
| node-driver-registrar | Node 启动时注册 | GetPluginInfo, NodeGetInfo | 向 kubelet 注册 CSI 驱动,上报节点拓扑信息 |
CSI 驱动部署模式
CSI 驱动在 Kubernetes 中以 DaemonSet + StatefulSet(或 Deployment)组合方式部署:
- Controller 组件(StatefulSet/Deployment):运行 Identity 和 Controller 服务,通常部署 2 个副本保证高可用。负责卷的创建、删除、快照等控制面操作。
- Node 组件(DaemonSet):在每个 Kubernetes 节点上运行,提供 Node 服务。负责卷的挂载、卸载、格式化、指标采集等数据面操作。
生产建议:Controller 组件应设置
podAntiAffinity 确保跨节点调度;Node 组件必须设置 hostNetwork: true 和 privileged: true,因为需要访问宿主机设备(如 /dev 下的块设备)和挂载命名空间。
CSI 驱动与 kubelet 的交互流程
CSI 驱动健康检查与故障排查要点
- Probe 接口:kubelet 定期调用 CSI 驱动的
Probe方法检查驱动健康状态。如果返回非 OK 状态,kubelet 会标记该节点为NodeWithFaultyCSIDriver,阻止新 Pod 调度到该节点。 - 日志采集:CSI 驱动日志通常输出到 stdout/stderr,可通过
kubectl logs -n <namespace> <csi-driver-pod> -c <csi-driver-container>查看。Sidecar 容器日志同样重要,建议统一采集到日志平台。 - 常见故障模式:
- 卷挂载超时:检查节点网络连通性、存储后端防火墙规则、iSCSI/NFS 客户端配置。
- 卷创建失败:检查 StorageClass 参数、存储后端配额、CSI 驱动权限。
- 拓扑不匹配:检查 CSI 驱动上报的拓扑键与节点标签是否一致。