在 Kubernetes(K8s)中, 持久化存储(Persistent Storage)是构建 有状态服务(如数据库、缓存等)的关键组件。而 PersistentVolume(PV) 和 PersistentVolumeClaim(PVC) 是用于管理 持久化存储资源的核心机制。它们是 Kubernetes 中的 存储抽象层, 解耦了存储的具体 实现和 使用方式。
| 功能/组件 | 描述 |
|---|---|
| PV | 存储资源抽象,管理员定义的磁盘。 |
| PVC | 用户的资源请求,定义容量/访问模式等。 |
| StorageClass | 定义存储的类型、策略,实现动态分配。 |
| 访问模式 | ReadWriteOnce、ReadOnlyMany、ReadWriteMany |
| 回收策略 | Retain(保留)、Recycle(回收)、Delete(删除) |
| 动态供应 | 通过 StorageClass 实现,自动创建 PV |
PV – 存储资源提供者
- PV 是集群管理员提供的一块持久化存储资源,是对存储的抽象封装。
- 类似于硬件层面的“磁盘分区”。
- 由管理员预先配置(静态)或由系统动态创建。
- 与具体 Pod 解耦,生命周期独立于 Pod。
常见类型:hostPath、NFS、CephFS、GlusterFS、AWS EBS、GCE PD、CSI 插件 等。
创建pv-nfs.yaml
apiversion: v1
kind: PersistentVolume # 描述资源对象为PV类型
metadata:
name: pv0001 # PV 的名字
spec:
capacity: # 容量配置
storage: 5Gi # pv的容量
volumeMode: Filesystem # 存储类型为文件系统
accessModes: # 访问模式: ReadwriteOnce(同时只能被一个PVC使用)、ReadwriteMany、ReadOnlyMany
- ReadwriteMany # 可被单节点独写
persistentvolumeReclaimPolicy: Retain # 回收策略
storageClassName: slow # 创建 PV的存储类名,需要与pvc的相同
mountOptions: # 加载配置
- hard
- nfsvers=4.1
nfs: # 连接到nfs
path: /data/nfs/rw/test-pv # 存储路径
server: 192.168.113.121 # nfs服务地址
创建pv资源
kubectl create -f pv-nfs.yaml

获取PV资源
kubectl get pv

pv状态说明
| 状态(Status) | 含义说明 |
|---|---|
| Available | 可用状态,表示 PV 已创建但尚未被任何 PVC 绑定。 |
| Bound | 已绑定状态,PV 已与某个 PVC 成功绑定。 |
| Released | 已释放状态,绑定的 PVC 已删除,但 PV 尚未回收或重新绑定。 |
| Failed | 失败状态,表示 PV 发生了错误,如回收失败或无法使用。 |
| Terminating | 正在删除状态,表示 PV 正在被删除(在某些 Kubernetes 版本中可见)。 |
回收策略
当 PVC 被删除后,PV 会根据其设置的 persistentVolumeReclaimPolicy 决定如何处理。
Kubernetes 支持三种回收策略:
1. Retain(保留)
- Retain(保留)
含义:即使 PVC 被删除,PV 和数据仍然保留。
用途:防止误删,适用于敏感数据。
操作:需要手动回收该 PV,或者清理数据后重新绑定。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-retain
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: "/mnt/data"
2. Delete(删除)
- Delete(删除)
含义:PVC 被删除时,PV 对应的后端存储资源也会被删除。
用途:适合临时数据(如缓存、CI构建数据)。
要求:PV 必须是由动态存储类(StorageClass)创建。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
provisioner: kubernetes.io/aws-ebs
reclaimPolicy: Delete
3.Recycle(已废弃)
含义:以前会清除数据并重新标记为可用。
状态:K8s 1.11 起被废弃,建议改用外部 provisioner + Retain/Delete 策略。
回收策略影响数据生命周期的安全性与便捷性:
- Retain 最安全,但需手动处理。
- Delete 自动清理,适合无状态数据。
- 管理员应根据数据敏感程度和业务需求选择合适的策略
PVC – 存储资源使用者
- PVC 是用户对持久存储资源的请求。
- 就像 Pod 请求 CPU/内存一样,请求一个“磁盘资源”。
- 用户通过 PVC 说明期望的容量、访问模式(ReadWriteOnce、ReadOnlyMany、ReadWriteMany)。
- 系统将 PVC 绑定到满足条件的 PV 上。
创建PVC
pvc-test.yaml
apiVersion: v1
kind: PersistentVolumeClaim # 资源类型为 PVC
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadwriteMany # 权限需要与对应的pv相同
volumeMode: Filesystem
resources:
requests:
storage: 5Gi # 资源可以小于pv 的,但是不能大于,如果大于就会匹配不到 pv
storageClassName: slow #名字需要与对应的pv相同
#selector:#使用选择器选择对应的pv
## matchLabels:
## release: "stable"
## matchExpressions:
## - { key : environment,operator: In,values: [dev]}
#
kubectl create -f pvc-test.yaml

获取pvc,pv可以看到pv与pvc的绑定关系

