备份和恢复 GKE 集群的永久性存储

本页面介绍了如何备份和恢复底层 Filestore 使用 Kubernetes 卷与 GKE 集群关联的存储空间 快照。

创建 Kubernetes 卷快照等效于创建 Filestore 备份

如需了解详情,请参阅 关于 Kubernetes 卷快照

要求

如需在 GKE 上使用卷快照,必须满足以下要求:

  • 您必须部署 Filestore CSI 驱动程序。仅支持以下 Filestore 服务层级

    • 具有 GKE 1.21 版或更高版本的基本 HDD 层级
    • 具有 GKE 1.21 版或更高版本的基本 SSD 层级
    • 具有 GKE 1.27 版或更高版本的可用区层级(10 TiB 到 100 TiB)
    • 具有 GKE 1.25 版或更高版本的 Enterprise 层级
  • 使用控制层面版本 1.17 或更高版本。 如需在 VolumeSnapshot 中使用 Filestore CSI 驱动程序,请使用适用于您的服务层级的 GKE 版本号。

  • 已有要用于快照的 PersistentVolumeClaim。用于快照来源的 PersistentVolume 必须由 CSI 驱动程序管理。您可以通过检查 PersistentVolume 规范的 csi 部分是否包含 driver: pd.csi.storage.gke.iofilestore.csi.storage.gke.io 来验证是否使用了 CSI 驱动程序。如果 PersistentVolume 由 CSI 驱动程序动态预配(如以下部分所述),则它由 CSI 驱动程序管理。

限制

  • 快照卷的大小限制与常规卷相同。例如,对于基本 HDD 层级,Filestore 快照的大小必须大于或等于 1 TiB。

  • 对于以下 Filestore 服务层级,Filestore CSI 驱动程序不支持动态预配或备份工作流:

    • 可用区层级(1 TiB 到 9.75 TiB)
    • 区域
  • 对每个实例一次只能备份一个共享。就存储池而言,由两个不同 Filestore 实例的两个不同共享发出的备份请求将同时执行。

  • 单共享备份只能恢复到单共享卷。使用 Filestore CSI 驱动程序,您只能将单共享卷恢复到新的 Filestore 实例。

    • 新实例必须使用与备份相同的服务层级。
    • 新实例必须具有与备份相同的最小容量。
  • 不支持对来源或现有 Filestore 实例执行 Filestore backup restore 操作。如需查看功能限制的完整列表,请参阅 Filestore 备份功能限制

  • 不支持多共享备份。

须知事项

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

创建和使用卷快照

本文档中的示例展示了如何执行以下操作:

  1. 创建 PersistentVolumeClaimDeployment
  2. 将文件添加到 Deployment 使用的 PersistentVolume
  3. 创建 VolumeSnapshotClass 以配置快照
  4. 创建 PersistentVolume 的卷快照
  5. 删除测试文件
  6. PersistentVolume 恢复到您创建的快照
  7. 验证恢复是否有效

如需使用卷快照,您必须完成以下步骤:

  1. 创建 VolumeSnapshotClass 对象以指定快照的 CSI 驱动程序和删除政策。
  2. 创建 VolumeSnapshot 对象以请求现有 PersistentVolumeClaim 的快照。
  3. PersistentVolumeClaim 中引用 VolumeSnapshot 以将卷恢复到该快照,或者使用该快照创建新卷。

创建 PersistentVolumeClaimDeployment

  1. 如需创建 PersistentVolumeClaim 对象,请将以下清单保存为 my-pvc.yaml

    Filestore

     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
       name: my-pvc
     spec:
       storageClassName: enterprise-rwx
       accessModes:
       - ReadWriteMany
       resources:
         requests:
           storage: 1Ti
    

    本示例会创建一个企业层级 Filestore PVC。如需了解详情,请参阅使用 Filestore CSI 驱动程序访问 Filestore 实例

    对于 spec.storageClassName,您可以指定使用受支持的 CSI 驱动程序的任何存储类别。

  2. 应用清单:

    kubectl apply -f my-pvc.yaml
    
  3. 如需创建 Deployment,请将以下清单保存为 my-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-app
    spec:
      selector:
        matchLabels:
          app: hello-app
      template:
        metadata:
          labels:
            app: hello-app
        spec:
          containers:
          - name: hello-app
            image: google/cloud-sdk:slim
            args: [ "sleep", "3600" ]
            volumeMounts:
            - name: sdk-volume
              mountPath: /usr/share/hello/
          volumes:
          - name: sdk-volume
            persistentVolumeClaim:
              claimName: my-pvc
    
  4. 应用清单:

    kubectl apply -f my-deployment.yaml
    
  5. 检查 Deployment 的状态:

    kubectl get deployment hello-app
    

    Deployment 可能需要一段时间才能准备就绪。您可以运行上述命令,直到看到类似如下所示的输出:

    NAME        READY   UP-TO-DATE   AVAILABLE   AGE
    hello-app   1/1     1            1           2m55s
    

