PersistentVolumeClaim(PVC,持久卷申领)是 Kubernetes 中面向用户的存储资源请求接口,与 PersistentVolume(PV,持久卷)配合构成 K8s 的持久化存储管理体系,核心作用是解耦 Pod 与底层实际存储资源的直接关联,让用户无需关注存储的底层实现(如本地磁盘、NFS、云硬盘),仅需声明存储需求即可使用。

一、核心定义

  1. PV:是 K8s 集群中由管理员提前创建的持久化存储资源对象,代表集群中的一块实际存储(如本地磁盘分区、NFS 共享目录、AWS EBS 云硬盘、Ceph 块存储等),PV 拥有独立的生命周期,不依赖于 Pod 的生命周期,Pod 被删除后,PV 中的数据仍会保留。

  2. PVC:是 K8s 集群中由普通用户创建的存储资源请求对象,用户通过 PVC 声明自己的存储需求:如存储容量、访问模式、存储类(StorageClass) 等,K8s 会自动将 PVC 与满足需求的 PV 进行绑定,绑定后的 PVC 即可被 Pod 挂载使用,实现数据持久化。

通俗类比

  • PV = 机房中管理员提前准备好的硬盘(已格式化、分配好容量);

  • PVC = 员工向管理员提交的硬盘使用申请单(申请 XX 容量、可读写 / 只读等);

  • K8s = 管理员,自动将符合申请单要求的硬盘分配给员工;

  • Pod = 员工的电脑,挂载分配到的硬盘(PVC 绑定的 PV)使用。

二、PVC 的设计初衷(核心价值)

K8s 设计 PVC 的核心目的是实现「存储资源」与「应用 Pod」的解耦,解决传统容器存储的两大痛点,同时适配 K8s 的声明式 API、资源抽象、多租户设计理念:

1. 对用户:屏蔽底层存储细节,降低使用成本

用户无需了解集群中使用的是本地存储、NFS 还是云存储,也无需配置存储的底层连接信息(如 NFS 服务器地址、云硬盘 ID),仅需通过 PVC 声明容量、访问模式等核心需求,即可获取存储资源,专注于应用开发。

2. 对管理员:统一管理存储资源,提升集群可控性

集群管理员可提前创建各类规格的 PV(如小容量本地存储、大容量 NFS 存储),对集群存储资源进行统一规划和管理;同时通过StorageClass实现 PV 的动态创建,避免手动创建 PV 的繁琐,适配大规模集群的存储需求。

3. 实现存储的「持久化」与「可移植性」

  • 持久化:PVC 绑定 PV 后,Pod 的生命周期与存储生命周期解耦,Pod 被删除、重建后,只要 PVC 未被删除,重新挂载的 Pod 仍可访问原有数据;

  • 可移植性:相同的 PVC 配置可在不同 K8s 集群中使用(只要集群中有满足需求的 PV/StorageClass),无需因底层存储变化修改 Pod 配置,提升应用的可移植性。

4. 适配 K8s 的多租户体系

PVC 属于命名空间级资源,不同命名空间的 PVC 相互隔离,管理员可通过 RBAC 权限控制不同租户 / 用户的 PVC 创建、使用权限,实现存储资源的租户隔离。

三、PVC 的核心特性

1. 命名空间级资源(Namespace-Scoped)

PVC 是命名空间作用域的资源,而 PV 是集群级资源(Cluster-Scoped),这意味着:

  • 一个 PVC 只能被同一命名空间的 Pod 挂载使用;

  • 配置 PVC 时必须指定metadata.namespace(若不指定,默认创建在default命名空间);

  • PV 属于集群全局资源,可被任意命名空间的 PVC 绑定(只要匹配需求)。

创建 PVC 时,命名空间必须与使用该 PVC 的 Pod/Deployment 命名空间一致,否则无法绑定使用

2. 声明式 API,仅声明需求不指定实现

