3. Kubernetes 存储基础:PV、PVC、StorageClass、CSI 驱动与动态供给原理
在 Kubernetes 集群中运行有状态应用(如数据库、消息队列)时,存储管理是核心挑战之一。本章将深入剖析 Kubernetes 的存储抽象层,包括 PV(PersistentVolume)、PVC(PersistentVolumeClaim)、StorageClass 以及 CSI(Container Storage Interface)驱动的协作机制,并重点讲解动态供给(Dynamic Provisioning)的实现原理。理解这些基础是后续实现存储变更门禁与灰度发布准入检查的前提。
3.1 核心概念与分层模型
Kubernetes 将存储的管理职责从 Pod 生命周期中解耦,通过以下四个核心资源构建了清晰的存储分层模型:
| 资源对象 | 层级 | 职责描述 | 生命周期 |
|---|---|---|---|
| PersistentVolume (PV) | 集群资源 | 由管理员预先制备的存储后端抽象,代表一块实际的存储(如 NFS、Ceph RBD、云盘)。 | 独立于 Pod,由集群管理。 |
| PersistentVolumeClaim (PVC) | 命名空间资源 | 用户对存储的请求描述,指定所需大小、访问模式(ReadWriteOnce/ReadOnlyMany/ReadWriteMany)等。 | 与 Pod 绑定,Pod 删除后 PVC 可保留。 |
| StorageClass | 集群资源 | 存储的“模板”或“类”,定义动态供给的驱动(Provisioner)和参数(如磁盘类型、回收策略)。 | 集群级,由管理员定义。 |
| CSI Driver | 插件层 | 实现 CSI 标准的存储插件,负责与真实存储后端交互,执行挂载、格式化、快照等操作。 | 作为 DaemonSet 或 Sidecar 运行。 |
关键理解: PVC 是“需求”,PV 是“资源”,StorageClass 是“工厂”,CSI Driver 是“工人”。用户只需声明 PVC,系统即可通过 StorageClass 调用 CSI Driver 自动创建匹配的 PV。
3.2 动态供给原理与流程
动态供给(Dynamic Provisioning)是 Kubernetes 存储体系的核心能力,它允许在用户创建 PVC 时,自动触发存储后端的资源分配和 PV 创建,无需管理员预先准备存储。其工作流程如下:
- 用户创建 PVC: 用户提交一个 PVC 对象,其中指定
storageClassName字段指向一个已存在的 StorageClass。 - 控制器检测: Kubernetes 的
PersistentVolumeController监听到新的 PVC 事件,发现其storageClassName不为空且未绑定 PV。 - 调用 Provisioner: 控制器根据 StorageClass 中定义的
provisioner字段(如disk.csi.azure.com、ebs.csi.aws.com),调用对应的 CSI 驱动或内置 Provisioner。 - 后端分配: CSI 驱动与存储后端 API 通信,创建一块指定大小和类型的存储卷(如 AWS EBS 卷、GCE Persistent Disk)。
- 创建 PV: 驱动将新创建的存储卷信息封装成一个 PV 对象,并自动绑定到发起请求的 PVC。
- Pod 使用: Pod 通过声明该 PVC,即可挂载并使用这块动态创建的存储。
动态供给优势: 消除了管理员手动创建 PV 的运维负担,实现了存储资源的按需分配和自动化管理,是云原生存储的最佳实践。
3.3 StorageClass 配置详解
StorageClass 是动态供给的“配置中心”。以下是一个典型的 StorageClass YAML 示例,用于阿里云 CSI 驱动创建 SSD 云盘:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: alicloud-disk-ssd
provisioner: diskplugin.csi.alibabacloud.com
parameters:
type: cloud_ssd
regionId: cn-hangzhou
zoneId: cn-hangzhou-g
fstype: ext4
diskTags: "usage:prod"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
mountOptions:
- discard
| 字段 | 说明 | 常见值 |
|---|---|---|
provisioner |
指定 CSI 驱动的名称,决定由哪个插件处理创建请求。 | ebs.csi.aws.com, disk.csi.azure.com |
parameters |
传递给 Provisioner 的键值对,用于定制存储后端的属性。 | type: gp3, fstype: xfs |
reclaimPolicy |
PV 被释放后的回收策略。 | Delete(自动删除), Retain(保留) |
allowVolumeExpansion |
是否允许后续扩容 PVC。 | true, false |
volumeBindingMode |
控制 PV 绑定时机。 | Immediate, WaitForFirstConsumer |
注意:
volumeBindingMode: WaitForFirstConsumer 模式会将 PV 的创建延迟到第一个 Pod 调度到节点之后,这有助于实现拓扑感知调度(如确保云盘与 Pod 在同一可用区),避免跨 AZ 挂载失败。
3.4 CSI 驱动架构与职责
CSI(Container Storage Interface)是 Kubernetes 与存储后端之间的标准接口协议。CSI 驱动通常以一组容器形式运行在集群中,主要包含以下三个核心组件:
- Controller Plugin: 以 Deployment 形式运行,负责处理创建、删除、快照、扩容等控制面操作。它不直接参与数据路径。
- Node Plugin: 以 DaemonSet 形式运行在每个节点上,负责执行挂载、格式化、卸载等节点级操作。
- Sidecar 容器: 如
csi-provisioner、csi-attacher、csi-resizer,它们监听 Kubernetes API 事件,并调用 CSI 驱动的 gRPC 接口。
3.5 存储变更门禁的切入点
在灰度发布和变更管理场景中,存储相关的变更(如修改 StorageClass 参数、更换 CSI 驱动版本、调整 PV 回收策略)风险极高。理解上述基础后,我们可以识别出以下关键准入检查点:
- PVC 变更校验: 检查 PVC 的
storageClassName是否指向一个已存在的、健康的 StorageClass。 - StorageClass 参数合规: 验证新创建的 StorageClass 是否包含允许的
provisioner和parameters,防止误用非生产配置。 - CSI 驱动版本一致性: 确保集群中运行的 CSI Driver 版本与 StorageClass 声明的 provisioner 兼容。
- 动态供给容量限制: 在创建 PVC 时,检查是否超过租户或集群的存储配额(Quota)。
- 回收策略安全: 禁止在关键命名空间中使用
reclaimPolicy: Delete,防止误删数据。