在Kubernetes(K8s)集群中,Pod作为最小部署单元,其生命周期是“临时的”——删除、重建或调度到新节点时,Pod内部的临时存储(如容器文件系统)会直接丢失。但实际业务中,数据库数据、日志、配置文件等需要长期留存,这就需要持久化存储来解决数据持久化问题。

而直接让开发/运维人员操作底层存储(如NFS、云盘、本地磁盘),不仅需要了解挂载路径、文件系统格式等细节,还会导致集群存储资源难以统一管控。为此,K8s设计了PV(PersistentVolume,持久卷) 和 PVC(PersistentVolumeClaim,持久卷声明) 两个核心组件,通过“分层抽象”解耦存储的“供给”与“使用”,让存储管理更高效、更灵活。

一、为什么需要PV和PVC?—— 解决持久化存储的核心痛点

在PV/PVC出现前,K8s中实现数据持久化的方式很“原始”:直接在Pod中通过`hostPath`挂载节点本地目录,或手动配置NFS等远程存储的挂载参数。这种方式存在两个致命问题:

1. 用户门槛高:开发人员需熟悉底层存储细节(如NFS服务器地址、云盘ID、挂载协议),而这些本应是管理员的职责;

2. 资源难管控:管理员无法统一分配、回收存储资源,易出现“存储滥用”或“资源浪费”,且跨节点调度Pod时存储配置需重新调整。

PV和PVC的出现,恰好解决了这两个痛点:

- 管理员视角:通过PV预先定义集群中的存储资源(或通过StorageClass动态生成),统一管控存储类型、容量、权限;

- 用户视角:通过PVC“申请”所需存储(如“我需要5Gi、单节点读写的存储”),无需关心底层是NFS还是云盘,K8s自动完成匹配。

二、PV:集群级的“存储资源池”

PV(PersistentVolume)是由集群管理员创建的、集群级别的存储资源对象,直接对应底层实际存储设备(如NFS共享目录、AWS EBS卷、阿里云云盘、本地磁盘分区等)。它相当于集群中的“公共存储池”,供用户通过PVC申请使用。

PV的核心属性(必懂)

PV的定义中,以下4个属性直接决定了它的“可用性”和“使用规则”,是与PVC匹配的关键:

| 属性                | 说明                                                                 |

| 容量(Capacity) | 存储资源的大小,如`10Gi`(支持Gi、Ti等单位),是PVC匹配的基础条件之一; |

| 访问模式(Access Modes) | 定义PV的读写权限及可访问节点数,决定PVC能以何种方式使用存储;         |

| 回收策略(Reclaim Policy) | PVC释放PV后,PV及数据的处理方式,影响数据安全性和资源复用;           |

| 存储类(StorageClass) | 关联指定的StorageClass(若配置),用于动态供给PV(后续会讲);        |

1. 访问模式:3种核心类型(实际场景高频考点)

访问模式决定了PV能否被多节点同时使用,需根据业务场景选择,常见3种类型:

- ReadWriteOnce(RWO):仅允许单个节点以“读写”方式挂载。适用于数据库(如MySQL)这类“独占写”场景;

- ReadOnlyMany(ROX):允许多个节点以“只读”方式挂载。适用于多节点共享配置文件、静态资源(如Nginx静态页)场景;

- ReadWriteMany(RWX):允许多个节点以“读写”方式挂载。需底层存储支持(如NFS、GlusterFS),适用于多节点共享日志、共享数据场景。

> 注意:访问模式是“PV的能力上限”——PVC申请的访问模式必须是PV支持的子集(如PV支持RWX,PVC可申请RWO/ROX/RWX)。

2. 回收策略:3种处理逻辑(数据安全关键)

当PVC被删除、释放PV后,K8s会根据PV的回收策略处理资源,3种核心策略:

- Retain(保留):保留PV对象及底层存储的数据,需管理员手动删除PV和清理数据。适用于核心业务数据(如生产库),避免误删;

