具有永久性磁盘的永久性卷

本页面简要介绍了 Kubernetes 中的 PersistentVolume 和 PersistentVolumeClaim,及其在 Google Kubernetes Engine (GKE) 中的用法。本页面重点介绍由 Compute Engine 永久性磁盘支持的存储。

概览

PersistentVolume 资源用于管理集群中的持久性存储。在 GKE 中,PersistentVolume 通常由 Compute Engine 永久性磁盘提供支持。PersistentVolume 还可用于其他存储类型,例如 NFS。Filestore 是 Google Cloud 上的原生 NFS 解决方案。如需了解如何将 Filestore 实例设置为 GKE 集群的 NFS PV 解决方案,请参阅 Filestore 文档中的访问 Google Kubernetes Engine 集群中的文件共享。请参阅 Kubernetes 文档,进一步大致了解 PersistentVolume。

不同,PersistentVolume 生命周期由 Kubernetes 管理。PersistentVolume 可以动态预配;用户不必手动创建和删除后备存储。

PersistentVolume 是独立于 Pod 存在的集群资源。这意味着在集群更改时以及在删除并重新创建 Pod 时,PersistentVolume 表示的磁盘和数据将继续存在。PersistentVolume 资源可以通过 PersistentVolumeClaim 动态预配,也可以由集群管理员明确创建。

PersistentVolumeClaim 是对 PersistentVolume 资源的请求和声明。PersistentVolumeClaim 对象会针对 PersistentVolume 请求特定大小、访问模式和 StorageClass。如果存在满足请求的 PersistentVolume 或者可以预配,则 PersistentVolumeClaim 会绑定到该 PersistentVolume。

Pod 将声明用作卷。集群会检查声明以找到绑定的卷并为 Pod 装载该卷。

可移植性是使用 PersistentVolume 和 PersistentVolumeClaim 的另一个优点。您可以在不同集群和环境中轻松使用相同的 Pod 规范,因为 PersistentVolume 是实际后备存储的接口。

StorageClass

诸如 gcePersistentDisk 之类的卷实现是通过 StorageClass 资源配置的。GKE 会为您创建一个使用标准永久性磁盘类型 (ext4) 的默认 StorageClass。如果 PersistentVolumeClaim 未指定 StorageClassName,则将使用默认 StorageClass。您可以将提供的默认 StorageClass 替换为您自己的 StorageClass。

如果您使用的是具有 Windows 节点池的集群,则必须创建 StorageClass,并在 PersistentVolumeClaim 中指定 StorageClassName,因为 Windows 不支持默认的 fstype ext4。如果您使用的是 Compute Engine 永久性磁盘,则必须使用 NTFS 作为文件存储类型。

您可以创建自己的 StorageClass 资源来描述不同类别的存储。例如,类可能与服务质量等级或备份政策相对应。在其他存储系统中,此概念有时称为“配置文件”。

动态预配 PersistentVolume

在大多数情况下,您不需要直接配置 PersistentVolume 对象或创建 Compute Engine 永久性磁盘。您可以改为创建 PersistentVolumeClaim,然后 Kubernetes 会自动为您预配永久性磁盘。

以下清单描述了对 30 GB (GiB) 磁盘的请求,该磁盘的访问模式允许单个节点以读写方式装载磁盘:

# pvc-demo.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 30Gi

在您使用 kubectl apply -f pvc-demo.yaml 创建此 PersistentVolumeClaim 后,Kubernetes 会动态创建对应的 PersistentVolume 对象。以下示例展示了已创建的 PersistentVolume。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pvc-cd3fd5e9-695a-11ea-a3da-42010a800003
  uid: ced478c1-695a-11ea-a3da-42010a800003
  annotations:
    kubernetes.io/createdby: gce-pd-dynamic-provisioner
    pv.kubernetes.io/bound-by-controller: "yes"
    pv.kubernetes.io/provisioned-by: kubernetes.io/gce-pd
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 30Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: pvc-demo
    uid: cd3fd5e9-695a-11ea-a3da-42010a800003
  gcePersistentDisk:
    fsType: ext4
    pdName: gke-cluster-1-pvc-cd3fd5e9-695a-11ea-a3da-42010a800003
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: failure-domain.beta.kubernetes.io/zone
          operator: In
          values:
          - us-central1-c
        - key: failure-domain.beta.kubernetes.io/region
          operator: In
          values:
          - us-central1
  persistentVolumeReclaimPolicy: Delete
  storageClassName: standard
  volumeMode: Filesystem
