灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 工作笔记

  • 容器与编排

    • kubectl常用命令
    • Kubernetes核心概念详解:Namespace、Pod、Deployment、PV和PVC
    • Kubernetes之yaml文件详解
    • k8s部署MySQL
    • Kubernetes (k8s) 相关名词详解
    • PV、PVC、StorageClass的区别和联系
      • 坑与边界
        • 总结
    • Docker使用笔记:容器保活、快速起 MySQL、密码管理器部署三件事
    • Browserless 使用笔记:把 Chrome 变成一个可以被并发调用的网络服务
  • Nginx

  • 监控

  • 网络安全

  • 其他

  • Linux笔记
  • 容器与编排
灯下哥谭
2025-03-30
目录

PV、PVC、StorageClass的区别和联系原创

在 Kubernetes 中,持久化存储是一个重要的概念,它通过 PersistentVolume (PV)、PersistentVolumeClaim (PVC) 和 StorageClass 来实现。下面我们详细介绍它们的区别和联系。

版本说明

本文写于 2025-03。
重要更新:所有 kubernetes.io/* 形式的 in-tree 存储插件(如 kubernetes.io/aws-ebs、kubernetes.io/gce-pd)自 1.23 起进入 CSI Migration,到 1.27 已从 kubelet/controller-manager 中彻底移除。现行集群必须使用对应的 CSI driver 名(AWS EBS 为 ebs.csi.aws.com,GCE PD 为 pd.csi.storage.gke.io)。本文示例已按 CSI 写法更新。

# 1. PersistentVolume (PV)

定义: PersistentVolume 是 Kubernetes 中的一种资源对象,它表示集群中的一个存储卷。PV 是由管理员预先创建的,或者通过 StorageClass 动态创建的。

特点:

  • PV 是集群范围的资源。
  • PV 的生命周期独立于 Pod。
  • PV 定义了存储的容量、访问模式、回收策略等。

示例:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ""                 # 静态 PV 建议留空,避免被动态供应逻辑重复匹配
  hostPath:
    path: /mnt/data
1
2
3
4
5
6
7
8
9
10
11
12
13

hostPath 只适合单节点或测试环境:它指的是「Pod 恰好被调度到的那个节点上的路径」,Pod 一旦漂移到别的节点,读到的就是一个空目录。多节点集群要用本地盘请改 local 类型的 PV,并配上 nodeAffinity 把 PV 钉在特定节点上。

# 2. PersistentVolumeClaim (PVC)

定义: PersistentVolumeClaim 是 Kubernetes 中的一种资源对象,它表示用户对存储的申请。PVC 用于绑定到 PV,并为 Pod 提供存储。

特点:

  • PVC 是用户的存储需求声明。
  • PVC 会自动绑定到符合条件的 PV。
  • PVC 通过 accessModes 和 storageClassName 来匹配 PV。

示例:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard
1
2
3
4
5
6
7
8
9
10
11

# 3. StorageClass

定义: StorageClass 是 Kubernetes 中的一种资源对象,它定义了存储卷的动态配置方式。通过 StorageClass,可以动态地创建 PV,而无需管理员手动创建。

特点:

  • StorageClass 定义了存储的提供方式。
  • StorageClass 可以指定不同的存储类型(如 NFS、Ceph、AWS EBS 等)。
  • StorageClass 可以设置 provisioner 和 parameters 来配置存储。

示例:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: ebs.csi.aws.com          # CSI driver 名;旧的 kubernetes.io/aws-ebs 已在 1.27 移除
volumeBindingMode: WaitForFirstConsumer  # 见下文「坑与边界」,多可用区集群必须设
reclaimPolicy: Delete
parameters:
  type: gp3
1
2
3
4
5
6
7
8
9

# 4. 区别

资源对象 定义 作用
PersistentVolume (PV) 表示集群中的存储卷 由管理员或 StorageClass 创建,用于存储数据
PersistentVolumeClaim (PVC) 用户的存储需求声明 用户通过 PVC 申请存储,并绑定到 PV
StorageClass 动态配置存储卷的方式 定义存储卷的类型和配置,用于动态创建 PV

# 5. 联系

  1. PV 与 PVC 的联系:

    • PVC 是用户的存储需求声明,PV 是存储的实际实现。
    • PVC 会自动绑定到符合条件的 PV。
  2. StorageClass 与 PV 的联系:

    • StorageClass 定义了动态创建 PV 的方式。
    • 如果使用 StorageClass,PV 会根据 StorageClass 的配置动态生成。
  3. StorageClass 与 PVC 的联系:

    • PVC 可以通过 storageClassName 字段指定使用哪个 StorageClass。
    • PVC 的 storageClassName 决定了绑定的 PV 的类型。

# 6. 使用场景

  • 静态存储: 如果集群管理员已经预先创建了 PV,用户可以通过 PVC 绑定到这些 PV。

  • 动态存储: 如果使用了 StorageClass,用户可以通过 PVC 动态创建 PV,而无需管理员手动干预。

# 7. 示例流程

以下是一个使用 StorageClass 动态创建 PV 的完整流程:

  1. 创建 StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: io1
  iopsPerGB: "10"
  fsType: ext4
1
2
3
4
5
6
7
8
9
10
  1. 创建 PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: fast-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: fast-storage
1
2
3
4
5
6
7
8
9
10
11
  1. 检查自动创建的 PV:
kubectl get pvc fast-pvc
kubectl get pv
1
2

期望输出:kubectl get pvc 里 STATUS 是 Bound,VOLUME 一列出现一个 pvc-<uuid> 形式的 PV 名——这个名字由 provisioner 自动生成,能看到它就说明动态供应真的发生了。

如果 PVC 长期停在 Pending,不要去看 PVC 本身,要看它的事件:

kubectl describe pvc fast-pvc | tail -20
1

三种最常见的事件与含义:

事件信息 含义
no persistent volumes available for this claim and no storage class is set PVC 没指定 storageClassName,集群也没有默认 StorageClass
storageclass.storage.k8s.io "fast-storage" not found StorageClass 名字写错,或根本没创建
长时间无任何事件 provisioner 名写错(例如仍在用已被移除的 kubernetes.io/aws-ebs),没有任何控制器在监听这个 StorageClass

# 坑与边界

1. volumeBindingMode 不设 WaitForFirstConsumer,多可用区集群会挂不上。 默认值是 Immediate:PVC 一创建就立刻在某个可用区把云盘开出来。等 Pod 真正被调度时,调度器可能把它放到另一个可用区,而块存储(EBS/PD)是不能跨 AZ 挂载的,结果就是 Pod 永远卡在 Pending,事件是 volume node affinity conflict。WaitForFirstConsumer 把开盘动作推迟到 Pod 调度决定之后,让存储跟着 Pod 走。

2. persistentVolumeReclaimPolicy 决定 PVC 删掉之后数据还在不在。 Delete(动态供应的默认值)会连底层云盘一起删除,误删 PVC 等于数据蒸发;Retain 会保留 PV 和数据,但 PV 进入 Released 状态后不会被自动重新绑定——必须手工清掉 PV 的 spec.claimRef 才能给新 PVC 用。生产上的库存数据建议 Retain,代价是要人工回收。

3. PVC 的容量请求是「下限」,不是「精确值」。 静态绑定时,一个请求 5Gi 的 PVC 完全可能绑到一个 100Gi 的 PV 上,PVC 会独占整个 PV,多余容量白白浪费。静态 PV 池要按容量分档准备,不要指望它切分。

4. 扩容能扩不能缩。 StorageClass 需要 allowVolumeExpansion: true 才允许改 PVC 的 resources.requests.storage,且只能变大;缩容 Kubernetes 完全不支持,只能新建 PVC 再迁数据。

5. accessModes 是「PV 声明自己支持什么」,不是 Kubernetes 强制的。 块存储(EBS、PD、大部分 CSI 云盘)实际只支持 ReadWriteOnce——同一时刻只能被一个节点挂载。要多 Pod 跨节点同时读写,必须用文件存储(NFS、CephFS、EFS)并声明 ReadWriteMany。把一个 RWO 的 PVC 挂给多副本 Deployment,是最常见的翻车方式。

通过以上流程,PVC 会自动绑定到由 StorageClass 动态创建的 PV。

# 总结

  • PV 是存储的实际实现。
  • PVC 是用户的存储需求声明。
  • StorageClass 提供了动态创建 PV 的方式。
  • 三者共同构成了 Kubernetes 中的持久化存储体系。
#容量规划
上次更新: 9/11/2026

← Kubernetes (k8s) 相关名词详解 Docker使用笔记:容器保活、快速起 MySQL、密码管理器部署三件事→

最近更新
01
DeepSeek Harness 实战 06|学习笔记:插件、工具、技能不在同一个维度上 原创
09-11
02
DeepSeek Harness 实战 05|让两个编码 Agent 共用一份长期记忆 原创
09-09
03
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式