PV 与 PVC
1. 核心概念
-
PV (PersistentVolume):集群中的一块存储资源(由管理员提供或由存储类动态提供),它是集群级别的资源,独立于 Pod 生命周期。
-
PVC (PersistentVolumeClaim):是用户对存储的请求。类似于 Pod 消费 Node 资源一样,PVC 消费 PV 资源。
2. PV 与 PVC 生命周期
-
Provisioning(配置):创建 PV(静态)或通过 StorageClass 动态创建。
-
Binding(绑定):用户创建 PVC,Kubernetes 寻找匹配的 PV 并绑定。
-
Using(使用):Pod 通过 PVC 使用该存储。
-
Releasing(释放):PVC 被删除,PV 状态变为 Released。
-
Reclaiming(回收):根据策略(Retain/Delete/Recycle)处理旧数据。
3. PV 的 4 种状态
-
Available:可用,未被任何 PVC 绑定。
-
Bound:已绑定到一个 PVC。
-
Released:关联的 PVC 已被删除,但资源尚未回收。
-
Failed:自动回收失败。
4. PV 的创建方式
-
静态创建:管理员手动创建 PV 对象。
-
动态创建:通过 StorageClass 自动创建(基于 PVC 请求)。
5. 关键配置字段
PV 配置 (spec字段):
-
capacity: 存储容量 (e.g.,10Gi) -
accessModes: 访问模式 (ReadWriteOnce,ReadOnlyMany,ReadWriteMany) -
persistentVolumeReclaimPolicy: 回收策略 (Retain,Delete,Recycle) -
storageClassName: 关联的存储类名称 -
nfs,awsElasticBlockStore,hostPath等:具体的存储后端配置
PVC 配置 (spec字段):
-
accessModes: 需要的访问模式 -
resources: 资源请求 (requests: { storage: 5Gi }) -
storageClassName: 需要的存储类 -
selector: 标签选择器,用于匹配特定 PV
六、实例:用 NFS 作为存储后端的静态 PV
在实际生产环境中,NFS 是一种非常常见的共享存储方案。下面演示如何将一个现有的 NFS 服务器共享目录封装成 Kubernetes 的 PV(持久卷),供 Pod 挂载使用。
1. 准备环境
假设我们有一台 NFS 服务器,IP 为 192.168.1.100,共享目录为 /data/nfs_share。
确保 Kubernetes 集群的所有节点都已经安装了 NFS 客户端工具(nfs-utils),并且能够挂载该共享目录。
2. 创建静态 PV (PersistentVolume)
创建一个 YAML 文件,定义一个指向 NFS 的 PV。
yaml
nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv-demo
labels:
type: nfs
spec:
capacity:
storage: 10Gi # 容量大小
volumeMode: Filesystem
accessModes:
-
ReadWriteMany # NFS 支持多节点读写
persistentVolumeReclaimPolicy: Retain # 回收策略:保留数据
nfs:
path: /data/nfs_share # NFS 服务器上的共享路径
server: 192.168.1.100 # NFS 服务器地址
字段解释:
-
accessModes:ReadWriteMany表示该存储卷可以被多个节点同时读写,这是 NFS 的典型特征。 -
persistentVolumeReclaimPolicy:Retain表示当 PVC 被删除后,PV 不会被自动删除,数据会被保留,需要管理员手动清理。
创建命令:
bash
kubectl apply -f nfs-pv.yaml
kubectl get pv nfs-pv-demo
3. 创建 PVC (PersistentVolumeClaim)
创建一个 PVC 来申请上述 PV 的资源。
yaml
nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc-demo
spec:
accessModes:
-
ReadWriteMany
resources:
requests:
storage: 5Gi # 请求 5Gi 空间
storageClassName: "" # 如果有默认的 StorageClass,这里可以留空或指定
selector:
matchLabels:
type: nfs # 匹配 PV 的 label
创建命令:
bash
kubectl apply -f nfs-pvc.yaml
kubectl get pvc nfs-pvc-demo
kubectl get pv nfs-pv-demo # 观察状态是否变为 Bound
4. 创建 Pod 使用 PVC
创建一个 Pod,将 PVC 挂载到容器内部。
yaml
nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod-demo
spec:
containers:
-
name: nginx
image: nginx
volumeMounts:
-
name: nfs-storage
mountPath: /usr/share/nginx/html # 容器内挂载路径
volumes:
-
-
name: nfs-storage
persistentVolumeClaim:
claimName: nfs-pvc-demo # 引用上面创建的 PVC
创建命令:
bash
kubectl apply -f nfs-pod.yaml
验证命令:
bash
进入 Pod 查看是否能看到 NFS 共享目录的内容
kubectl exec nfs-pod-demo -it -- ls /usr/share/nginx/html
在 NFS 服务器上创建一个测试文件
echo "Hello from NFS" > /data/nfs_share/index.html
然后在 Pod 内查看是否能读取到
kubectl exec nfs-pod-demo -it -- cat /usr/share/nginx/html/index.html
七、存储卷类型对比
| 类型 | 生命周期 | 持久性 | 跨节点 | 适用场景 |
|---|---|---|---|---|
| emptyDir | 与 Pod 一致 | ❌ | ❌ | 临时缓存、容器间通信 |
| hostPath | 与节点一致 | ✅(节点级) | ❌ | 日志采集、系统配置 |
| NFS | 独立于 Pod | ✅ | ✅ | 多 Pod 共享存储 |
| PV / PVC | 独立于 Pod | ✅ | 视后端而定 | 通用持久化存储 |
八、静态创建 PV 与动态创建 PV 对比
| 维度 | 静态创建 PV | 动态创建 PV |
|---|---|---|
| 创建者 | 管理员手动创建 | Kubernetes 根据 PVC 自动创建 |
| 灵活性 | 低,需预先规划 | 高,按需分配 |
| 适用场景 | 固定存储资源、已有存储设备 | 云环境、弹性存储需求 |
| 依赖 | 需要预先存在存储资源 | 需要配置 StorageClass |
| 复杂度 | 高(需管理 PV 和 PVC 匹配) | 低(只需管理 PVC) |
九、总结
-
Volume 是 Kubernetes 中解决容器数据持久化的核心机制。
-
PV/PVC 解耦了存储资源和 Pod,使存储管理更加灵活。
-
NFS 是一种常用的共享存储后端,适合多 Pod 共享数据。
-
静态 PV 适合已有存储资源的场景,动态 PV 适合云原生弹性存储场景。
📌 最佳实践 :生产环境中推荐使用 动态 PV + StorageClass,减少人工干预,提高资源利用率。