- Delete(删除):自动删除PV对象及关联的底层存储(如云盘、EBS卷)。适用于测试环境或临时存储,减少手动清理成本;

- Recycle(回收):清空PV中的数据(如执行`rm -rf /path/*`),但保留PV对象,供新PVC重新使用。已废弃(安全性低,推荐用Delete或Retain)。

三、PVC:用户的“存储申请单”

PVC(PersistentVolumeClaim)是用户向集群发起的“存储请求”,相当于一份“申请单”——用户只需声明“我需要多大容量、什么访问模式的存储”,无需关心底层存储细节。

K8s会通过`PersistentVolumeController`组件,自动遍历集群中的PV,找到“满足PVC需求”的PV并完成一对一绑定。绑定成功后,PVC即可被Pod挂载使用;若没有匹配的PV,PVC会一直处于`Pending`状态。

PVC的核心逻辑(关键注意点)

1. 需求匹配规则:PVC需与PV满足3个条件才能绑定:

   - PVC请求的容量 ≤ PV的容量(如PV是10Gi,PVC请求5Gi可行,请求15Gi不可行);

   - PVC的访问模式 ≤ PV的访问模式(如PV支持RWX,PVC可申请RWO);

   - 若PV关联了StorageClass,PVC也需指定相同的StorageClass(否则不匹配);

2. 命名空间隔离:PV是集群级资源(不归属任何命名空间),但PVC是命名空间级资源——使用PVC的Pod,必须与PVC在同一命名空间(否则找不到PVC);

3. 绑定不可修改:PV与PVC绑定后,两者的核心属性(如容量、访问模式)无法修改,需解绑(删除PVC)后重新配置。

四、PV与PVC的生命周期:从绑定到释放

PV和PVC的生命周期紧密关联,核心流程可分为5个阶段:

1. PV创建:管理员手动创建PV(静态供给),或K8s通过StorageClass动态生成PV;

2. PVC创建:用户创建PVC,声明存储需求;

3. 自动绑定:K8s匹配符合条件的PV与PVC,绑定后两者状态变为`Bound`;

4. Pod使用:Pod通过`volumes`字段引用PVC,将存储挂载到容器内指定路径,实现数据持久化;

5. 资源释放:

   - 删除PVC:PV会根据回收策略处理(Retain保留、Delete删除);

   - 删除PV:若已绑定PVC,PVC状态会变为`Lost`,需重新申请新PVC。

五、动态供给:告别“手动创建PV”

手动创建PV(静态供给)适用于存储资源固定的场景(如测试环境),但在生产环境中,存储需求多变,手动创建效率极低。此时可通过StorageClass实现“动态供给”——用户创建PVC时,K8s自动根据StorageClass创建对应的PV并绑定。

动态供给核心逻辑

1. 管理员定义StorageClass:指定底层存储类型(如NFS、阿里云云盘)、参数(如云盘类型、分区格式);

2. 用户创建PVC:在PVC中通过`storageClassName`字段指定对应的StorageClass;

3. K8s自动生成PV:根据StorageClass的配置,创建PV并与PVC绑定,无需管理员干预。

> 示例:若用阿里云ACK集群,可创建一个“阿里云SSD云盘”的StorageClass,用户后续申请存储时,K8s会自动创建SSD云盘作为PV。

六、总结:PV与PVC的核心价值

PV和PVC作为K8s持久化存储的核心抽象,其本质是解耦“存储供给”与“存储使用”:

- 对管理员:统一管控集群存储资源,无需为每个Pod配置底层存储;

- 对用户:只需声明存储需求,无需关心存储类型、挂载细节;

- 对集群:实现存储资源的复用与隔离,提升Pod调度灵活性(数据不随Pod销毁而丢失)。

在实际使用中,需重点关注访问模式匹配(避免PVCPending)、回收策略选择(保障数据安全)、命名空间一致性(Pod找不到PVC的常见坑),结合StorageClass动态供给,可进一步提升存储管理效率。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