K8s 存储核心:PV 与 PVC 实战详解(附 NFS+PV+PVC 完整实操)
初学 K8s 存储时,很多新手都会被 PV、PVC 的概念绕晕:什么是 PV?什么是 PVC?两者怎么绑定?NFS 和它们是什么关系?今天结合我自己的完整实操流程,用通俗的语言,一次性讲透 PV 与 PVC 的核心逻辑,新手跟着做就能上手,彻底搞懂 K8s 持久化存储!
先抛核心结论(面试必背,直接背):PV(持久卷)是 K8s 集群级的公共存储资源,由管理员预先创建,独立于 Pod 生命周期;PVC(持久卷申领)是 Pod 对存储的 “申请单”,Pod 不能直接用 PV,必须通过 PVC 绑定 PV 后,才能挂载使用;绑定后 PV 会被 PVC 独占,数据随 PV 永久保留,不会随 Pod 删除而丢失。
一、先搞懂核心概念(通俗大白话)
1. PV(PersistentVolume,持久卷)
- 本质:集群里的 “公共硬盘”,由管理员提前创建,不归任何节点、任何 Pod 独有。
- 核心特性:集群公共资源,由 kube-controller-manager 统一管理,API Server 仅存储配置,kubelet 仅负责挂载;生命周期独立,Pod 删除后 PV 和数据依然保留。
- 常见后端:NFS、Ceph、云厂商硬盘(阿里云 / 腾讯云)等,本次实验用 NFS 模拟共享存储。
2. PVC(PersistentVolumeClaim,持久卷申领)
- 本质:Pod 对 PV 的 “申请单”,就像你去银行办业务,不能直接用银行的保险柜,必须先填申请单。
- 绑定规则:一对一绑定,PVC 申请的存储容量只要≤PV 容量,就能匹配绑定;绑定后 PV 会被该 PVC 独占,无法再被其他 PVC 使用,哪怕只申请了 1G,绑定 5G 的 PV 后,剩下的 4G 也不能再被使用。
3. 两者关系(一句话串起来)
NFS(真实存储)→ PV(集群公共硬盘)→ PVC(Pod 的申请单)→ Pod(挂载使用存储)
二、完整实操流程(纯 bash 命令,可直接复制运行)
本次实验用 NFS 作为后端存储,创建 PV、PVC,再用 Nginx Pod 挂载验证,全程纯 bash 命令,新手零障碍上手。
步骤 1:搭建 NFS 服务器(真实存储,Master 节点执行)
先在 Master 节点搭建 NFS 共享目录,作为 PV 的真实存储位置:
# 安装NFS服务端
apt install nfs-kernel-server -y
# 创建共享目录
mkdir /nfsshare
chmod 777 /nfsshare -R
# 配置NFS共享权限(允许所有节点读写)
echo '/nfsshare *(rw,sync,no_subtree_check,no_root_squash)' >> /etc/exports
# 启动并设置开机自启
systemctl enable nfs-server --now
# 验证NFS共享配置是否生效
exportfs -rav
showmount -e localhost
步骤 2:安装 NFS 客户端(所有 Worker 节点执行)
集群所有节点都需要安装 NFS 客户端,才能挂载 NFS 共享目录:
# 安装NFS客户端(所有Worker节点执行)
apt install nfs-common -y
步骤 3:创建 PV(集群公共硬盘,Master 节点执行)
通过 kubectl apply -f 创建 PV,这里用cat >方式写入配置文件,再执行创建命令:
# 1. 写入PV配置文件(定义5G容量的NFS类型PV)
cat > pv.yml <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv
labels:
pvname: nfspv
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /nfsshare
server: 192.168.30.130 # 替换为你的Master节点IP
EOF
# 2. 创建PV
kubectl create -f pv.yml
# 3. 查看PV状态(确认状态为Available)
kubectl get pv
步骤 4:创建 PVC(Pod 的存储申请单,Master 节点执行)
创建 PVC,申请 1G 存储,通过标签选择器匹配上面的 nfspv:
# 1. 写入PVC配置文件(申请1G存储,匹配nfspv)
cat > pvc.yml <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: slow
selector:
matchLabels:
pvname: "nfspv"
EOF
# 2. 创建PVC
kubectl create -f pvc.yml
# 3. 查看PVC状态(确认状态为Bound,已成功绑定nfspv)
kubectl get pvc
此时你会发现,PVC 显示的容量是 5Gi,而不是申请的 1Gi—— 这是正常现象,因为 PV 是不可分割的整体,绑定后会被 PVC 独占全部容量。
步骤 5:创建 Pod 挂载 PVC(验证存储使用,Master 节点执行)
创建 Nginx Pod,将 PVC 挂载到网页根目录,验证数据读写:
# 1. 写入Pod配置文件(挂载PVC到Nginx网页目录)
cat > pvcuse.yml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: httpd
imagePullPolicy: IfNotPresent
ports:
- name: web
containerPort: 80
volumeMounts:
- mountPath: "/usr/local/apache2/htdocs"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
EOF
# 2. 创建Pod
kubectl create -f pvcuse.yml
# 3. 查看Pod状态(确认处于Running状态)
kubectl get -f pvcuse.yml -o wide
步骤 6:验证数据持久化(核心步骤)
在 NFS 共享目录写入网页文件,访问 Pod 验证是否能读取,再删除 Pod 验证数据是否保留:
# 1. 在NFS共享目录写入测试文件
echo pvctest! > /nfsshare/index.html
# 2. 访问Pod IP,验证数据是否读取成功(替换为你的Pod IP)
curl http://172.16.245.19
# 3. 删除Pod,验证数据是否保留
kubectl delete -f pvcuse.yml
# 4. 重新查看NFS目录,数据依然存在
cat /nfsshare/index.html
三、核心知识点详解(面试必背)
1. PV 的 4 种访问模式
定义了卷的挂载权限和范围,本次实验用的是 ReadWriteOnce:
- ReadWriteOnce(RWO):卷仅能被单个节点以读写方式挂载,同一节点上的多个 Pod 可共享访问;
- ReadOnlyMany(ROX):卷可被多个节点以只读方式挂载,所有节点的 Pod 仅能读取数据;
- ReadWriteMany(RWX):卷可被多个节点以读写方式挂载,NFS、Ceph 等存储支持该模式;
- ReadWriteOncePod(RWOP):K8s 1.23 + 新增,仅能被单个 Pod 以读写方式挂载,彻底避免数据竞争。
2. PV 的 3 种回收策略
定义了 PVC 删除后,PV 和数据的处理方式,本次实验用的是 Retain:
- Retain(保留):PVC 删除后,PV 状态变为 Released,数据和 PV 均保留,需手动清理后才能复用;
- Delete(删除):PVC 删除后,自动删除 PV 和后端存储数据(云厂商存储、CSI 存储支持);
- Recycle(废弃):旧版策略,PVC 删除后清空卷内数据,新版 K8s 已不推荐使用。
3. PV 的生命周期状态
- Available:空闲状态,未被任何 PVC 绑定;
- Bound:已被 PVC 绑定,处于使用中;
- Released:PVC 已删除,PV 等待回收;
- Failed:自动回收操作失败,需管理员处理。
四、新手常见误区避坑
-
误区 1:PVC 申请 1G,PV 是 5G,只能用 1G?纠正:不能!PV 是不可分割的整体,绑定后 PVC 会独占全部 5G 容量,剩下的 4G 无法再被其他 PVC 使用。
-
误区 2:删除 Pod,PV 和数据会被删除?纠正:不会!PV 生命周期独立于 Pod,删除 Pod 只会解除 PVC 与 Pod 的挂载,PVC 和 PV 依然存在,数据永久保留在 NFS 服务器上。
-
误区 3:PVC 可以跨节点共享同一个 PV?纠正:不能!PVC 与 PV 是一对一绑定,一个 PV 只能被一个 PVC 绑定,一个 PVC 也只能被一个 Pod 挂载(RWO 模式下)。
五、实验清理(按需执行)
实验完成后,可按需求清理资源,保留 NFS 共享目录可复用:
# 1. 删除Pod、PVC、PV
kubectl delete -f pvcuse.yml
kubectl delete -f pvc.yml
kubectl delete -f pv.yml
# 2. 可选:清理NFS共享目录(谨慎操作,避免删除有用数据)
rm -rf /nfsshare/*
六、总结
PV 与 PVC 是 K8s 实现持久化存储的核心,核心逻辑就是 “公共硬盘(PV)+ 申请单(PVC)+ 挂载使用(Pod)”,数据随 PV 永久保留,不会随 Pod 删除而丢失。本次实验用 NFS 模拟后端存储,完整演示了 PV 与 PVC 的创建、绑定、使用和验证流程,新手跟着做就能快速掌握。
如果在实操过程中遇到 PV 无法绑定、Pod 无法挂载、NFS 访问失败等问题,欢迎在评论区留言,我会一一回复!觉得有用的话,记得点赞 + 收藏,关注我,后续分享更多 K8s 存储干货~
更多推荐



所有评论(0)