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 创建,无需管理员预先准备存储。其工作流程如下:

  1. 用户创建 PVC: 用户提交一个 PVC 对象,其中指定 storageClassName 字段指向一个已存在的 StorageClass。
  2. 控制器检测: Kubernetes 的 PersistentVolumeController 监听到新的 PVC 事件,发现其 storageClassName 不为空且未绑定 PV。
  3. 调用 Provisioner: 控制器根据 StorageClass 中定义的 provisioner 字段(如 disk.csi.azure.com、ebs.csi.aws.com),调用对应的 CSI 驱动或内置 Provisioner。
  4. 后端分配: CSI 驱动与存储后端 API 通信,创建一块指定大小和类型的存储卷(如 AWS EBS 卷、GCE Persistent Disk)。
  5. 创建 PV: 驱动将新创建的存储卷信息封装成一个 PV 对象,并自动绑定到发起请求的 PVC。
  6. Pod 使用: Pod 通过声明该 PVC,即可挂载并使用这块动态创建的存储。
动态供给优势: 消除了管理员手动创建 PV 的运维负担,实现了存储资源的按需分配和自动化管理,是云原生存储的最佳实践。
Kubernetes 动态供给(Dynamic Provisioning)流程图 用户创建 PVC PV Controller 监听 匹配 StorageClass 调用 CSI Provisioner 存储后端分配卷 创建 PV 并绑定 PVC Pod 挂载使用 说明:StorageClass 中的 provisioner 字段决定了调用哪个 CSI 驱动;parameters 字段传递后端配置(如 diskType、zone)。

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 接口。
CSI 驱动架构与组件协作 Kubernetes API csi-provisioner csi-attacher csi-resizer Controller Plugin (Deployment) Node Plugin (DaemonSet) 存储后端 (AWS EBS / Ceph) CSI 通信流程: 1. Sidecar 容器监听 K8s API 中的 PVC/PV 变更事件。 2. Sidecar 通过 Unix Socket 调用 CSI Controller 的 gRPC 接口(如 CreateVolume)。 3. Controller Plugin 与存储后端 API 交互,完成卷的创建/删除/快照。 4. Node Plugin 在 Pod 调度到的节点上执行 StageVolume / PublishVolume 挂载操作。 5. 所有组件通过 gRPC 通信,CSI 规范保证了接口的标准化和可移植性。

3.5 存储变更门禁的切入点

在灰度发布和变更管理场景中,存储相关的变更(如修改 StorageClass 参数、更换 CSI 驱动版本、调整 PV 回收策略)风险极高。理解上述基础后,我们可以识别出以下关键准入检查点:

  • PVC 变更校验: 检查 PVC 的 storageClassName 是否指向一个已存在的、健康的 StorageClass。
  • StorageClass 参数合规: 验证新创建的 StorageClass 是否包含允许的 provisioner 和 parameters,防止误用非生产配置。
  • CSI 驱动版本一致性: 确保集群中运行的 CSI Driver 版本与 StorageClass 声明的 provisioner 兼容。
  • 动态供给容量限制: 在创建 PVC 时,检查是否超过租户或集群的存储配额(Quota)。
  • 回收策略安全: 禁止在关键命名空间中使用 reclaimPolicy: Delete,防止误删数据。