为了缩短 Google Kubernetes Engine (GKE) 工作负载的启动延迟时间,您可以为正在运行的 Pod 创建快照,并从中恢复新 Pod。本文档介绍了如何创建 Pod 快照政策,以及如何通过工作负载或手动触发快照。如需详细了解 Pod 快照的工作原理,请参阅 GKE Pod 快照简介。
平台管理员、运维人员和应用开发者可以使用本文档配置快照政策并触发快照。如需详细了解我们在 Google Cloud内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 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 标签匹配的选择器:
将以下清单保存为
example-pod-snapshot-policy.yaml。此示例创建了一个适用于具有app: my-app标签的 Pod 的政策。该政策使用您在为 Pod 快照做准备中创建的example-pod-snapshot-storage-configPodSnapshotStorageConfig 自定义资源来定义快照存储位置: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替换以下内容:
NAMESPACE:Pod 的命名空间。使用您在为 Pod 快照做准备中向其授予 Cloud Storage 访问权限的同一命名空间。TRIGGER_TYPE:触发器类型。 支持的值包括:workload(适用于基于工作负载的触发器)或manual(适用于按需快照)。
在此示例中,
postCheckpoint: resume设置会在 GKE 创建快照后使 Pod 保持运行状态。如需查看可配置字段的完整列表,请参阅 PodSnapshotPolicy 规范。
应用清单:
kubectl apply -f example-pod-snapshot-policy.yaml
配置其他 Pod 快照政策设置
除了必需的选择器、存储配置和触发器之外,PodSnapshotPolicy 自定义资源还支持可选设置。这些额外设置可控制每个快照捕获的内容、GKE 保留快照的时长以及 GKE 如何对快照进行分组以进行恢复:
快照范围:如需指定要在快照中捕获 Pod 状态的哪些部分,请配置
spec.snapshotScope字段。支持的值包括whole-pod(默认)和rootfs-only。whole-pod范围会捕获整个 Pod,包括应用状态、内存和文件系统。rootfs-only范围仅捕获容器根文件系统。rootfs-only范围需要 GKE 1.35.3-gke.1031000 或更高版本。自动清理:如需自动清理旧的 PodSnapshot 自定义资源,请使用
spec.retentionConfig字段配置保留政策。您可以使用lastAccessTimeout字段指定时长,例如7d。此时间段过后,GKE 会删除快照。快照分组:如需隔离在类似环境但不同上下文中拍摄的快照,请在
spec.snapshotGroupingRules字段中指定分组标签。例如,在多租户场景中,如果所有用户的基础 Pod 都相同,您可以按用户或群组隔离快照。在恢复期间,GKE 仅从同一标签组中选择快照。如需详细了解此分组如何影响恢复期间的兼容性匹配,请参阅分组规则匹配。
您可以单独配置快照范围、保留和分组设置。以下示例展示了 PodSnapshotPolicy 自定义资源中的所有三项设置:
# Multiple lines are omitted here
spec:
snapshotScope: rootfs-only
retentionConfig:
lastAccessTimeout: 7d
snapshotGroupingRules:
groupByLabelValue:
labels: ["tenant", "environment"]
groupRetentionPolicy:
maxSnapshotCountPerGroup: 5
如需查看可配置字段的完整列表,请参阅 PodSnapshotPolicy 规范。
优化快照大小
快照越大,保存和恢复所需的时间就越长。在触发快照之前,请删除 GKE 从快照恢复 Pod 后应用不需要的任何临时文件或应用状态,以缩减快照大小。
使用默认的 whole-pod 快照范围时,GKE Sandbox 会捕获所有容器的完整状态,包括:
- 应用状态,例如内存和寄存器
- 对根文件系统和
tmpfs装载(包括emptyDir卷)的更改 - 内核状态,例如打开的文件描述符、线程和套接字
对于大语言模型 (LLM) 等工作负载,优化快照大小尤为重要。LLM 服务器通常会将模型权重下载到本地存储空间(rootfs 或 tmpfs),然后再将其加载到 GPU 中。当您创建快照时,GKE Sandbox 会同时保存 GPU 状态和模型权重文件。在这种情况下,如果模型大小为 100 GB,则生成的快照大小约为 200 GB(100 GB 的模型文件,加上 100 GB 的 GPU 状态)。应用将模型权重加载到 GPU 后,通常不需要文件系统中的文件即可运行。通过在触发快照之前删除这些模型文件,您可以将快照大小缩减一半,并以显著降低的延迟时间恢复应用。
触发快照
选择以下方法之一来触发快照:
工作负载触发器:如果您可以修改应用,使其在准备好创建快照时发出信号(例如在初始化完成后),请使用此方法。此方法最适合缩短横向伸缩工作负载的启动延迟时间。工作负载触发器在工作负载周期内仅运行一次。
手动触发器:如果您无法修改应用来发出就绪信号,或者您希望按需创建特定 Pod 的快照,请使用此方法。您可以根据需要创建任意数量的手动触发器。
从工作负载触发快照
如需从应用代码中触发快照,请将应用配置为在准备好创建快照时发送信号。如需发出就绪信号,请将值 1 写入 /proc/gvisor/checkpoint 文件,例如,通过运行 echo 1 > /proc/gvisor/checkpoint 命令。写入操作会异步启动快照过程并立即返回。从同一文件描述符读取数据会阻塞读取过程,直到快照或恢复操作完成且工作负载准备好恢复。
在从工作负载触发快照之前,请确保快照政策选择了 Pod。该政策中 triggerConfig.type 字段的值必须设置为 workload。
确切用法因应用而异,但以下示例展示了 Python 应用的快照触发器。如需从此示例工作负载触发快照,请按照以下步骤操作:
将以下清单保存为
my-app.yaml。在此示例中,app: my-app标签与示例快照政策中的选择器匹配,并且runtimeClassName: gvisor设置在 GKE Sandbox 中运行 Pod:apiVersion: v1 kind: Pod metadata: name: my-app namespace: NAMESPACE labels: app: my-app spec: serviceAccountName: SERVICEACCOUNT_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 readiness at the 20th count trigger_snapshot() i += 1 time.sleep(1) resources: limits: cpu: "500m" memory: "512Mi" requests: cpu: "250m" memory: "256Mi"替换以下内容:
NAMESPACE:Pod 的命名空间。SERVICEACCOUNT_NAME:您在准备 Pod 快照中向其授予 Cloud Storage 访问权限的 ServiceAccount 对象的名称。
部署应用:
kubectl apply -f my-app.yaml应用启动并发出就绪信号后,GKE Sandbox 会创建快照。如需确认快照是否成功,请参阅验证快照。
手动触发快照
在手动触发快照之前,请确保目标 Pod 正在运行,并且快照政策选择了该 Pod。该政策中 triggerConfig.type 字段的值必须设置为 manual。
如需为特定 Pod 手动触发按需快照,请按照以下步骤创建 PodSnapshotManualTrigger 自定义资源:
将以下清单保存为
example-manual-trigger.yaml。此示例会为名为my-pod的 Pod 触发快照:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotManualTrigger metadata: name: example-manual-trigger namespace: NAMESPACE spec: targetPod: my-pod将
NAMESPACE替换为 Pod 的命名空间。应用清单:
kubectl apply -f example-manual-trigger.yaml如需确认快照已成功触发,请检查 PodSnapshotManualTrigger 自定义资源的
status部分:kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io \ example-manual-trigger \ --namespace NAMESPACE -o yaml将
NAMESPACE替换为 Pod 的命名空间。如果触发器成功,则
status.conditions字段会显示检查点已完成,status.snapshotCreated字段会显示所创建的 PodSnapshot 自定义资源的名称。
验证快照
如需确认 GKE 已创建快照,请查看事件记录中是否有 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
替换以下内容:
NAMESPACE:Pod 的命名空间。POD_NAME:您的 pod 的名称。
输出类似于以下内容:
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
MESSAGE 列显示 Successfully checkpointed the pod to PodSnapshot,这确认了 GKE 已将 Pod 状态保存到 PodSnapshot 自定义资源。如需查看和管理 PodSnapshot 自定义资源,请参阅管理快照。