1. 什么是 PV(PersistentVolume)?
PV(PersistentVolume) 是 Kubernetes 中表示持久化存储资源的对象。它抽象了底层存储系统的细节(如云存储、NFS、本地磁盘等),允许用户通过声明式配置(YAML)使用存储资源,而无需关心存储的具体实现。
核心特点
• 集群级资源 :由管理员预先创建或通过 StorageClass
动态生成。
• 与存储后端解耦 :支持多种存储类型(如 AWS EBS、NFS、HostPath 等)。
• 生命周期独立于 Pod :Pod 删除后,PV 及其数据仍然保留。
• 需通过 PVC(PersistentVolumeClaim)绑定:用户通过 PVC 申请存储资源,PVC 会匹配并绑定到符合条件的 PV。
2. 在 Linux 系统中创建 PV 的步骤
在 Kubernetes 中创建 PV 不直接依赖 Linux 系统本身的操作,而是通过 Kubernetes API 定义。以下是常见的几种 PV 类型及其配置方法:
场景 1:使用 hostPath
(节点本地目录)
适用场景
• 开发测试环境。
• 单节点集群(如 Minikube)。
步骤
-
在 Linux 节点上创建目录:
bashsudo mkdir -p /mnt/data sudo chmod 777 /mnt/data # 确保容器有写入权限
-
定义 PV YAML 文件:
yaml# hostpath-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-hostpath spec: capacity: storage: 10Gi # 存储容量 accessModes: - ReadWriteOnce # 访问模式(单节点读写) persistentVolumeReclaimPolicy: Retain # 回收策略(保留数据) hostPath: path: /mnt/data # 节点本地目录 type: DirectoryOrCreate # 目录不存在则自动创建
-
创建 PV:
bashkubectl apply -f hostpath-pv.yaml
-
验证:
bashkubectl get pv # 输出示例: # NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM # pv-hostpath 10Gi RWO Retain Available
场景 2:使用 NFS(网络共享存储)
适用场景
• 多节点集群共享存储。
• 需要跨节点读写数据的应用(如文件服务器)。
步骤
-
在 Linux 系统中配置 NFS 服务端:
bash# 在 NFS 服务器上操作 sudo apt install nfs-kernel-server sudo mkdir -p /nfs_share sudo chmod 777 /nfs_share echo "/nfs_share *(rw,sync,no_subtree_check)" | sudo tee -a /etc/exports sudo systemctl restart nfs-server
-
定义 PV YAML 文件:
yaml# nfs-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs spec: capacity: storage: 100Gi # 存储容量 accessModes: - ReadWriteMany # 多节点读写 persistentVolumeReclaimPolicy: Retain nfs: server: 192.168.1.100 # NFS 服务器 IP path: /nfs_share # NFS 共享目录
-
创建 PV:
bashkubectl apply -f nfs-pv.yaml
场景 3:使用本地卷(Local Volume)
适用场景
• 需要高性能本地存储(如数据库)。
• 使用本地磁盘或 SSD。
步骤
-
在节点上准备磁盘或目录:
bashsudo mkdir -p /mnt/local-ssd sudo chmod 777 /mnt/local-ssd
-
定义 PV YAML 文件:
yaml# local-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-local spec: capacity: storage: 500Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain local: path: /mnt/local-ssd # 本地目录 nodeAffinity: # 限制 PV 只能被调度到特定节点 required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node1 # 节点名称
-
创建 PV:
bashkubectl apply -f local-pv.yaml
3. PV 的关键配置参数
(1) 访问模式(Access Modes)
• ReadWriteOnce (RWO) :单节点读写。
• ReadOnlyMany (ROX) :多节点只读。
• ReadWriteMany (RWX):多节点读写。
(2) 回收策略(Reclaim Policy)
• Retain :删除 PVC 后保留 PV 和数据(需手动清理)。
• Delete :自动删除 PV 和底层存储(仅限动态供给的云存储)。
• Recycle(已废弃):擦除数据后重新绑定。
(3) 存储类别(StorageClass)
• 动态供给 PV 时需指定 StorageClass
,静态 PV 可省略或设为空字符串。
4. 验证 PV 绑定到 PVC
-
创建 PVC:
yaml# pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi # storageClassName: "" # 空字符串表示使用静态 PV
-
绑定 PV:
bashkubectl apply -f pvc.yaml kubectl get pv,pvc # 输出示例: # NAME STATUS CLAIM CAPACITY # pv-hostpath Bound default/my-pvc 10Gi
5. 常见问题
(1) PV 无法绑定到 PVC
• 原因 :PVC 的 accessModes
、storage
或 storageClassName
不匹配。
• 解决:检查 PV 和 PVC 的配置是否一致。
(2) 容器无法写入 PV
• 原因 :目录权限不足或存储后端故障。
• 解决:
bash
kubectl exec -it <pod-name> -- ls -l /data # 检查挂载点权限
kubectl describe pv <pv-name> # 查看 PV 事件日志
总结
• PV 是存储资源的抽象 :由管理员创建或动态供给,供应用通过 PVC 申请。
• 常用 PV 类型 :hostPath
(本地目录)、nfs
(网络存储)、local
(高性能本地盘)。
• 关键配置 :访问模式、容量、回收策略和节点亲和性(Local PV)。
• 操作流程:定义 PV → 创建 PVC → 挂载到 Pod。
在 Kubernetes 中配置存储的核心是通过 持久化存储卷(Persistent Volume, PV) 和 持久化存储声明(Persistent Volume Claim, PVC) 实现数据持久化和动态管理。以下是详细的存储配置指南:
1. 核心概念
概念 | 作用 |
---|---|
PersistentVolume (PV) | 集群级别的存储资源(如云存储、NFS、本地磁盘),由管理员创建或动态生成。 |
PersistentVolumeClaim (PVC) | 用户对存储资源的申请,指定容量、访问模式等要求,绑定到 PV。 |
StorageClass (SC) | 动态生成 PV 的模板(如 AWS EBS、GCP PD),按需创建存储资源。 |
2. 存储配置步骤
(1) 静态供给(手动创建 PV)
场景:已有存储资源(如 NFS、本地磁盘),需手动绑定。
步骤:
-
创建 PV(以 NFS 为例):
yaml# nfs-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs spec: capacity: storage: 10Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain nfs: server: 192.168.1.100 path: /data/nfs
bashkubectl apply -f nfs-pv.yaml
-
创建 PVC(匹配 PV):
yaml# pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nfs spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: "" # 空字符串表示手动绑定
bashkubectl apply -f pvc.yaml
-
挂载到 Pod:
yaml# pod.yaml apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: app image: nginx volumeMounts: - name: nfs-volume mountPath: /usr/share/nginx/html volumes: - name: nfs-volume persistentVolumeClaim: claimName: pvc-nfs
(2) 动态供给(自动创建 PV)
场景:使用云存储(如 AWS EBS、GCP PD),按需自动生成 PV。
步骤:
-
创建 StorageClass:
yaml# storageclass-aws.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: aws-gp3 provisioner: ebs.csi.aws.com parameters: type: gp3 volumeBindingMode: WaitForFirstConsumer # 延迟绑定到 Pod 调度 reclaimPolicy: Delete
bashkubectl apply -f storageclass-aws.yaml
-
创建 PVC(触发动态供给):
yaml# pvc-dynamic.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-dynamic spec: accessModes: - ReadWriteOnce resources: requests: storage: 50Gi storageClassName: aws-gp3 # 引用 StorageClass
bashkubectl apply -f pvc-dynamic.yaml
-
挂载到 Deployment:
yaml# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: web-app spec: template: spec: containers: - name: nginx image: nginx volumeMounts: - name: dynamic-storage mountPath: /data volumes: - name: dynamic-storage persistentVolumeClaim: claimName: pvc-dynamic
3. 存储类型与适用场景
存储类型 | 配置方式 | 适用场景 | 示例 |
---|---|---|---|
临时存储 | emptyDir |
容器间共享临时数据(如缓存) | 日志处理中间结果 |
本地存储 | hostPath 或 local |
开发测试、单节点高性能存储 | 本地数据库、测试环境 |
网络存储 | NFS/CephFS | 多节点共享读写 | 文件服务器、共享配置 |
云存储 | StorageClass 动态供给 | 生产环境持久化存储(跨节点可用) | AWS EBS、Azure Disk、GCP PD |
配置/密钥 | ConfigMap/Secret | 注入配置文件或敏感信息 | 数据库连接字符串、TLS 证书 |
4. 高级配置技巧
(1) 子路径隔离
同一 PVC 挂载到多个 Pod 时,使用 subPath
隔离目录:
yaml
volumeMounts:
- name: shared-storage
mountPath: /app/data
subPath: app1 # 使用 PVC 中的子目录
(2) 文件权限控制
通过 securityContext
设置文件系统权限:
yaml
securityContext:
fsGroup: 1000 # 设置挂载目录的组 ID
runAsUser: 1000 # 容器运行的用户 ID
(3) 存储扩容
动态供给的 PVC 支持在线扩容(需存储插件支持):
bash
kubectl edit pvc pvc-dynamic # 修改 spec.resources.requests.storage
(4) 多 Pod 共享存储
使用 ReadWriteMany
访问模式的存储(如 NFS):
yaml
# pvc.yaml
spec:
accessModes:
- ReadWriteMany
5. 常见问题排查
(1) PVC 处于 Pending 状态
• 原因 :无可用 PV 或 StorageClass 配置错误。
• 解决:
bash
kubectl describe pvc <pvc-name> # 查看事件日志
kubectl get storageclass # 检查 StorageClass 是否存在
(2) 容器无法写入存储卷
• 原因 :权限不足或存储后端故障。
• 解决:
bash
kubectl exec -it <pod-name> -- ls -l /data # 检查挂载点权限
kubectl logs <storage-plugin-pod> # 查看存储插件日志
(3) PV 无法回收
• 原因 :回收策略为 Retain
,需手动删除 PV 和底层数据。
• 解决:
bash
kubectl delete pv <pv-name> # 手动清理
6. 最佳实践
- 生产环境优先使用动态供给:避免手动管理 PV,提高资源利用率。
- 合理选择访问模式 :
•ReadWriteOnce
:数据库等单节点读写场景。
•ReadWriteMany
:文件共享、内容管理系统(CMS)。 - 定期备份重要数据:即使使用持久化存储,也需通过工具(如 Velero)备份。
- 监控存储使用情况:集成 Prometheus 监控 PVC 使用率,预防存储不足。
总结
通过 PV/PVC 和 StorageClass,Kubernetes 提供了灵活且强大的存储管理能力。无论是本地开发还是云上生产环境,合理配置存储卷可确保应用数据的高可用性和持久性。根据业务需求选择合适的存储类型,并结合动态供给、权限控制等高级特性,能够显著提升运维效率。