PVC 遵循 K8s 的声明式 API设计,用户只需在 PVC 中声明「需要什么」,而无需指定「如何实现」:

  • 声明容量:需要多少存储(如 250Mi、10Gi);

  • 声明访问模式:需要读写 / 只读、单节点 / 多节点访问;

  • 声明存储类:需要哪种类型的存储(如 local-path、nfs、ebs)。

    K8s 会根据声明的需求自动匹配最优的 PV,用户无需干预绑定过程。

3. 与 PV 的「一对一绑定」原则

PVC 与 PV 绑定后,会形成一对一的专属关联,即一个 PVC 只能绑定一个 PV,一个 PV 在被绑定后,无法被其他 PVC 再次绑定,直到该 PVC 被删除、解绑。

  • 若 PV 的容量大于等于PVC 的请求容量,且其他条件(访问模式、存储类)匹配,K8s 会优先绑定;

  • 若集群中无满足 PVC 需求的 PV,PVC 的状态会变为Pending,直到有符合条件的 PV 被创建。

4. 生命周期独立于 Pod,依赖于 PV

  • PVC 的生命周期不依赖于 Pod:挂载 PVC 的 Pod 被删除后,PVC 仍存在,且与 PV 的绑定关系不变,新创建的 Pod 可继续挂载该 PVC 访问数据;

  • PVC 的生命周期依赖于 PV:若绑定的 PV 被管理员手动删除,PVC 会失去存储资源,状态变为Lost,无法继续使用;

  • PVC 可通过回收策略控制底层存储的生命周期(由 PV 的回收策略决定)。

四、PVC 的关键配置项(CKA 考试必背)

PVC 的配置通过 YAML 文件定义,核心配置项集中在spec字段,所有配置项均为与 PV 的匹配条件,以下为标准 PVC 配置模板 + 核心配置项解读:

apiVersion: v1  # PVC的API版本,固定为v1
kind: PersistentVolumeClaim  # 资源类型为PersistentVolumeClaim
metadata:
  name: my-pvc  # PVC名称,需唯一,Pod挂载时通过名称关联
  namespace: default  # 命名空间,必须与使用的Pod一致
spec:
  storageClassName: "local-path"  # 存储类名称,与PV的storageClassName一致(核心匹配条件)
  accessModes:  # 访问模式,与PV的accessModes匹配(核心匹配条件)
    - ReadWriteOnce
  resources:
    requests:
      storage: 250Mi  # 存储容量请求,≤PV的容量(核心匹配条件)
  # 可选:selector标签选择器,仅匹配带有指定标签的PV
  # selector:
  #   matchLabels:
  #     storage-type: local

1. 核心匹配配置项(与 PV 绑定的必要条件)

这三个配置项是 PVC 与 PV 绑定的核心条件必须完全匹配(或满足子集关系),否则无法绑定:

(1)resources.requests.storage:存储容量请求

  • 定义用户需要的存储容量,单位支持Ki(千字节)、Mi(兆字节)、Gi(吉字节)、Ti等;

  • 绑定规则:PVC 的容量请求 ≤ 目标 PV 的容量(如 PVC 请求 250Mi,可绑定 250Mi/500Mi/1Gi 的 PV);

  • 严格按照题目要求配置(如考题 8 要求 250Mi),且需与现有 PV 的容量匹配。

(2)accessModes:访问模式

定义 PVC 对存储资源的访问权限,K8s 支持 3 种标准访问模式,PVC 的访问模式必须是 PV 访问模式的子集(通常完全一致):

访问模式

缩写

核心含义

适用场景

ReadWriteOnce

RWO

该存储只能被一个节点上的一个或多个 Pod读写模式挂载

单实例应用(如 MariaDB、MySQL)、本地存储

ReadOnlyMany

ROX

该存储能被多个节点上的多个 Pod只读模式挂载

静态资源共享(如配置文件、静态网页)

ReadWriteMany

RWX

该存储能被多个节点上的多个 Pod读写模式挂载

多实例应用共享存储(如 NFS、Ceph)

