PersistentVolume (PV)PersistentVolumeClaim (PVC) 是 Kubernetes 中持久化存储的核心概念,它们使得存储能够独立于 Pod 的生命周期,在不同的 Pod 和节点之间保持数据持久化。在实际应用中,PV 和 PVC 提供了一种声明式的存储管理方式,让开发者可以方便地使用持久化存储,而无需关心底层的存储实现。

PersistentVolume (PV) 详解

PersistentVolume (PV) 是 Kubernetes 集群中一种独立于 Pod 的存储资源。它为 Pod 提供持久化存储,解决了 Pod 重启或迁移后数据丢失的问题。

PV 的核心特性

持久化存储

PV 的生命周期与 Pod 解耦,不依赖于 Pod 的创建或销毁。当一个 Pod 停止运行后,PV 中的数据依然保留,可以在新的 Pod 中重新挂载并继续使用。因此,PV 适用于需要跨越多个 Pod 生命周期的数据存储场景,如数据库、日志存储等。

存储类型多样化

PV 是对底层存储的抽象,Kubernetes 支持多种存储系统。常见的存储类型包括:

  • 本地存储hostPath):直接使用节点上的文件系统。
  • 网络文件系统(如 NFS、GlusterFS):适用于多节点共享存储。
  • 云存储(如 AWS EBS、GCE Persistent Disk、Azure Disk):用于云环境中的持久化存储。
  • 块存储(如 iSCSI):提供更高性能的数据存储。
访问模式

PV 的访问模式决定了存储卷可以被哪些 Pod 访问,以及如何访问。常见的访问模式包括:

  • ReadWriteOnce (RWO):只能被单个节点以读写方式挂载。常用于独占存储,如云磁盘。
  • ReadOnlyMany (ROX):可以被多个节点以只读方式挂载,适用于数据共享的场景。
  • ReadWriteMany (RWX):可以被多个节点以读写方式挂载,常用于共享存储,如 NFS 或 GlusterFS。
存储容量

PV 需要声明其可提供的存储容量。在绑定 PVC 时,Kubernetes 会根据 PVC 的存储请求将其绑定到一个有足够容量的 PV。

PV 的回收策略

PV 的回收策略定义了当 PVC 释放该 PV 时,Kubernetes 对 PV 的处理方式。常见的回收策略包括:

  • Retain(保留):PVC 释放后,PV 中的数据保留,管理员需要手动处理该 PV(如删除数据或再次分配给其他用户)。
  • Delete(删除):PVC 释放后,Kubernetes 会删除该 PV 以及其中存储的数据。适用于动态存储,如云存储。
  • Recycle(回收):PVC 释放后,PV 中的数据会被清空并再次提供给新的 PVC 使用。此策略现已弃用,建议使用 Delete 策略替代。

PV 示例

以下是一个 PV 的 YAML 文件示例:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-example
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  hostPath:
    path: "/mnt/data"

在这个示例中:

  • 该 PV 提供了 10Gi 的存储容量。
  • 访问模式为 ReadWriteOnce,意味着该 PV 只能被单个节点以读写方式挂载。
  • PV 的回收策略是 Retain,当 PVC 释放后,数据会保留,管理员需要手动处理。
  • 使用了 hostPath,将节点上的 /mnt/data 路径作为存储挂载点。

PersistentVolumeClaim (PVC) 详解

PersistentVolumeClaim (PVC) 是应用程序请求存储资源的一种方式。PVC 声明了应用所需的存储资源和访问模式,Kubernetes 会根据这些需求自动分配或绑定相应的 PV。

PVC 的核心特性

声明式请求存储

PVC 允许用户通过声明的方式请求存储资源,而无需关心底层的存储实现。用户只需指定所需的存储大小、访问模式等参数,Kubernetes 会负责查找或创建合适的 PV 并进行绑定。

自动绑定

当 PVC 创建后,Kubernetes 会根据 PVC 的需求(如存储容量、访问模式等)寻找匹配的 PV。如果找到符合要求的 PV,PVC 会自动绑定到该 PV。绑定后,PVC 将专门使用该 PV,直到 PVC 被删除。

与 StorageClass 集成

PVC 可以指定使用某个 StorageClass 动态创建 PV。StorageClass 提供了对存储类型和配置的抽象,如 SSD 或 HDD、不同的存储提供者(如 AWS、GCP)等。如果 PVC 指定了 StorageClass,Kubernetes 会自动根据 PVC 的需求动态创建一个 PV 并绑定。

PVC 的生命周期

PVC 的生命周期由以下步骤组成:

  • 创建:用户或应用程序创建 PVC,声明存储需求。
  • 绑定:Kubernetes 根据 PVC 的声明,寻找符合条件的 PV。如果 PVC 指定了 StorageClass,则会动态创建一个 PV 并绑定 PVC。
  • 使用:Pod 可以通过挂载 PVC 来使用其中的存储资源。
  • 释放:当 PVC 被删除时,Kubernetes 会根据 PV 的回收策略处理该 PV。

PVC 示例

以下是一个 PVC 的 YAML 文件示例:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-example
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
  storageClassName: manual

在这个示例中:

  • PVC 请求了 8Gi 的存储容量。
  • 访问模式为 ReadWriteOnce,表示该存储卷只能被单个节点以读写方式挂载。
  • 使用了 manual StorageClass,表明需要绑定手动创建的 PV。

动态存储的支持

