铜陵市网站建设_网站建设公司_C#_seo优化
2026/1/16 6:34:36 网站建设 项目流程

目录

前言

一、先搞懂:K8s 基础存储卷(Volume)

1. emptyDir:Pod 级临时存储

二、PV 与 PVC:存储资源的 “供需分离”

1. 核心概念与角色分工

2. 关键配置详解

(1)访问模式(accessModes)

(2)回收策略(persistentVolumeReclaimPolicy)

3. PV 与 PVC 的生命周期

三、实战:NFS + PV + PVC 静态存储部署

1. 前置准备:部署 NFS 服务端

创建共享目录

配置NFS共享

生效配置

2. 运维视角:创建 PV

3. 开发者视角:创建 PVC 与 Pod

实现PVC和Pod的创建与测试

操作步骤

四、进阶:StorageClass 动态存储方案

1. 核心原理

2. 动态存储部署步骤

(1)配置 RBAC 权限

(2)部署 NFS Provisioner

(3)创建 StorageClass

(4)测试动态存储

操作流程

五、不同存储方案对比与选型建议

选型核心建议:

六、总结


前言

在 Kubernetes(K8s)集群中,容器的文件系统默认是临时性的 —— 容器崩溃重启后数据会丢失,同一 Pod 内的多个容器也无法直接共享文件。为了解决这两个核心问题,K8s 引入了Volume抽象,而PV(Persistent Volume,持久化存储卷)PVC(Persistent Volume Claim,持久化存储请求)则是在Volume基础上进一步优化的持久化存储方案,让存储管理更灵活、更符合生产环境需求。本文将从基础存储卷入手,逐步深入 PV/PVC 的核心机制、实战配置与动态存储方案。

一、先搞懂:K8s 基础存储卷(Volume)

在学习 PV/PVC 之前,先了解 K8s 原生的三种基础存储卷,它们是 PV/PVC 的技术基础,各自适用于不同场景:

1. emptyDir:Pod 级临时存储

  • 核心特点:Pod 调度到节点时自动创建,Pod 删除后数据随之销毁,仅支持同一 Pod 内的容器共享。
  • 适用场景:临时缓存、容器间临时数据交换(如日志转发、临时计算结果存储)。
  • 简单示例:两个容器共享emptyDir卷,一个写入日期,一个通过 Nginx 提供访问:
    apiVersion: v1 kind: Pod metadata: name: pod-emptydir spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ - name: busybox image: busybox:latest volumeMounts: - name: html mountPath: /data/ command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done'] volumes: - name: html emptyDir: {}

    二、PV 与 PVC:存储资源的 “供需分离”

    基础存储卷虽然解决了临时共享和单节点持久化问题,但在生产环境中存在明显短板:

  • 开发者需要关心底层存储细节(如 NFS 服务器地址、挂载路径),耦合度高;
  • 存储资源无法统一管理,权限控制复杂;
  • 无法动态分配存储,扩展性差。

PV 与 PVC 的核心设计理念是 **“供需分离”**:运维人员统一管理底层存储资源(定义 PV),开发者只需声明存储需求(创建 PVC),K8s 自动完成 PVC 与 PV 的绑定,开发者无需关注底层存储实现。

1. 核心概念与角色分工

组件作用维护者核心配置
PV定义底层存储资源(如 NFS 路径、容量、访问模式)运维工程师存储类型(nfs/hostPath)、容量(capacity)、访问模式(accessModes)、回收策略(persistentVolumeReclaimPolicy)
PVC声明存储需求(如容量、访问模式)应用开发者申请容量(storage)、访问模式、存储类(storageClassName)
StorageClass提供动态创建 PV 的模板(可选)运维工程师关联存储分配器(Provisioner)、默认回收策略

2. 关键配置详解

(1)访问模式(accessModes)

定义存储卷的访问权限,PV 与 PVC 的访问模式必须匹配(PVC 的访问模式需是 PV 的子集):

  • ReadWriteOnce(RWO):可读可写,仅支持单个 Pod 挂载(所有存储类型均支持);
  • ReadOnlyMany(ROX):只读,支持多个 Pod 挂载(NFS、GlusterFS 等支持);
  • ReadWriteMany(RWX):可读可写,支持多个 Pod 共享(仅 NFS、Ceph 等分布式存储支持)。

(2)回收策略(persistentVolumeReclaimPolicy)