status:
  phase: Bound

假设您尚未替换 GKE 默认存储类别,则此 PersistentVolume 会由一个新的空 Compute Engine 永久性磁盘支持。您可以在 Pod 中使用此磁盘,将声明用作卷即可。删除声明时,相应的 PersistentVolume 对象以及预配的 Compute Engine 永久性磁盘也会被删除。

如果您要防止删除动态预配的永久性磁盘,请将 PersistentVolume 资源或其 StorageClass 资源的收回政策设置为 Retain。在这种情况下,只要存在永久性磁盘,即使没有 PersistentVolumeClaim 使用永久性磁盘,您也需要支付费用。 如需查看有关如何更改收回政策的示例,请参阅更改 PersistentVolume 的收回政策StorageClass 资源

访问模式

PersistentVolume 支持以下访问模式

  • ReadWriteOnce:卷可以由单个节点以读写方式装载。
  • ReadOnlyMany:卷可以由多个节点以只读方式装载。
  • ReadWriteMany:卷可以由多个节点以读写方式装载。 由 Compute Engine 永久性磁盘支持的 PersistentVolume 不支持此访问模式。

以 ReadOnlyMany 方式使用 Compute Engine 永久性磁盘

ReadWriteOnce 是永久性磁盘最常见的使用场景,用作大多数应用的默认访问模式。Compute Engine 永久性磁盘也支持 ReadOnlyMany 模式,以便多个应用或同一应用的多个副本可以同时使用同一磁盘。一个示例使用场景是跨多个副本传送静态内容。

请参阅本文,了解为多个读取器创建持久性磁盘的说明

将原有永久性磁盘用作 PersistentVolume

动态预配的 PersistentVolume 在创建时是空的。如果您已经有一个填充了数据的现存 Compute Engine 永久性磁盘,您可以通过手动创建对应的 PersistentVolume 资源将该磁盘引入您的集群。永久性磁盘必须与集群节点位于同一 [地区] 中。

请参阅此示例,了解如何创建由原有永久性磁盘支持的永久性卷

Deployment 与 StatefulSet

您可以在更高级层的控制器(如 DeploymentStatefulSet)中分别使用 PersistentVolumeClaim 或 VolumeClaim 模板。

Deployment 是专为无状态应用设计的,因此 Deployment 的所有副本共用同一个 PersistentVolumeClaim。由于创建的副本 Pod 彼此相同,因此只有具有 ReadOnlyMany 或 ReadWriteMany 模式的卷才能适用于此设置。

即使是具有一个使用 ReadWriteOnce 卷的副本的 Deployment,也不建议采用。这是因为默认 Deployment 策略将在重新创建时先创建第二个 Pod,然后再关闭第一个 pod。第二个 Pod 无法启动时,Deployment 可能会因死锁而失败,这是因为 ReadWriteOnce 卷已在使用中,而第一个 Pod 由于第二个 Pod 尚未启动而无法移除。应改为针对 ReadWriteOnce 卷使用 StatefulSet。

建议使用 StatefulSet 部署有状态应用,这些应用需要每个副本具有唯一卷。通过将 StatefulSet 与 PersistentVolumeClaim 模板结合使用,您的应用可以随与每个副本 Pod 关联的唯一 PersistentVolumesClaim 自动纵向扩容。

区域永久性磁盘

区域永久性磁盘在同一区域中的两个地区之间复制数据,并且使用方式与标准永久性磁盘类似。如果发生地区性中断,或者某个地区的集群节点无法安排,Kubernetes 可进行故障转移,将使用该卷的工作负载分配到其他地区。您可以使用区域永久性磁盘为 GKE 上的有状态工作负载构建高可用性解决方案。用户必须确保主要地区和故障转移地区都配置了足够的资源容量来运行工作负载。

区域 SSD 永久性磁盘是应用(例如同时要求高可用性和高性能的数据库)的一个选项。如需了解详情,请参阅块存储性能比较

与标准永久性磁盘一样,区域永久性磁盘可以根据需要动态预配,也可以由集群管理员提前预配。

如需了解如何添加区域永久性磁盘,请参阅预配区域永久性磁盘的相关说明

后续步骤