触发 Pod 快照

了解如何创建快照政策,以及如何在 Google Kubernetes Engine (GKE) 上触发正在运行的工作负载的 Pod 快照。

准备工作

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

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。如果您之前安装了 gcloud CLI,请通过运行 gcloud components update 命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
  • 请确保您已完成前提条件,并在集群中启用了 Pod 快照。如需了解详情,请参阅准备 Pod 快照

创建快照政策

如需为 Pod 启用快照,请创建一个 PodSnapshotPolicy 资源,其中包含与 Pod 标签匹配的选择器。

  1. 以下示例创建了一项政策,该政策适用于具有 app: my-app 标签的 Pod,并使用 example-pod-snapshot-storage-config 存储配置。将以下清单保存为 example-pod-snapshot-policy.yaml

    apiVersion: podsnapshot.gke.io/v1
    kind: PodSnapshotPolicy
    metadata:
      name: example-pod-snapshot-policy
      namespace: NAMESPACE
    spec:
      storageConfigName: example-pod-snapshot-storage-config
      selector:
        matchLabels:
          app: my-app
      triggerConfig:
        type: TRIGGER_TYPE
        postCheckpoint: resume
    

    替换以下内容:

    • TRIGGER_TYPE:触发器的类型。支持的值为 workload(表示基于工作负载的触发器)或 manual(表示按需快照)。
    • NAMESPACE:Pod 的命名空间。

    如需查看您可以配置的所有字段的完整列表,请参阅 PodSnapshotPolicy 自定义资源定义 (CRD) 文档

  2. 应用清单:

    kubectl apply -f example-pod-snapshot-policy.yaml
    

配置其他 Pod 快照政策

您可以在 PodSnapshotPolicy 中配置其他政策,例如:

  • 快照范围:如需指定要在快照中捕获的 Pod 状态的哪些部分,请配置 spec.snapshotScope 字段。支持的值为 whole-pod(默认),用于对整个 Pod(包括应用状态、内存和文件系统)进行检查点设置;或 rootfs-only,用于仅对容器根文件系统进行检查点设置。rootfs-only 范围需要 GKE 1.35.3-gke.1031000 版或更高版本。

  • 自动清理:如需自动清理旧的 Pod 快照资源,请使用 spec.retentionConfig 字段配置保留政策。您可以使用 lastAccessTimeout 字段(例如 7d)指定时长,之后系统会删除快照。

  • 整理快照:您可以按逻辑对快照进行分组,以区分在相似环境但在不同情境下拍摄的快照。例如,在多租户场景中,如果所有用户的基本 Pod 都相同,您可以按用户或群组隔离快照。如需隔离快照,请使用 snapshotGroupingRules 字段在政策中指定分组标签。恢复 Pod 时,系统只会将该 Pod 与同一标签组中的快照进行匹配。如需详细了解此分组在恢复期间如何影响兼容性匹配,请参阅分组规则匹配

以下示例展示了如何在 PodSnapshotPolicy 中同时配置保留设置和分组设置。您可以单独设置以下设置:

# ... other fields omitted
spec:
  snapshotScope: rootfs-only
  retentionConfig:
    lastAccessTimeout: 7d
  snapshotGroupingRules:
    groupByLabelValue:
      labels: ["tenant", "environment"]
      groupRetentionPolicy:
        maxSnapshotCountPerGroup: 5

如需查看您可以配置的所有字段的完整列表,请参阅 PodSnapshotPolicy 参考文档

优化快照大小

当触发 Pod 快照时,gVisor 会捕获所有容器的完整状态,包括:

  • 应用状态,例如内存和寄存器
  • 对根文件系统和 tmpfs(包括 emptyDir 卷)的更改
  • 内核状态,例如打开的文件描述符、线程和套接字

快照的大小由以下因素决定。较大的快照需要更长的时间来保存和恢复。为了优化性能,在触发快照之前,您应清理在从快照恢复 Pod 后不需要的任何应用状态或文件。