将测试文件添加到卷

  1. 列出 Deployment 中的 Pods

    kubectl get pods -l app=hello-app
    

    输出类似于以下内容:

    NAME                         READY   STATUS    RESTARTS   AGE
    hello-app-6d7b457c7d-vl4jr   1/1     Running   0          2m56s
    
  2. Pod 中创建测试文件:

    kubectl exec POD_NAME \
        -- sh -c 'echo "Hello World!" > /usr/share/hello/hello.txt'
    

    POD_NAME 替换为 Pod 的名称。

  3. 验证文件是否存在:

    kubectl exec POD_NAME \
        -- sh -c 'cat /usr/share/hello/hello.txt'
    

    输出内容类似如下:

    Hello World!
    

创建一个 VolumeSnapshotClass 对象

创建一个 VolumeSnapshotClass 对象,以指定卷快照的 CSI 驱动程序和 deletionPolicy。您可以在创建 VolumeSnapshot 对象时引用 VolumeSnapshotClass 对象。

  1. 将以下清单保存为 volumesnapshotclass.yaml

    Filestore

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotClass
    metadata:
      name: my-snapshotclass
    driver: filestore.csi.storage.gke.io
    parameters:
      type: backup
    deletionPolicy: Delete
    

    在此示例中:

    • CSI 驱动程序使用 driver 字段来预配快照。在此示例中,filestore.csi.storage.gke.io 使用 Filestore CSI 驱动程序
    • 删除绑定的 VolumeSnapshot 对象后,deletionPolicy 字段会告知 GKE 如何处理 VolumeSnapshotContent 对象和底层快照。指定 Delete 以删除 VolumeSnapshotContent 对象和底层快照。如果要保留 VolumeSnapshotContent 和底层快照,请指定 Retain
  2. 应用清单:

    kubectl apply -f volumesnapshotclass.yaml
    

创建 VolumeSnapshot

VolumeSnapshot 对象是对现有 PersistentVolumeClaim 对象的快照的请求。当您创建 VolumeSnapshot 对象时,GKE 会自动创建它并将它与 VolumeSnapshotContent 对象绑定在一起(该对象是集群中的资源,例如 PersistentVolume 对象)。

  1. 将以下清单保存为 volumesnapshot.yaml

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: my-snapshot
    spec:
      volumeSnapshotClassName: my-snapshotclass
      source:
        persistentVolumeClaimName: my-pvc
    
  2. 应用清单:

    kubectl apply -f volumesnapshot.yaml
    

    创建 Volume 快照后,GKE 会在集群中创建相应的 VolumeSnapshotContent 对象。此对象用于存储 VolumeSnapshot 对象的快照和绑定。您不会直接与 VolumeSnapshotContents 对象进行交互:

  3. 确认 GKE 创建了 VolumeSnapshotContents 对象:

    kubectl get volumesnapshotcontents
    

    输出类似于以下内容:

    NAME                                               AGE
    snapcontent-cee5fb1f-5427-11ea-a53c-42010a1000da   55s
    

创建 Volume 快照内容后,您在 VolumeSnapshotClass 中指定的 CSI 驱动程序会在相应存储系统上创建快照。GKE 在存储系统上创建快照并将其绑定到集群上的 VolumeSnapshot 对象后,该快照即可供使用。您可以通过运行以下命令来检查状态:

kubectl get volumesnapshot \
  -o custom-columns='NAME:.metadata.name,READY:.status.readyToUse'

如果快照可供使用,则输出类似于以下内容:

NAME               READY
my-snapshot        true

删除测试文件

  1. 删除您创建的测试文件:

    kubectl exec POD_NAME \
        -- sh -c 'rm /usr/share/hello/hello.txt'
    
  2. 验证文件是否不再存在:

    kubectl exec POD_NAME \
        -- sh -c 'cat /usr/share/hello/hello.txt'
    

    输出内容类似如下:

    cat: /usr/share/hello/hello.txt: No such file or directory
    

