使用卷快照备份永久性磁盘存储空间


本页面介绍如何使用卷快照备份和恢复永久性磁盘存储空间。

如需了解说明,请参阅 Kubernetes 卷快照简介

要求

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

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

限制

Compute Engine 上创建磁盘快照的所有限制也适用于 GKE。

最佳做法

在 GKE 上使用永久性磁盘 Volume 快照时,请务必遵循 Compute Engine 磁盘快照的最佳做法

须知事项

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

  • 启用 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

    Persistent Disk

     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
       name: my-pvc
     spec:
       storageClassName: standard-rwo
       accessModes:
       - ReadWriteOnce
       resources:
         requests:
           storage: 1Gi
    

    此示例使用默认随 Compute Engine 永久性磁盘 CSI 驱动程序安装的 standard-rwo 存储类别。如需了解详情,请参阅使用 Compute Engine 永久性磁盘 CSI 驱动程序

    对于 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

    Persistent Disk

    对于运行 1.21 版或更高版本的集群,请使用 v1 API 版本。

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

    在此示例中:

    • CSI 驱动程序使用 driver 字段来预配快照。在此示例中,pd.csi.storage.gke.io 使用 Compute Engine 永久性磁盘 CSI 驱动程序

    • 删除绑定的 VolumeSnapshot 对象后,deletionPolicy 字段会告知 GKE 如何处理 VolumeSnapshotContent 对象和底层快照。指定 Delete 以删除 VolumeSnapshotContent 对象和底层快照。如果要保留 VolumeSnapshotContent 和底层快照,请指定 Retain

      如需使用自定义存储位置,请向快照类添加 storage-locations 参数。如需使用此参数,您的集群必须使用 1.21 或更高版本。

      apiVersion: snapshot.storage.k8s.io/v1
      kind: VolumeSnapshotClass
      metadata:
        name: my-snapshotclass
      parameters:
        storage-locations: us-east2
      driver: pd.csi.storage.gke.io
      deletionPolicy: Delete
      
    • 如需创建磁盘映像,请将以下内容添加到 parameters 字段:

      parameters:
        snapshot-type: images
        image-family: IMAGE_FAMILY
      

      IMAGE_FAMILY 替换为首选映像系列的名称,例如 preloaded-data

  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
    

恢复卷快照

您可以在 PersistentVolumeClaim 中引用 VolumeSnapshot,以使用现有卷中的数据预配新卷,或者将卷恢复到您在快照中捕获的状态。

如需在 PersistentVolumeClaim 中引用 VolumeSnapshot,请将 dataSource 字段添加到 PersistentVolumeClaim。无论 VolumeSnapshotContents 引用的是磁盘映像还是快照,都会使用相同的流程。

在此示例中,您可以引用在新 PersistentVolumeClaim 中创建的 VolumeSnapshot,并更新 Deployment 以使用新声明。

  1. 验证您使用的是磁盘快照还是映像快照,不同之处如下:

    • 磁盘快照:频繁截取快照,但不常恢复。
    • 映像快照:不常截取快照,但频繁恢复。创建映像快照的速度可能也比磁盘快照慢。

    如需了解详情,请参阅快照频率限制。在排查任何问题时,了解快照类型将会很有帮助。

    检查 VolumeSnapshot

    kubectl describe volumesnapshot SNAPSHOT_NAME
    

    volumeSnapshotClassName 字段指定快照类。

    kubectl describe volumesnapshotclass SNAPSHOT_CLASS_NAME
    

    snapshot-type 参数将指定 snapshotsimages。如果没有指定该参数,则默认值为 snapshots

    如果没有快照类(例如,如果快照是静态创建的),请检查 VolumeSnapshotContentssh kubectl describe volumesnapshotcontents SNAPSHOT_CONTENTS_NAME 可通过输出中快照句柄的格式确定快照的类型,如下所示:* projects/PROJECT_NAME/global/snapshots/SNAPSHOT_NAME:磁盘快照

    • projects/PROJECT_NAME/global/images/IMAGE_NAME:映像快照
  1. 将以下清单保存为 pvc-restore.yaml

    Persistent Disk

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-restore
    spec:
      dataSource:
        name: my-snapshot
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
      storageClassName: standard-rwo
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    
  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: pd.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: standard-rwo
      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
    

后续步骤