优化快照大小对于大语言模型 (LLM) 等工作负载尤为重要。LLM 服务器通常会将模型权重下载到本地存储空间(rootfstmpfs),然后再将其加载到 GPU 中。拍摄快照时,系统会保存 GPU 状态和模型权重文件。在这种情况下,如果模型为 100 GB,则生成的快照大约为 200 GB(100 GB 的模型文件,加上 100 GB 的 GPU 状态)。将模型权重加载到 GPU 后,应用通常不需要文件系统上的文件即可运行。通过在触发快照之前删除这些模型文件,您可以将快照大小减少一半,并以显著更低的延迟恢复应用。

触发快照

您可以在应用准备就绪时从工作负载内触发快照,也可以手动为特定 Pod 触发按需快照。

从工作负载触发快照

如需从应用代码内触发快照,请将应用配置为在准备好拍摄快照时发送信号。如需发出就绪信号,请将 1 写入 /proc/gvisor/checkpoint 文件,例如 echo 1 > /proc/gvisor/checkpoint。写入操作会异步启动快照流程,并立即返回。从同一文件描述符读取数据会阻塞读取进程,直到快照和恢复都完成且工作负载准备好恢复为止。

具体用法因应用而异,但以下示例展示了 Python 应用的快照触发器。如需从此示例工作负载触发快照,请完成以下步骤:

  1. 将以下清单保存为 my-app.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-app
      namespace: NAMESPACE
      labels:
        app: my-app
    spec:
      serviceAccountName: KSA_NAME
      runtimeClassName: gvisor
      containers:
      - name: my-container
        image: python:3.10-slim
        command: ["python3", "-c"]
        args:
          - |
            import time
            def trigger_snapshot():
              try:
                with open("/proc/gvisor/checkpoint", "r+") as f:
                  f.write("1")
                  res = f.read().rstrip()
                  print(f"GKE Pod Snapshot: {res}")
              except FileNotFoundError:
                print("GKE Pod Snapshot file does not exist -- Pod Snapshots is disabled")
                return
            i = 0
            while True:
              print(f"Count: {i}", flush=True)
              if (i == 20): #simulate the application being ready to snapshot at 20th count
                trigger_snapshot()
              i += 1
              time.sleep(1)
        resources:
          limits:
            cpu: "500m"
            memory: "512Mi"
          requests:
            cpu: "250m"
            memory: "256Mi"
    

    替换以下内容:

    • NAMESPACE:Pod 的命名空间。
    • KSA_NAME:您的 KSA 的名称。
  2. 部署应用:

    kubectl apply -f my-app.yaml
    

手动触发快照

如需手动触发特定 Pod 的按需快照,请创建 PodSnapshotManualTrigger 资源。

  1. 以下示例针对名为 my-pod 的 Pod 触发了快照。将以下清单保存为 example-manual-trigger.yaml

    apiVersion: podsnapshot.gke.io/v1
    kind: PodSnapshotManualTrigger
    metadata:
      name: example-manual-trigger
      namespace: NAMESPACE
    spec:
      targetPod: my-pod
    

    NAMESPACE 替换为您的 Pod 的命名空间。

  2. 应用清单:

    kubectl apply -f example-manual-trigger.yaml
    

如需确认快照是否已成功触发,请检查 PodSnapshotManualTrigger 资源的 status 字段:

kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io example-manual-trigger -n NAMESPACE -o yaml

status 字段用于指示触发快照是成功还是失败。

验证快照

您可以通过查看 GKEPodSnapshotting 事件的事件记录来确认是否已拍摄快照:

kubectl get events -o \
custom-columns=NAME:involvedObject.name,CREATIONTIME:.metadata.creationTimestamp,REASON:.reason,MESSAGE:.message \
--namespace NAMESPACE \
--field-selector involvedObject.name=POD_NAME,reason=GKEPodSnapshotting

替换以下内容:

  • POD_NAME:Pod 的名称,例如 my-appmy-pod
  • NAMESPACE:Pod 的命名空间。

输出将类似以下内容:

NAME                                    CREATIONTIME           REASON               MESSAGE
default/5b449f9c7c-bd7pc                2025-11-05T16:25:11Z   GKEPodSnapshotting   Successfully checkpointed the pod to PodSnapshot

后续步骤

了解如何从 Pod 快照恢复工作负载