注意:访问模式的支持由底层存储决定,如本地存储仅支持 RWO,NFS 支持 RWO/ROX/RWX,云硬盘(如 EBS)仅支持 RWO。

(3)storageClassName:存储类名称

  • 存储类(StorageClass)是 K8s 中对存储资源的分类标识,管理员可通过 StorageClass 对不同类型的存储进行分组(如 local-path:本地存储、nfs:NFS 存储、ebs:AWS 云硬盘);

  • 绑定规则:PVC 的storageClassName必须与 PV 的 storageClassName 完全一致(若不指定,默认绑定default存储类的 PV,或无存储类的 PV);

2. 可选配置项

(1)selector:标签选择器

用于精准匹配带有指定标签的 PV,支持matchLabels(精确匹配)和matchExpressions(表达式匹配),若配置该字段,PVC 仅会绑定 同时满足「核心匹配条件 + 标签匹配条件」 的 PV:

spec:
  selector:
    matchLabels:
      storage-type: local  # 仅匹配带有storage-type=local标签的PV
      env: test

(2)volumeMode:卷模式

定义存储的使用模式,支持两种:

  • Filesystem(文件系统模式):将 PV 挂载为文件系统,Pod 中以文件 / 目录形式访问(默认模式,绝大多数场景使用);

  • Block(块设备模式):将 PV 作为原始块设备使用,适用于需要直接访问块设备的应用(如数据库底层存储)。

五、PVC 与 PV 的关系(核心绑定逻辑)

PVC 和 PV 是互补的一对资源,共同实现 K8s 的持久化存储管理,两者的关系可总结为 「用户请求 - 资源提供」「动态匹配 - 一对一绑定」,核心绑定逻辑如下:

1. 绑定触发条件

当用户通过kubectl apply -f pvc.yaml创建 PVC 后,K8s 的PV 控制器会立即触发绑定流程,在集群中查找满足 PVC 所有匹配条件的 PV。

2. 绑定匹配顺序

K8s 会按照 「精准匹配优先、容量最适配次之」 的原则查找 PV:

  1. 先筛选出存储类、访问模式与 PVC 完全匹配的 PV;

  2. 再从筛选结果中,选择容量≥PVC 请求容量且最接近的 PV;

  3. 若配置了selector标签,再筛选出带有指定标签的 PV。

3. 绑定状态与结果

  • 绑定成功:PVC 状态变为Bound,PV 的状态也会变为Bound,并在 PV 的spec.claimRef中记录绑定的 PVC 信息(名称、命名空间、UID),形成一对一关联;

  • 绑定失败:PVC 状态变为Pending,K8s 会持续监控集群,直到有符合条件的 PV 被创建,PVC 会自动完成绑定。

4. 解绑与重新绑定

  • 主动解绑:删除 PVC(kubectl delete pvc <pvc-name>),PV 会解除绑定,状态恢复为Available(具体由 PV 的回收策略决定),可被其他 PVC 重新绑定;

  • 被动解绑:若绑定的 PV 被手动删除,PVC 状态变为Lost,无法继续使用,需重新创建 PVC 并绑定新的 PV。

5. 核心区别

特性

PersistentVolumeClaim(PVC)

PersistentVolume(PV)

资源作用域

命名空间级(Namespace-Scoped)

集群级(Cluster-Scoped)

创建者

普通用户 / 应用开发者

集群管理员

核心作用

声明存储需求,请求存储资源

提供实际存储资源,满足 PVC 请求

生命周期

依赖于 PV,独立于 Pod

独立生命周期,不依赖于 Pod/PVC

配置重点

声明需求(容量、访问模式、存储类)

定义实现(存储类型、容量、访问模式、回收策略)

六、PVC 的生命周期

PVC 的生命周期从创建开始,到删除结束,整个生命周期包含5 个状态,通过kubectl get pvc <pvc-name>可查看 PVC 的当前状态,需能通过状态判断 PVC 的绑定和使用情况:

