使用卷快照

在 Google Kubernetes Engine (GKE) 中,您可以将 Kubernetes 卷快照功能用于 GKE 集群中的永久性卷

通过卷快照,您可以在特定时间点创建卷的副本。您可以使用此副本将卷恢复到之前的状态或预配新卷。

在 1.17 版及更高版本中,您可以使用以下组件预配和附加卷快照:

要求

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

  • 使用支持快照的 CSI 驱动程序。树内永久性磁盘驱动程序不支持快照。

  • 使用版本为 GKE 1.17 版或更高版本的控制层面(主)版本。如需使用 Compute Engine 永久性磁盘 CSI 驱动程序,请在 VolumeSnapshot 中使用 GKE 1.17.6-gke.4 版或更高版本。如需在 VolumeSnapshot 中使用 Filestore CSI 驱动程序,请使用 GKE 1.21 版或更高版本。

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

准备工作

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

使用以下任一方法设定默认的 gcloud 设置:

  • 使用 gcloud init(如果您想要在系统引导下完成默认设置)。
  • 使用 gcloud config(如果您想单独设置项目 ID、区域和地区)。

使用 gcloud init

如果您收到 One of [--zone, --region] must be supplied: Please specify location 错误,请完成本部分。

  1. 运行 gcloud init 并按照说明操作:

    gcloud init

    如果您要在远程服务器上使用 SSH,请使用 --console-only 标志来防止命令启动浏览器:

    gcloud init --console-only
  2. 按照说明授权 gcloud 使用您的 Google Cloud 帐号。
  3. 创建新配置或选择现有配置。
  4. 选择 Google Cloud 项目。
  5. 为可用区级集群选择默认 Compute Engine 可用区,或为区域级集群或 Autopilot 集群选择区域。

使用 gcloud config

  • 设置默认项目 ID
    gcloud config set project PROJECT_ID
  • 如果您使用的是可用区级集群,请设置默认计算可用区
    gcloud config set compute/zone COMPUTE_ZONE
  • 如果您使用的是 Autopilot 集群或区域级集群,请设置默认计算区域
    gcloud config set compute/region COMPUTE_REGION
  • gcloud 更新到最新版本:
    gcloud components update

创建和使用卷快照

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

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

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

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

创建 PersistentVolumeClaim 和 Deployment

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

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

    对于 spec.storageClassName,您可以指定使用受支持的 CSI 驱动程序的任何存储类别。此示例使用默认随 Compute Engine 永久性磁盘 CSI 驱动程序安装的 standard-rwo 存储类别。如需了解详情,请参阅使用 Compute Engine 永久性磁盘 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
    

将测试文件添加到卷

  1. 列出 Deployment 中的 Pod:

    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。您可以使用 API 版本 v1beta1v1,具体取决于集群上的 GKE 版本。

    v1beta1

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

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

    v1

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

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

    在此示例中:

    • driver 字段是用于预配快照的 CSI 驱动程序。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
    
  2. 应用清单:

    kubectl apply -f volumesnapshotclass.yaml
    

创建 VolumeSnapshot

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

  1. 将以下清单保存为 volumesnapshot.yaml。您可以使用 API 版本 v1beta1v1

    v1beta1

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

    apiVersion: snapshot.storage.k8s.io/v1beta1
    kind: VolumeSnapshot
    metadata:
      name: my-snapshot
    spec:
      volumeSnapshotClassName: my-snapshotclass
      source:
        persistentVolumeClaimName: my-pvc
    

    v1

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

    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
    

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

  3. 如需确认 GKE 创建了 VolumeSnapshotContents 对象,请运行以下命令:

    kubectl get volumesnapshotcontents
    

    输出内容类似如下:

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

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

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

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

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

    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
    

检查快照是否已成功恢复

如需检查快照是否已成功恢复,请获取为更新后的 Deployment 创建的新 Pod GKE 的名称:

kubectl get pods -l app=hello-app

验证测试文件是否存在:

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

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

输出内容类似如下:

Hello World!

清理

  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
    

后续步骤