恢复卷快照

  1. 将以下清单保存为 pvc-restore.yaml

    Filestore

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-restore
    spec:
      dataSource:
        name: my-snapshot
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
      storageClassName: enterprise-rwx
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 1Ti
    
  2. 应用清单:

    kubectl apply -f pvc-restore.yaml
    
  3. 更新 my-deployment.yaml 文件以使用新的 PersistentVolumeClaim

    ...
    volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: pvc-restore
    
  4. 应用更新后的清单:

    kubectl apply -f my-deployment.yaml
    

检查快照是否已成功恢复

  1. 获取 GKE 为更新后的 Deployment 创建的新 Pod 的名称:

     kubectl get pods -l app=hello-app
    

验证测试文件是否存在:

   kubectl exec NEW_POD_NAME \
       -- sh -c 'cat /usr/share/hello/hello.txt'

NEW_POD_NAME 替换为 GKE 创建的新 Pod 的名称。

输出类似于以下内容:

   Hello World!

导入现有快照

您可以使用在当前集群外创建的现有卷快照来手动预配 VolumeSnapshotContents 对象。例如,您可以使用在其他集群中创建的另一个 Google Cloud 资源的快照来填充 GKE 中的卷。

  1. 找到快照的名称。

    Google Cloud 控制台

    访问 https://console.cloud.google.com/compute/snapshots

    Google Cloud CLI

    运行以下命令:

    gcloud compute snapshots list
    

    输出类似于以下内容:

    NAME                                           DISK_SIZE_GB  SRC_DISK                                                     STATUS
    snapshot-5e6af474-cbcc-49ed-b53f-32262959a0a0  1             us-central1-b/disks/pvc-69f80fca-bb06-4519-9e7d-b26f45c1f4aa READY
    
  2. 将以下 VolumeSnapshot 清单保存为 restored-snapshot.yaml

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: restored-snapshot
    spec:
      volumeSnapshotClassName: my-snapshotclass
      source:
        volumeSnapshotContentName: restored-snapshot-content
    
  3. 应用清单:

    kubectl apply -f restored-snapshot.yaml
    
  4. 将以下 VolumeSnapshotContent 清单保存为 restored-snapshot-content.yaml。将 snapshotHandle 字段替换为您的项目 ID 和快照名称。volumeSnapshotRef.namevolumeSnapshotRef.namespace 都必须指向之前创建的 VolumeSnapshot,双向绑定才会有效。

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotContent
    metadata:
      name: restored-snapshot-content
    spec:
      deletionPolicy: Retain
      driver: filestore.csi.storage.gke.io
      source:
        snapshotHandle: projects/PROJECT_ID/global/snapshots/SNAPSHOT_NAME
      volumeSnapshotRef:
        kind: VolumeSnapshot
        name: restored-snapshot
        namespace: default
    
  5. 应用清单:

    kubectl apply -f restored-snapshot-content.yaml
    
  6. 将以下 PersistentVolumeClaim 清单保存为 restored-pvc.yaml。Kubernetes 存储控制器会找到名为 restored-snapshotVolumeSnapshot,然后尝试找到或动态创建 PersistentVolume 作为数据源。之后,您可以在 Pod 中使用此 PVC 来访问恢复的数据。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: restored-pvc
    spec:
      dataSource:
        name: restored-snapshot
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
      storageClassName: enterprise-rwx
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    
  7. 应用清单:

    kubectl apply -f restored-pvc.yaml
    
  8. 将以下 Pod 清单保存为引用 PersistentVolumeClaimrestored-pod.yaml。CSI 驱动程序将预配 PersistentVolume 并从快照进行填充。

    apiVersion: v1
    kind: Pod
    metadata:
      name: restored-pod
    spec:
      containers:
      - name: busybox
        image: busybox
        args:
        - sleep
        - "3600"
        volumeMounts:
        - name: source-data
          mountPath: /demo/data
      volumes:
      - name: source-data
        persistentVolumeClaim:
          claimName: restored-pvc
          readOnly: false
    
  9. 应用清单:

    kubectl apply -f restored-pod.yaml
    
  10. 验证该文件是否已恢复:

    kubectl exec restored-pod -- sh -c 'cat /demo/data/hello.txt'
    

清理

为避免因本页中使用的资源导致您的 Google Cloud 账号产生费用,请按照以下步骤操作。

  1. 删除 VolumeSnapshot

    kubectl delete volumesnapshot my-snapshot
    
  2. 删除 VolumeSnapshotClass

    kubectl delete volumesnapshotclass my-snapshotclass
    
  3. 删除 Deployment

    kubectl delete deployments hello-app
    
  4. 删除 PersistentVolumeClaim 对象:

    kubectl delete pvc my-pvc pvc-restore
    

后续步骤