Kubernetes 允许通过 StorageClass 来动态创建 PV。StorageClass 是 Kubernetes 用于定义不同存储类型和策略的抽象层。管理员可以定义不同的存储类,如基于 SSD 或 HDD 的存储池。当 PVC 请求存储时,Kubernetes 会根据 PVC 中定义的 StorageClass 动态创建合适的 PV 并绑定。

StorageClass 示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
  fsType: ext4

此示例定义了一个名为 fast 的 StorageClass,使用 Google Cloud 的 SSD 存储盘,并且文件系统类型为 ext4。PVC 可以通过指定 storageClassName: fast 来使用该 StorageClass,Kubernetes 会自动创建一个基于 SSD 的 PV。

PV 和 PVC 的关系

  • 绑定关系:PVC 是对存储资源的请求,PV 是实际的存储卷。PVC 和 PV 之间是通过访问模式和存储容量的匹配绑定在一起的。一个 PVC 只能绑定一个 PV,反之亦然。
  • 抽象与实现分离:用户通过 PVC 来声明他们的存储需求,而不需要关心底层存储的细节(如存储类型、存储位置等)。Kubernetes 会自动根据 PVC 的需求匹配或创建合适的 PV。
  • 生命周期管理:PV 和 PVC 的生命周期分离,但它们紧密关联。当 PVC 被删除时,Kubernetes 会根据 PV 的回收策略来决定如何处理 PV。

PV 和 PVC 的回收策略

当 PVC 被删除后,PV 的回收策略决定了 Kubernetes 如何处理 PV:

  • Retain:PVC 释放后,PV 中的数据保留。管理员需要手动处理 PV(如删除或清理数据后重新使用)。
  • Delete:PVC 释放后,PV 和其中的存储资源会被自动删除。这种策略常用于云存储,特别是在动态创建 PV 的场景中。
  • Recycle:PVC 释放后,PV 中的数据会被清空并再次分配给新的 PVC 使用。然而,Recycle 策略已经被弃用,建议使用 Delete 策略替代。

PV 和 PVC 最佳实践

使用动态存储类(StorageClass)

在大多数场景中,建议使用 StorageClass 来实现动态 PV 的创建和绑定,这样可以避免手动创建 PV 的麻烦。StorageClass 可以帮助管理不同类型的存储需求,如 SSD 和 HDD,甚至可以为不同的存储提供不同的 QoS(质量服务)。

StorageClass 的配置示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  fsType: ext4
  encrypted: "true"
reclaimPolicy: Delete
allowVolumeExpansion: true

在这个示例中:

  • provisioner:指定了使用 AWS EBS 作为存储提供者。
  • parameters:定义了存储的具体类型(gp2),文件系统(ext4),以及是否启用存储加密。
  • reclaimPolicy:设置为 Delete,表明当 PVC 被删除时,PV 和存储资源都会被销毁。
  • allowVolumeExpansion:启用存储卷扩展功能,允许在 PVC 增加存储请求后动态扩展卷。

选择合适的访问模式

PV 支持多种访问模式(ReadWriteOnce, ReadOnlyMany, ReadWriteMany),选择合适的访问模式对应用性能和稳定性至关重要。例如:

  • ReadWriteOnce (RWO):适合单实例的应用程序或数据库使用,例如 MySQL、PostgreSQL。
  • ReadWriteMany (RWX):适合多实例访问的共享存储场景,例如 NFS,可以允许多个 Pod 同时对数据进行读写。
  • ReadOnlyMany (ROX):适合共享静态内容的应用,如内容分发或日志共享。

PVC 的容量扩展

如果 PVC 绑定的存储资源不够使用,可以通过调整 PVC 请求的存储容量来动态扩展存储卷(前提是存储提供支持该功能,并且启用了 allowVolumeExpansion)。

PVC 扩展示例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-expand-example
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: fast-storage

在这个示例中,原本的存储容量是 10Gi,现在请求扩展为 20Gi。Kubernetes 会根据底层存储的支持情况,自动扩展存储卷的大小。

存储回收策略

根据业务需求,合理选择 PV 的回收策略。常见的回收策略包括:

  • Retain:适合需要保留数据手动处理的场景。比如需要保存数据库快照或者手动转移数据的场景。
  • Delete:适合动态存储环境,PVC 删除后自动清理存储资源。
  • Recycle:虽然已经弃用,但在一些场景下仍然可以通过清理数据后重复使用。

PV 和 PVC 的生命周期管理

为了避免存储资源浪费,管理员需要定期检查未绑定的 PVC 和未使用的 PV,避免遗留的存储资源影响整体集群性能。此外,确保 PVC 的生命周期与实际业务需求匹配,例如当 Pod 被删除后是否需要继续保留存储。

总结

Kubernetes 的 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 提供了一种灵活而强大的存储管理机制,它们可以跨越 Pod 的生命周期,保持数据的持久性。通过使用 PV,应用程序可以利用多种存储系统,包括本地存储、共享存储和云存储。PVC 使用户能够声明他们的存储需求,Kubernetes 会自动处理底层的存储资源分配和管理。此外,通过 StorageClass,还可以实现存储资源的动态创建和配置。

一些最佳实践包括:

  • 尽量使用 StorageClass 实现动态存储管理,简化运维。
  • 根据应用的特点选择合适的访问模式,确保性能和稳定性。
  • 动态扩展 PVC 的容量以应对业务增长需求。
  • 定期检查未绑定的 PVC 和未使用的 PV,避免资源浪费。

PV 和 PVC 的结合使用,帮助 Kubernetes 集群中的应用程序无缝访问持久化存储资源,是构建可靠、可扩展云原生应用程序的关键。