pod绑定PVC
在pod的挂载容器配置中,增加pvc挂载
apiversion: v1
kind: Pod
metadata:
name: test-pvc-pd
spec:
containers:
- image: nginx
name: nginx-volume
volumeMounts:
- mountPath: /usr/share/nginx/html # 挂载到容器的哪个目录
name: test-volume # 挂载哪个volume
volumes:
- name: test-volume
persistentVolumeClaim: # 关联pve
claimName: nfs-pvc # 要关联到哪个pvc
StorageClass – 定义“类型”与提供“策略”。
- StorageClass 定义了存储的“类型”与“动态供应策略”。
- 指定存储的级别、类型(SSD/HDD)、副本数等参数。
- 实现 PVC 的动态创建 PV。
- 不同云平台和插件支持不同的 StorageClass 类型。
工作原理
1. 静态绑定流程
- 静态绑定流程
- 1.管理员创建好 PV。
- 2.用户创建 PVC。
- 3.Kubernetes 根据 PVC 的需求自动匹配一个合适的 PV 并进行绑定。
2. 动态供应流程
- 动态供应流程
- 1.用户创建一个带 storageClassName 的 PVC。
- 2.Kubernetes 自动调用该 StorageClass 对应的存储插件动态创建 PV。
- 3.自动绑定 PVC 和新建的 PV。
通俗理解pv,pvc,storage
想象你是一个人(开发者),你要租一个仓库(数据存储)来放你的货(数据)。
| K8s 组件 | 类比 | 谁来写 |
|---|---|---|
| PV(PersistentVolume) | 仓库管理员创建的“仓库” | 管理员 |
| PVC(PersistentVolumeClaim) | 你提交的“租仓库申请” | 开发者 |
| StorageClass | 仓库的类型和建仓规则(自动建仓策略) | 管理员配置 |
所以流程是这样的:
- 你(Pod)提出一个仓库申请(PVC);
- 如果已经有仓库(PV)满足条件,系统自动配对给你;
- 如果没有,系统可以按规则(StorageClass)动态建一个仓库(动态创建 PV);
- 仓库(PV)一旦租给你(PVC),你就可以使用它了。
1. PV(PersistentVolume)- 已存在的存储资源
由管理员手动创建或通过 StorageClass 动态创建。
它定义了能用的存储,比如大小、类型(NFS、EBS)、访问权限等。
kind: PersistentVolume
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
storageClassName: fast
关键字段
| 字段 | 说明 |
|---|---|
capacity | 存储容量,如 1Gi |
accessModes | 访问模式,如 ReadWriteOnce |
storageClassName | 指定属于哪个 StorageClass |
hostPath, nfs | 存储后端类型 |
persistentVolumeReclaimPolicy | 释放后的回收策略:Retain、Delete、Recycle |
常见访问模式
| 模式 | 含义 |
|---|---|
ReadWriteOnce | 单个节点读写(最常用) |
ReadOnlyMany | 多个节点只读 |
ReadWriteMany | 多个节点读写(如 NFS、CephFS) |
2. PVC(PersistentVolumeClaim)- 开发者的存储请求
由开发者或应用创建,描述你需要多大的盘、是否可读写等。
系统会查找满足这个 PVC 的 PV 并绑定。
kind: PersistentVolumeClaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: fast
关键字段
| 字段 | 说明 |
|---|---|
resources.requests.storage | 申请的存储大小,如 500Mi |
accessModes | 访问模式,必须与 PV 匹配 |
storageClassName | 指定使用哪个 StorageClass 的 PV |
PVC 会根据配置寻找一个满足条件(容量、访问模式、StorageClass)的 PV 并绑定。
3. StorageClass —— 自动建 PV 的“工厂说明书”
常见字段:
| 字段 | 含义 |
|---|---|
provisioner | 指定由哪个插件或 CSI 驱动负责动态创建 PV |
parameters | 提供给插件的参数(如存储类型、目录、池名等) |
volumeBindingMode | 等待调度策略,常用 WaitForFirstConsumer |
reclaimPolicy | 释放后的回收策略(Retain/Delete) |
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
4. PV/PVC 关联条件
在 Kubernetes 中,PV 与 PVC 的绑定有以下限制与匹配规则:
- 访问模式必须兼容(Access Modes)
PVC 的访问模式(如 ReadWriteOnce)必须被 PV 所支持。- 存储容量必须满足(Storage Requests)
PV 的容量必须 ≥ PVC 请求的容量。- 匹配 StorageClass(可选)
如果 PVC 指定了 StorageClass,系统只会绑定到该类 PV。
如果 PVC 没指定 StorageClass,只能绑定未指定 StorageClass 的 PV。- 绑定是单向的
一个 PVC 只能绑定一个 PV,反之亦然(除非使用 VolumeMode 为 Block 的共享块设备等特例)。- 匹配 Label Selector(如设置)
PVC 可设置 selector 匹配特定 PV 的 label。
spec:
selector:
matchLabels:
usage: database- 状态必须为空闲(Available)
PV 只能与状态为 Available 的 PVC 匹配。
如果 PV 已被绑定,则不能再被其他 PVC 使用。
三者之间的关系
| 概念 | 作用 | 典型由谁创建 |
|---|---|---|
| PV | 实际的存储资源对象 | 管理员或动态创建 |
| PVC | 用户申请存储的请求 | 开发者 / 应用提交 |
| StorageClass | 定义存储类型模板,支持动态供给 | 管理员 |

创建顺序一图看懂
| 使用方式 | 顺序 | 描述 |
|---|---|---|
| 静态分配 | 1️⃣ PV → 2️⃣ PVC → 3️⃣ Pod | 管理员先建 PV,PVC 请求时自动绑定 |
| 动态分配 | 1️⃣ StorageClass → 2️⃣ PVC → 3️⃣ PV 自动生成 → 4️⃣ Pod | PVC 自动触发 PV 创建并绑定 |
实战示例
1. 创建StorageClass(以hostPath模拟)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
2. 创建 PV(静态方式)
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
hostPath:
path: "/mnt/data"
3. 创建 PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-storage
4. Pod 挂载 PVC
apiVersion: v1
kind: Pod
metadata:
name: pvc-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-storage
volumes:
- name: my-storage
persistentVolumeClaim:
claimName: my-pvc

1158

被折叠的 条评论
为什么被折叠?



