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 驱动通信。
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 集群中的典型部署拓扑,帮助理解其架构差异。
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),否则并发写入可能导致数据损坏。