2. Kubernetes 存储基础回顾:PV/PVC/StorageClass 概念、CSI 驱动架构、本地存储与远程存储对比

2.1 核心抽象:PV、PVC 与 StorageClass

Kubernetes 存储体系围绕三个核心 API 资源构建,将存储的供给与消费彻底解耦,使应用开发者无需关心底层存储基础设施的细节。

资源对象 全称 角色 生命周期
PV PersistentVolume 集群管理员预置或动态创建的存储资源,独立于 Pod 存在 由管理员管理,与 PVC 解绑后可被回收或保留
PVC PersistentVolumeClaim 用户对存储资源的请求声明,描述所需容量、访问模式 由用户管理,绑定到 PV 后供 Pod 使用
StorageClass StorageClass 存储类模板,定义动态制备 PV 的驱动、参数、回收策略 由管理员定义,PVC 通过 storageClassName 引用
关键流程: PVC 通过 storageClassName 匹配 StorageClass → StorageClass 调用 CSI 驱动动态创建 PV → PV 与 PVC 完成绑定 → Pod 通过 volume 挂载 PVC 使用存储。

2.2 访问模式与回收策略

PV 的访问模式决定了存储卷可以被多少个节点以何种方式挂载,是存储架构设计中的关键约束。

  • ReadWriteOnce (RWO):仅被单个节点以读写方式挂载,适用于大多数块存储。
  • ReadOnlyMany (ROX):被多个节点以只读方式挂载,适用于共享配置或静态数据。
  • ReadWriteMany (RWX):被多个节点以读写方式挂载,适用于 NFS、GlusterFS 等共享文件系统。
  • ReadWriteOncePod (RWOP):仅被单个 Pod 挂载,Kubernetes v1.22+ 特性,增强安全性。

回收策略决定 PVC 释放后 PV 的处理方式:

策略 行为 适用场景
Retain 保留 PV 及其后端存储,需管理员手动清理 需要数据持久保留,手动迁移
Delete 自动删除 PV 及后端存储资源 动态制备的临时或测试存储
Recycle (已弃用)执行 rm -rf 后重新可用 不建议在新集群中使用

2.3 CSI 驱动架构

Container Storage Interface (CSI) 是 Kubernetes 存储生态的标准插件机制,它将存储驱动从核心 kubelet 中剥离,以 DaemonSet + Sidecar 容器的方式运行,实现了存储厂商与 Kubernetes 版本的解耦。

架构要点: CSI 驱动由三个核心 gRPC 服务组成:Identity Service(身份与能力)、Controller Service(卷创建/删除/快照)、Node Service(卷挂载/格式化/卸载)。Kubernetes 通过 external-provisioner、external-attacher、node-driver-registrar 等 Sidecar 容器与 CSI 驱动通信。
CSI 驱动架构组件关系图 CSI 驱动架构组件关系 Kubernetes API Server Sidecar 容器 external-provisioner external-attacher node-driver-registrar CSI Controller CSI Node 后端存储系统 SAN / NAS / 云盘 本地盘 / 分布式存储 CSI 工作流程说明 1. PVC 创建 → external-provisioner 监听 → 调用 CSI Controller.CreateVolume 2. Pod 调度到节点 → external-attacher 调用 CSI Controller.ControllerPublishVolume 3. kubelet 通过 Unix Socket 调用 CSI Node.NodePublishVolume → 挂载到 Pod 路径 4. 所有 CSI 驱动以 DaemonSet 运行在每个节点,Sidecar 容器负责与 API Server 交互

2.4 本地存储与远程存储对比

在多集群架构中,选择本地存储还是远程存储直接影响数据一致性、故障域和运维复杂度。以下从多个维度进行对比:

对比维度 本地存储 (Local SSD/NVMe) 远程存储 (NFS/Ceph/云盘)
延迟 亚毫秒级,极低 毫秒级,受网络影响
吞吐量 受单机 PCIe 带宽限制 可水平扩展,聚合吞吐高
数据持久性 依赖节点健康,节点故障数据丢失 多副本/纠删码,跨节点/跨 AZ 保护
故障域 单节点故障即影响 跨节点/机架/数据中心
访问模式 通常仅 RWO 支持 RWO / RWX / ROX
运维复杂度 低,无需额外存储集群 高,需维护存储集群与网络
适用场景 高吞吐数据库、缓存、日志 共享文件、持久化工作负载、跨集群迁移
多集群架构建议: 本地存储适合对延迟极度敏感的有状态工作负载,但必须配合节点故障转移机制(如 Strimzi Kafka 的 JBOD + rack awareness)。远程存储是跨集群数据共享和迁移的基础,推荐使用支持 CSI 快照与克隆能力的存储后端(如 Ceph RBD、AWS EBS CSI)。

2.5 本地存储与远程存储的典型部署模式

下图展示了两种存储模式在 Kubernetes 集群中的典型部署拓扑,帮助理解其架构差异。

本地存储与远程存储部署模式对比 本地存储 vs 远程存储部署模式 本地存储模式 Node-1 Pod A (RWO) Local SSD Node-2 Pod B (RWO) Local NVMe Node-3 Pod C (RWO) Local SSD Node-4 Pod D (RWO) Local NVMe 每个 Pod 绑定到特定节点,数据不共享 节点故障 → 数据丢失,需上层应用处理 远程存储模式 Node-1 Pod A Node-2 Pod B Node-3 Pod C 存储集群 Ceph / NFS 副本数: 3 RWX 共享 快照/克隆 所有 Pod 共享同一存储后端 节点故障 → Pod 漂移,数据不丢失

2.6 实践建议与避坑指南

StorageClass 配置示例: 以下 YAML 定义了一个使用 Ceph RBD 的 StorageClass,开启 allowVolumeExpansion 支持在线扩容。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
  clusterID: <ceph-cluster-id>
  pool: kubernetes
  imageFeatures: layering
  csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
  csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi
  csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
  csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
  - discard
避坑提醒:
  • 不要在生产集群中混用 Retain 和 Delete 策略而不做标签隔离,容易导致数据残留或意外删除。
  • 本地存储必须配合 nodeAffinity 或 volumeBindingMode: WaitForFirstConsumer,否则调度器可能将 Pod 调度到没有对应本地盘的节点。
  • CSI 驱动升级前务必检查 Sidecar 容器版本兼容性矩阵,不匹配的版本会导致卷挂载失败。
  • 远程存储的 RWX 模式需要底层文件系统支持锁机制(如 NFS v4.1+ 或 CephFS),否则并发写入可能导致数据损坏。