PV 被 PVC 释放后的处理方式:

  • Retain(保留):保留数据,需手动清理(适合重要数据,避免误删);
  • Delete(删除):自动删除底层存储资源(仅云存储如 AWS EBS、Azure Disk 支持);
  • Recycle(回收):清空数据后重新变为可用(仅 NFS/HostPath 支持,已逐步废弃)。

3. PV 与 PVC 的生命周期

  1. Provisioning(配置):运维手动创建 PV(静态),或通过 StorageClass 动态创建;
  2. Binding(绑定):K8s 根据 PVC 的需求(容量、访问模式)匹配可用 PV,绑定后 PV 状态变为Bound
  3. Using(使用):Pod 通过 PVC 挂载存储卷,持续使用直至 Pod 销毁;
  4. Releasing(释放):删除 PVC 后,PV 状态变为Released,数据保留;
  5. Recycling(回收):根据回收策略处理 PV(保留 / 删除 / 清空),处理后状态变为Available可重新绑定。

三、实战:NFS + PV + PVC 静态存储部署

下面通过 “NFS 作为底层存储,手动创建 PV,开发者通过 PVC 申请” 的流程,实现集群级持久化存储。

1. 前置准备:部署 NFS 服务端

假设 NFS 服务端地址为stor01(192.168.10.13),创建 5 个共享目录供 PV 使用:

使用以下命令安装NFS服务和依赖组件:

yum install -y nfs-utils rpcbind

启动并设置开机自启NFS和RPC服务:

systemctl start rpcbind nfs systemctl enable rpcbind nfs

创建共享目录

创建多个共享目录并设置权限:

