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,避免跨节点调度导致挂载失败。