16.5.2 PersistentVolume与PersistentVolumeClaim机制

PersistentVolume(PV)是集群级别的存储资源抽象,由管理员或存储系统预先提供;PersistentVolumeClaim(PVC)是用户对存储的声明,通过申请容量、访问模式与存储类等条件来绑定合适的 PV。PV 与 PVC 解耦,使应用无需关心底层存储实现,实现统一管理与复用。

原理草图(绑定流程)

文章图片

核心对象与职责
- PV:描述存储能力与属性,如容量、访问模式、回收策略、挂载参数等。
- PVC:描述应用所需的存储需求,作为 Pod 挂载的入口。
- StorageClass(可选):用于动态供给时的存储类选择与参数传递。

PV 关键字段与含义
- capacity:容量大小,决定可满足的 PVC 请求。
- accessModes:访问模式(RWO/ROX/RWX),决定可被挂载方式。
- reclaimPolicy:回收策略(Retain/Delete/Recycle),影响 PVC 删除后的数据保留与清理行为。
- volumeMode:块设备或文件系统(Block/Filesystem)。
- nodeAffinity:限制 PV 可被哪些节点使用,常见于本地存储。
- volumeSource:具体存储类型与参数(NFS/iSCSI/CSI 等)。

PVC 关键字段与含义
- resources.requests.storage:申请的存储容量。
- accessModes:与 PV 对齐的访问模式需求。
- storageClassName:指定或绑定存储类。
- volumeMode:需与 PV 匹配。

示例:基于 NFS 的 PV/PVC 全流程(含安装与验证)

1)后端安装 NFS(示例:nfs-server)

# nfs-server 上执行
sudo yum -y install nfs-utils
sudo mkdir -p /data/k8s-nfs
sudo chown -R nfsnobody:nfsnobody /data/k8s-nfs

# /etc/exports 增加共享
echo "/data/k8s-nfs *(rw,sync,no_root_squash)" | sudo tee -a /etc/exports

sudo systemctl enable --now nfs-server
sudo exportfs -rav

命令解释
- exportfs -rav:重新导出共享目录;
- no_root_squash:允许客户端 root 写入(生产需谨慎)。

2)Kubernetes 创建 PV 与 PVC

# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-10g
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  volumeMode: Filesystem
  nfs:
    server: 10.10.0.10
    path: /data/k8s-nfs
---
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-nfs-5g
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
kubectl get pv,pvc

预期效果:PV 状态 Available -> Bound,PVC 状态 Bound

3)Pod 挂载 PVC 并验证

# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: demo-pvc
spec:
  containers:
  - name: busybox
    image: busybox:1.36
    command: ["/bin/sh", "-c", "echo hello > /data/hello.txt; sleep 3600"]
    volumeMounts:
    - mountPath: /data
      name: data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: pvc-nfs-5g
kubectl apply -f pod.yaml
kubectl exec demo-pvc -- cat /data/hello.txt

预期输出hello

关键命令速查与解释

kubectl get pv,pvc              # 查看状态(Available/Bound)
kubectl describe pvc pvc-nfs-5g  # 查看绑定条件、事件
kubectl describe pv pv-nfs-10g   # 查看容量、回收策略、后端信息
kubectl get events --sort-by=.metadata.creationTimestamp  # 排查事件

常见问题与排查(含命令)
- PVC 一直 Pending
- 可能原因:无可用 PV、访问模式/容量不匹配、StorageClass 不存在。
- 排查:
bash kubectl describe pvc pvc-nfs-5g kubectl get pv -o wide
- Pod 挂载失败
- 可能原因:NFS 不通、权限不足、CSI 驱动异常、nodeAffinity 限制。
- 排查:
bash kubectl describe pod demo-pvc showmount -e 10.10.0.10 # 在节点上验证 NFS 共享
- 数据丢失
- 可能原因:reclaimPolicy=Delete 导致 PVC 删除后数据被清理。
- 建议:生产环境对关键数据使用 Retain

练习
1. 将 PVC 容量从 5Gi 调整到 8Gi,观察是否可扩容(需支持扩容的 StorageClass)。
2. 将 PV 的回收策略从 Retain 改为 Delete,删除 PVC 后验证数据是否还在。
3. 创建第二个 Pod 挂载同一 PVC(RWX),验证多 Pod 读写(如写入不同文件)。

最佳实践
- 生产环境优先使用动态供给与统一 StorageClass 管理。
- 关键数据设置 Retain,并结合备份/迁移策略。
- 访问模式与容量规划要匹配应用特性,避免 RWO 多 Pod 误用。
- 对本地存储设置 nodeAffinity,避免跨节点调度导致挂载失败。