Kubernetes PersistentVolume(PV)和 PersistentVolumeClaim(PVC)是用于管理存储的两种重要资源,它们实现了存储资源的声明式管理和动态分配。
PersistentVolume(PV)
PersistentVolume 是集群中的一块存储,由管理员预先配置或通过存储类动态创建。PV 是集群级别的资源,独立于 Pod 的生命周期。
PV 的生命周期
-
Provisioning(配置):
- 静态配置:管理员手动创建 PV
- 动态配置:通过 StorageClass 自动创建
-
Binding(绑定):
- PVC 请求存储时,控制器将 PVC 绑定到合适的 PV
- 绑定是一对一的,一旦绑定,PV 就专属于该 PVC
-
Using(使用):
- Pod 通过 PVC 使用存储
- 存储可以挂载到 Pod 的指定路径
-
Releasing(释放):
- PVC 删除后,PV 进入 Released 状态
- PV 中的数据仍然保留
-
Reclaiming(回收):
- Retain(保留):手动回收
- Recycle(回收):已废弃,使用动态配置替代
- Delete(删除):自动删除 PV 和底层存储
PV 的访问模式
-
ReadWriteOnce(RWO):
- 卷可以被单个节点以读写模式挂载
- 适用于块存储
-
ReadOnlyMany(ROX):
- 卷可以被多个节点以只读模式挂载
- 适用于共享只读数据
-
ReadWriteMany(RWX):
- 卷可以被多个节点以读写模式挂载
- 适用于文件系统(如 NFS)
-
ReadWriteOncePod(RWOP):
- 卷可以被单个 Pod 以读写模式挂载
- 确保同一时间只有一个 Pod 访问
PV 的状态
-
Available:可用,未绑定到任何 PVC
-
Bound:已绑定到 PVC
-
Released:PVC 已删除,但资源尚未被集群回收
-
Failed:自动回收失败
PersistentVolumeClaim(PVC)
PVC 是用户对存储的请求,类似于 Pod 对计算资源的请求。PVC 是命名空间级别的资源。
PVC 的配置
yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: standard selector: matchLabels: environment: production
PVC 的使用
- 在 Pod 中使用 PVC:
yamlapiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container image: nginx volumeMounts: - name: my-volume mountPath: /data volumes: - name: my-volume persistentVolumeClaim: claimName: my-pvc
- 在 Deployment 中使用 PVC:
yamlapiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: volumes: - name: my-volume persistentVolumeClaim: claimName: my-pvc containers: - name: my-container image: nginx volumeMounts: - name: my-volume mountPath: /data
StorageClass
StorageClass 定义了不同类型的存储,支持动态配置 PV。
StorageClass 的配置
yamlapiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/aws-ebs parameters: type: gp2 iopsPerGB: "10" reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true
常见的 Provisioner
-
kubernetes.io/aws-ebs:AWS EBS 块存储
-
kubernetes.io/gce-pd:GCE 持久化磁盘
-
kubernetes.io/azure-disk:Azure 磁盘
-
kubernetes.io/azure-file:Azure 文件存储
-
kubernetes.io/cinder:OpenStack Cinder
-
kubernetes.io/nfs:NFS 存储
-
rancher.io/local-path:本地路径存储
StorageClass 参数
-
provisioner:存储提供者
-
parameters:存储提供者特定的参数
-
reclaimPolicy:回收策略(Delete 或 Retain)
-
volumeBindingMode:
- Immediate:立即绑定
- WaitForFirstConsumer:等待第一个消费者
-
allowVolumeExpansion:是否允许卷扩展
动态配置
动态配置允许根据 PVC 自动创建 PV,无需管理员手动创建。
动态配置流程
-
用户创建 PVC,指定 StorageClass
-
PersistentVolumeController 监听到 PVC
-
控制器调用 StorageClass 的 provisioner 创建 PV
-
PV 绑定到 PVC
-
Pod 可以使用 PVC
动态配置示例
yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: dynamic-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: fast
静态配置
静态配置需要管理员手动创建 PV,适用于特定的存储需求。
静态 PV 示例
yamlapiVersion: v1 kind: PersistentVolume metadata: name: manual-pv labels: type: local spec: storageClassName: manual capacity: storage: 10Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: path: /mnt/data
PV 和 PVC 的区别
| 特性 | PV | PVC |
|---|---|---|
| 作用域 | 集群级别 | 命名空间级别 |
| 创建者 | 管理员或动态配置 | 用户 |
| 用途 | 提供存储资源 | 请求存储资源 |
| 生命周期 | 独立于 Pod | 依赖于 Pod |
最佳实践
-
使用动态配置:优先使用 StorageClass 动态配置,减少手动管理
-
设置合理的回收策略:生产环境使用 Retain,测试环境使用 Delete
-
使用访问模式:根据应用需求选择合适的访问模式
-
监控存储使用:监控 PV 和 PVC 的使用情况
-
备份重要数据:定期备份 PV 中的重要数据
-
使用标签和注解:为 PV 和 PVC 添加有意义的标签和注解
-
设置资源限制:为 PVC 设置合理的存储请求
-
使用存储类:为不同的应用需求创建不同的 StorageClass
故障排查
- 查看 PV 状态:
bashkubectl get pv kubectl describe pv <pv-name>
- 查看 PVC 状态:
bashkubectl get pvc kubectl describe pvc <pvc-name>
- 查看 StorageClass:
bashkubectl get storageclass kubectl describe storageclass <sc-name>
- 查看 Pod 挂载情况:
bashkubectl describe pod <pod-name>
- 查看事件:
bashkubectl get events --sort-by=.metadata.creationTimestamp