1. Pending(待绑定)

  • 状态含义:PVC 已创建,但集群中无满足匹配条件的 PV,处于等待绑定状态;

  • 常见原因:无匹配的 PV、PV 容量不足、存储类 / 访问模式不匹配;

2. Bound(已绑定)

  • 状态含义:PVC 已成功绑定到符合条件的 PV,可被 Pod 挂载使用,这是 PVC 的正常使用状态

  • 核心特征:PV 的状态同步变为 Bound,PV 的spec.claimRef指向该 PVC。

3. Lost(丢失)

  • 状态含义:PVC 原本已绑定 PV,但绑定的 PV 被手动删除,PVC 失去对应的存储资源,无法继续使用;

  • 处理方式:删除该 PVC,重新创建新的 PVC 并绑定新的 PV。

4. Terminating(正在删除)

  • 状态含义:用户执行了 PVC 删除命令,K8s 正在清理 PVC 的关联资源,处于删除中状态;

  • 若删除卡住,可通过kubectl delete pvc <pvc-name> --force强制删除。

5. Failed(创建失败)

  • 状态含义:PVC 创建过程中出现错误(如配置格式错误、权限不足),创建失败;

  • 处理方式:检查 PVC 的 YAML 配置,修正后重新创建。

七、PVC 的使用流程(K8s 实操通用)

步骤 1:查询现有 PV 的关键属性(核心前提)

若集群中已有管理员创建的 PV,需先通过命令查询 PV 的存储类、容量、访问模式,确保 PVC 配置与 PV 匹配:

kubectl get pv  # 查看所有PV的核心属性
kubectl describe pv <pv-name>  # 查看PV的详细配置(可选)

步骤 2:创建 PVC 配置文件并应用

根据 PV 的属性和业务需求,编写 PVC 的 YAML 配置文件,执行命令创建 PVC:

vim pvc.yaml  # 编写PVC配置
kubectl apply -f pvc.yaml  # 创建PVC

步骤 3:在 Pod/Deployment 中挂载 PVC

将 PVC 挂载到 Pod 的指定路径,核心是在 Pod/Deployment 的spec.template.spec中配置volumesvolumeMounts

# 以Deployment为例,挂载PVC到Pod的/var/lib/mysql路径(MariaDB数据目录)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mariadb
  namespace: mariadb
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: mariadb
        image: mariadb
        volumeMounts:  # 容器内的卷挂载配置
        - name: mariadb-data  # 与volumes中的名称一致
          mountPath: /var/lib/mysql  # 容器内的挂载路径
      volumes:  # 定义卷,关联PVC
      - name: mariadb-data
        persistentVolumeClaim:
          claimName: mariadb  # 要绑定的PVC名称(核心)

执行命令应用配置,启动 Pod:

kubectl apply -f deployment.yaml

步骤 4:验证 PVC 绑定和使用状态

检查 PVC 的状态是否为 Bound,Pod 是否正常运行,确认存储挂载成功:

kubectl get pvc -n <namespace>  # 检查PVC状态(Bound为正常)
kubectl get pod -n <namespace>   # 检查Pod状态(Running为正常)
kubectl exec -it <pod-name> -n <namespace> -- df -h  # 验证容器内挂载路径(可选)

八、PVC 与动态存储供应(拓展)

以上讲解的是静态存储供应(管理员手动创建 PV,用户创建 PVC 绑定),而在实际生产环境中,更多使用动态存储供应(通过 StorageClass 自动创建 PV),核心逻辑是:

  1. 管理员创建StorageClass,配置存储的底层驱动(如 NFS、云硬盘)、默认参数(访问模式、回收策略);

  2. 用户创建 PVC 时,指定该 StorageClass,K8s 会通过存储驱动自动创建符合 PVC 需求的 PV,并完成绑定;

  3. 无需管理员手动创建 PV,实现存储资源的按需动态分配

文章作者: 楚少爱看雪
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 楚少爱看雪
学习 Study
喜欢就支持一下吧