mkdir -p /data/volumes/v{1..5} chmod 777 /data/volumes/*

配置NFS共享

编辑/etc/exports文件,配置集群网段访问权限:

vim /etc/exports

文件内容示例:

/data/volumes/v1 192.168.10.0/24(rw,no_root_squash) /data/volumes/v2 192.168.10.0/24(rw,no_root_squash) /data/volumes/v3 192.168.10.0/24(rw,no_root_squash) /data/volumes/v4 192.168.10.0/24(rw,no_root_squash) /data/volumes/v5 192.168.10.0/24(rw,no_root_squash)

生效配置

重新加载NFS配置使更改生效:

exportfs -arv

2. 运维视角:创建 PV

定义 5 个 PV,分别对应 NFS 的 5 个共享目录,配置不同容量和访问模式:

apiVersion: v1 kind: PersistentVolume metadata: name: pv003 spec: nfs: path: /data/volumes/v3 server: stor01 accessModes: ["ReadWriteOnce"] capacity: storage: 2Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv004 spec: nfs: path: /data/volumes/v4 server: stor01 accessModes: ["ReadWriteMany"] capacity: storage: 4Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv005 spec: nfs: path: /data/volumes/v5 server: stor01 accessModes: ["ReadWriteOnce"] capacity: storage: 5Gi persistentVolumeReclaimPolicy: Retain

执行创建命令并查看 PV 状态:

kubectl apply -f pv-demo.yaml kubectl get pv

3. 开发者视角:创建 PVC 与 Pod

开发者无需关心 NFS 地址和路径,只需声明 “2Gi 容量、支持 RWX 访问” 的需求:

apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc spec: accessModes: ["ReadWriteMany"] storageClassName: "standard" # 指定存储类,动态分配存储 resources: requests: storage: 2Gi --- apiVersion: v1 kind: Pod metadata: name: pod-vol-pvc spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html command: ["/bin/sh", "-c"] # 添加启动命令 args: - while true; do echo "$(date) - Hello from PVC" > /usr/share/nginx/html/index.html; sleep 10; done volumes: - name: html persistentVolumeClaim: claimName: mypvc

执行部署并验证:

实现PVC和Pod的创建与测试

以下是使用Kubernetes YAML文件创建PVC和Pod,并测试数据持久化的完整代码示例:

操作步骤

执行以下命令部署PVC和Pod:

kubectl apply -f pod-vol-pvc.yaml

验证PVC状态(应显示Bound状态):

kubectl get pvc

在NFS服务端创建测试文件(假设PV对应的路径是/data/volumes/v3):

echo "welcome to use pv3" > /data/volumes/v3/index.html

验证数据持久化效果:

kubectl get pods -o wide curl <Pod_IP>

四、进阶:StorageClass 动态存储方案

静态 PV 方案需要运维手动创建大量 PV,不适用于大规模集群。StorageClass通过 “存储分配器(Provisioner)” 实现 PV 的动态创建 —— 开发者创建 PVC 后,K8s 自动生成对应的 PV 和 NFS 共享目录,大幅降低运维成本。

1. 核心原理

  • StorageClass:定义动态 PV 的模板(关联 Provisioner、回收策略等);
  • Provisioner:存储分配器(如nfs-client-provisioner),负责与 NFS 服务端交互,自动创建共享目录和 PV;
  • RBAC权限:授权 Provisioner 操作 PV、PVC、StorageClass 等资源的权限。

2. 动态存储部署步骤

(1)配置 RBAC 权限

创建 ServiceAccount 和集群角色,授权 Provisioner 管理存储资源:

apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: nfs-client-provisioner-clusterrole rules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: nfs-client-provisioner-clusterrolebinding subjects: - kind: ServiceAccount name: nfs-client-provisioner namespace: default roleRef: kind: ClusterRole name: nfs-client-provisioner-clusterrole apiGroup: rbac.authorization.k8s.io

(2)部署 NFS Provisioner

Provisioner 是动态创建 PV 的核心组件,需关联 NFS 服务端:

apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner spec: replicas: 1 selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: quay.io/external_storage/nfs-client-provisioner:latest env: - name: PROVISIONER_NAME value: nfs-storage - name: NFS_SERVER value: stor01 - name: NFS_PATH value: /opt/k8s volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes volumes: - name: nfs-client-root nfs: server: stor01 path: /opt/k8s

(3)创建 StorageClass

apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client annotations: storageclass.kubernetes.io/is-default-class: "false" # 设为false避免冲突 provisioner: k8s-sigs.io/nfs-subdir-external-provisioner parameters: archiveOnDelete: "false" # true保留PVC数据,false自动删除 pathPattern: "${.PVC.namespace}/${.PVC.name}" # 存储路径命名规则 onDelete: "delete" # 保留策略:delete/retain/archive mountOptions: - nfsvers=4.1 # 指定NFS协议版本 - noatime # 禁用访问时间更新 allowVolumeExpansion: true # 允许动态扩容 reclaimPolicy: Delete # 回收策略:Delete/Retain volumeBindingMode: Immediate # 绑定模式:Immediate/WaitForFirstConsumer

(4)测试动态存储

创建 PVC 时指定storageClassName,K8s 自动生成 PV:

apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-nfs-pvc spec: accessModes: ["ReadWriteMany"] storageClassName: nfs-client-storageclass resources: requests: storage: 1Gi --- apiVersion: v1 kind: Pod metadata: name: test-storageclass-pod spec: containers: - name: busybox image: busybox:latest command: ["/bin/sh", "-c", "sleep 3600"] volumeMounts: - name: nfs-pvc mountPath: /mnt volumes: - name: nfs-pvc persistentVolumeClaim: claimName: test-nfs-pvc

验证动态创建结果:

操作流程

部署存储类和PVC

kubectl apply -f storageclass-nfs.yaml

验证PVC绑定状态

kubectl get pvc test-nfs-pvc # 预期输出显示STATUS为Bound,VOLUME为自动生成的PV名称

检查NFS服务端共享目录

ls /opt/k8s/ # 应出现格式为{namespace}-{pvcName}-{pvName}的目录

测试数据共享功能

kubectl exec -it test-storageclass-pod -- sh -c 'echo "dynamic storage test" > /mnt/test.txt'

验证NFS端数据同步

cat /opt/k8s/default-test-nfs-pvc-*/test.txt # 应显示"dynamic storage test"内容

五、不同存储方案对比与选型建议

存储类型生命周期共享性持久性适用场景
emptyDirPod 级同 Pod 内容器临时缓存、容器间临时数据交换
hostPath节点级单节点本地测试、节点日志存储
NFS独立服务多节点集群共享存储(无动态需求)
PV + PVC集群级按需分配生产环境(静态存储管理)
StorageClass动态创建多节点动态分配大规模集群、云原生生产环境

选型核心建议:

  1. 开发 / 测试环境:用emptyDir(临时)或hostPath(简单持久化);
  2. 小规模生产环境:NFS + PV + PVC(静态管理,运维成本低);
  3. 大规模生产环境:StorageClass + NFS/Ceph(动态分配,适配弹性扩缩容)。

六、总结

PV 与 PVC 通过 “供需分离” 的设计,让运维专注于底层存储管理,开发者专注于业务存储需求,大幅提升了 K8s 存储的灵活性和可维护性。而 StorageClass 则进一步实现了 PV 的动态创建,完美适配大规模集群的存储需求。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询