持久化卷(PV)和声明(PVC)为 Kubernetes 提供了统一、灵活的存储管理能力,是实现有状态应用和数据持久化的基础。
Kubernetes 持久化卷(PersistentVolume)子系统为用户和管理员提供了一套完整的 API,将存储的实现细节从使用方式中抽象出来,实现了存储资源的统一管理。本文详细介绍 PV 和 PVC 的核心概念、生命周期管理以及在生产环境中的最佳实践。
Kubernetes 通过引入三个关键的 API 资源来实现存储与计算的解耦和自动化管理。
PV(PersistentVolume)是集群管理员预先配置或动态创建的存储资源,属于集群基础设施的一部分。PV 生命周期独立于 Pod,封装了底层存储实现的细节(如 NFS、iSCSI、云存储等)。
PVC(PersistentVolumeClaim)是用户对存储资源的请求声明。类似于 Pod 消耗节点资源,PVC 消耗 PV 资源。用户通过 PVC 请求特定大小和访问模式的存储,无需了解底层实现。
StorageClass 提供了一种描述存储“类别”的机制,支持动态配置、不同服务质量级别、配置参数和回收策略,满足多样化的存储需求。
PV 和 PVC 遵循标准的生命周期流程,确保存储资源的高效利用和安全管理。
控制平面持续监控新创建的 PVC,寻找匹配的 PV 并建立一对一绑定关系,确保数据安全。未找到匹配 PV 的 PVC 将保持 Pending 状态。
绑定匹配条件包括:
Pod 通过 volume 配置引用 PVC 使用持久化存储。调度器确保 Pod 被调度到能访问对应存储的节点,kubelet 负责挂载存储卷。
启用存储对象保护后:
PVC 删除后,PV 根据回收策略处理:
PV 的配置涉及容量、访问模式、卷类型、节点亲和等多个关键属性。
以下为典型 PV 配置示例:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs-example
labels:
type: nfs
environment: production
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-storage
mountOptions:
- hard
- nfsvers=4.1
- rsize=1048576
- wsize=1048576
nfs:
path: /data/kubernetes
server: nfs.example.com
定义 PV 的存储容量,使用标准 Kubernetes 资源单位。目前主要支持存储大小,未来可能扩展支持 IOPS、吞吐量等属性。
PV 支持多种访问模式,适应不同应用场景。
| 模式 | 简写 | 描述 | 使用场景 |
|---|---|---|---|
| ReadWriteOnce | RWO | 单节点读写 | 数据库、文件系统 |
| ReadOnlyMany | ROX | 多节点只读 | 配置文件、静态资源 |
| ReadWriteMany | RWX | 多节点读写 | 共享文件系统 |
| ReadWriteOncePod | RWOP | 单 Pod 读写 | 1.22+ 版本支持 |
限制 PV 可挂载的节点范围,提升数据安全和调度灵活性。
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values: ["linux"]
PVC 用于声明存储需求,支持多种资源和选择器配置。
以下为典型 PVC 配置示例:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: web-storage-claim
namespace: default
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
limits:
storage: 10Gi
storageClassName: fast-ssd
selector:
matchLabels:
environment: production
matchExpressions:
- key: type
operator: In
values: [ssd, nvme]
通过标签选择器精确匹配 PV:
selector:
matchLabels:
environment: production
tier: frontend
matchExpressions:
- key: type
operator: NotIn
values: [slow-disk]
Pod 可通过 volume 或 volumeDevices 挂载 PVC,支持文件系统和块设备两种模式。
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
containers:
- name: nginx
image: nginx:1.21
volumeMounts:
- name: web-content
mountPath: /usr/share/nginx/html
readOnly: false
- name: nginx-config
mountPath: /etc/nginx/conf.d
readOnly: true
volumes:
- name: web-content
persistentVolumeClaim:
claimName: web-storage-claim
- name: nginx-config
persistentVolumeClaim:
claimName: nginx-config-claim
apiVersion: v1
kind: Pod
metadata:
name: database-pod
spec:
containers:
- name: database
image: postgres:13
volumeDevices:
- name: db-storage
devicePath: /dev/block-device
env:
- name: PGDATA
value: /dev/block-device
volumes:
- name: db-storage
persistentVolumeClaim:
claimName: database-block-claim
StorageClass 支持多种参数和策略,适配不同存储后端和业务需求。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
annotations:
storageclass.kubernetes.io/is-default-class: "false"
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Delete
mountOptions:
- debug
- noatime
Kubernetes 支持多种云原生和企业级存储插件,满足不同场景需求。
| 存储类型 | RWO | ROX | RWX | RWOP |
|---|---|---|---|---|
| AWS EBS | ✓ | - | - | ✓ |
| Azure Disk | ✓ | - | - | ✓ |
| Google PD | ✓ | ✓ | - | ✓ |
| NFS | ✓ | ✓ | ✓ | ✓ |
| Ceph RBD | ✓ | ✓ | - | ✓ |
| CephFS | ✓ | ✓ | ✓ | ✓ |
| GlusterFS | ✓ | ✓ | ✓ | ✓ |
Kubernetes 支持在线扩展卷容量,提升存储弹性。
在 StorageClass 中启用:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: expandable-storage
provisioner: ebs.csi.aws.com
allowVolumeExpansion: true
parameters:
type: gp3
encrypted: "true"
直接编辑 PVC 的存储请求:
spec:
resources:
requests:
storage: 20Gi # 从 10Gi 扩展到 20Gi
监控 PV/PVC 状态和存储性能,有助于及时发现和解决问题。
PVC 无法绑定
# 检查 PVC 状态
kubectl describe pvc <pvc-name>
# 查看可用 PV
kubectl get pv --show-labels
# 检查 StorageClass
kubectl describe storageclass <class-name>
Pod 无法启动
# 检查 Pod 事件
kubectl describe pod <pod-name>
# 查看 PVC 状态
kubectl get pvc -o wide
# 检查节点存储插件状态
kubectl get pods -n kube-system | grep csi
结合实际业务需求,建议遵循以下最佳实践。
Kubernetes 持久化卷(PV/PVC)为有状态应用提供了统一、灵活的存储管理能力。通过合理配置 StorageClass、访问模式、回收策略和监控机制,可以实现高性能、高可用的数据持久化,提升集群的运维效率和业务可靠性。