GKE Pod 快照简介

Google Kubernetes Engine (GKE) Pod 快照通过恢复正在运行的 Pod 的快照来帮助缩短工作负载启动延迟时间。Pod 快照会保存整个 Pod 状态,包括内存和文件系统更改。创建新副本时,系统会从快照恢复这些副本,从而使工作负载能够恢复,而不是从新状态开始。

本文档从概念上简要介绍了 GKE Pod 快照。如需启用和使用此功能,请参阅以下文档:

  1. 准备使用 Pod 快照
  2. 触发 Pod 快照
  3. 从 Pod 快照恢复工作负载

何时使用 Pod 快照

对于初始化时间较长的工作负载,请使用 Pod 快照,例如将大型模型加载到 CPU 或 GPU 内存中的 AI 推理工作负载,或加载许多库和依赖项的大型应用。启动时间已经很短的工作负载通常不会受益于 Pod 快照。

Pod 快照的工作原理

GKE Pod 快照会存储 Pod 在特定时间点的确切进程状态。创建新副本时,Pod 不会从全新状态进行初始化,而是从快照恢复,并从拍摄快照时开始恢复执行。

如需使用 Pod 快照,您需要创建 Kubernetes 自定义资源定义 (CRD),以声明方式配置快照行为。在每个 GKE 节点上运行的代理会管理快照生命周期。根据您定义的政策,代理会确定何时创建新快照,以及何时使用现有快照来恢复新 Pod。在 GKE 控制平面上运行的控制器会清理过时的快照并解决问题。Cloud Storage 会存储您的 Pod 快照。

快照内容

下表介绍了 Pod 快照中包含和不包含的内容:

类别 包含在快照中 未包含在快照中
应用状态 整个应用状态:所有打开的文件描述符、线程、CPU 寄存器和内存。
文件系统 容器根文件系统 (rootfs)、EmptyDir 卷和 tmpfs 装载。 前一列未涵盖的任何内容。最值得注意的是,永久性卷不会进行检查点设置。
网络 环回连接、监听套接字和 Unix 网域套接字。 外部连接不会恢复(会在恢复时终止)。系统不会恢复用户添加的规则(例如 iptablesnftables)和路线。

CustomResourceDefinitions

Pod 快照通过以下 CRD 以声明方式进行配置:

  • PodSnapshotStorageConfig:指定快照的存储位置。仅支持 Cloud Storage 存储分区
  • PodSnapshotPolicy:根据 Kubernetes 标签选择器定义要创建快照的 Pod。此资源包含该功能的大部分配置选项,包括如何触发快照、快照范围和保留政策。
  • PodSnapshotManualTrigger:(可选)如果您不使用工作负载触发器,则定义一个手动触发器,用于为特定 Pod 创建快照。

快照触发器

您可以通过以下方式触发 Pod 快照:

  • 工作负载触发器:Pod 内的应用向 GKE 代理发出信号,表明其已准备好进行快照。此类触发器在工作负载周期中执行一次,例如在工作负载就绪状态下执行。此方法最适合用于缩短横向伸缩工作负载的启动延迟时间。
  • 手动触发:您可以通过创建 PodSnapshotManualTrigger 自定义资源,按需为特定 Pod 触发快照。此类触发器可根据需要执行任意次数。此方法最适合无法修改应用来发出就绪信号的情况。

快照匹配和兼容性

为确保快照与恢复的工作负载兼容,GKE 会在原始已设置检查点的 Pod 与目标 Pod 之间执行兼容性匹配。

兼容性由以下规则决定:

  • 选择顺序:默认情况下,GKE 会从与 Pod 的命名空间和配置匹配的最新 PodSnapshot 资源中恢复工作负载。
  • 匹配条件:兼容性检查因 PodSnapshotPolicy 中配置的快照范围(whole-podrootfs-only)而异。

whole-pod 范围匹配(默认)

对于具有默认 whole-pod 范围的政策,GKE 会检查以下内容:

  1. 精简规范哈希:GKE 会根据 Pod 规范中的基本运行时字段生成一个唯一哈希。为了成功恢复,目标 Pod 必须从其精简规范中生成相同的哈希。此检查可确保已设置检查点和已恢复的 Pod 在运行时配置方面完全相同。

    Pod 对象的以下字段属于精简规范,会影响唯一哈希:

    • metadata:
      • annotations:仅与 gVisor 运行时相关的注释(例如以 dev.gvisor.* 前缀开头的注释)。
      • labelsbatch.kubernetes.io/job-completion-index
    • spec:
      • volumes: name, volumeSource, hostPath, persistentVolumeClaim, configMap
      • containers
        • name
        • image
        • command
        • args
        • workingDir
        • ports: name, containerPort, protocol
        • volumeMounts: name, readOnly, recursiveReadOnly, mountPath, subPath, mountPropagation, subPathExpr
        • volumeDevicesname
        • lifecyclepostStartpreStop
        • terminationMessagePath
        • terminationMessagePolicy
        • securityContext(以及所有子字段)
        • stdin
        • stdinOnce
        • tty
      • initContainers:与 containers 相同的子字段。
      • dnsPolicy
      • automountServiceAccountToken
      • hostNetwork
      • hostPID
      • hostIPC
      • shareProcessNamespace
      • securityContext
      • dnsConfig
      • runtimeClassName
      • os
      • hostUsers
  2. 硬件兼容性:目标 Pod 必须在具有与原始已设置检查点的 Pod 相同的机器系列和 CPU 架构的节点上运行(例如,从 N2 到 N2,或从 G2 到 G2)。

  3. 版本兼容性:gVisor 内核版本和 GPU 驱动程序版本必须与原始快照中捕获的版本一致。

rootfs-only 范围匹配

如果您使用 rootfs-only 范围(适用于 GKE 1.35.3-gke.1031000 版及更高版本)配置政策,匹配要求会宽松一些:

  • GKE 不会计算或比较精简的 Pod 规范哈希值。这种宽松的匹配方式可让您将快照恢复到具有不同资源、环境或其他配置字段的目标 Pod,前提是底层容器映像和节点版本兼容。
  • 由于进程内存不会恢复,因此您可以将在一台机器家族上拍摄的快照恢复到另一台机器家族(包括 E2 机器类型)。

分组规则匹配

如果政策使用 snapshotGroupingRules 字段按特定标签值(例如按租户或环境)对快照进行分组,则恢复的 Pod 必须具有完全相同的标签键和值。Pod 快照控制器仅从匹配的组中选择快照。如需详细了解如何设置分组标签,请参阅配置其他 Pod 快照政策

恢复准备状态和后台加载

从快照恢复 Pod 时,系统会先恢复 gVisor 内核,这通常需要几秒钟的时间。为了最大限度缩短启动延迟时间,应用会在内核恢复后立即恢复。它不会等待应用内存完全加载。应用内存通过后台流式传输机制恢复。

如果应用尝试访问尚未加载的内存部分,就会发生缺页中断。gVisor 会拦截此中断,暂停应用线程,并立即从存储空间中提取所需的内存页。此按需提取的优先级高于后台数据流。

由于这种后台加载,如果应用需要尚未流式传输的内存,那么在恢复后的前几秒内,内存访问可能会出现少量延迟。当内存状态完全同步时,此延迟时间会消失。

此后台加载行为也适用于 GPU 状态。例如,大语言模型 (LLM) Pod 可能看起来处于 Running 状态,并且即使其 GPU 内存仍在填充中,也会响应网络检查。在 GPU 状态完全恢复之前,模型不会完全响应推理。由于存在此延迟,因此在衡量恢复速度时,请务必捕获模型服务器何时启动。您可以使用“第一个词元的时间”(TTFT) 或 Pod 就绪性探测等指标来检查模型服务器的启动时间。

GPU 状态

Pod 快照支持捕获 GPU 的状态。当您为使用 GPU 的 Pod 触发快照时,NVIDIA cuda-checkpoint 工具会将 GPU 状态保存到进程内存中。这意味着,存储在 GPU 上的任何数据(例如模型权重)都会包含在快照中。然后,Pod 会暂停并拍摄快照。在恢复期间,该过程会反转。

由于 GPU 状态会写入进程内存,因此在快照和恢复操作期间,Pod 内存用量会增加。在为 Pod 设置内存限额时,您应考虑这一额外的内存需求。

恢复的 Pod 的注意事项

从 Kubernetes API 的角度来看,系统会创建一个新的 Pod。当 Pod 启动时,如果存在与该 Pod 对应的快照,则系统会从该快照恢复 Pod,包括原始内存和进程状态。不过,Pod 的状态必须在某些方面发生变化,才能作为新的唯一实例运行。

请考虑恢复后出现的以下状态变化:

  • 网络接口:恢复的 Pod 会收到新的 IP 地址。所有接口和路由都会重新配置。在拍摄快照时存在的有效网络连接会在恢复时关闭。监听套接字、环回连接和 Unix 网域套接字连接会继续正常运行。
  • 主机名:恢复的 Pod 会采用新身份并接收新主机名。
  • 实际用时:实际用时会跳到当前时间。
  • 应用状态:每个 Pod 的应用状态必须是唯一的,例如实验 ID 或随机数种子,并且必须在恢复后重新初始化。
  • Secret:在拍摄快照之前创建的加密密钥和证书必须重新创建。
  • 环境变量:您可以在快照和恢复之间更改环境变量。不过,由于环境变量存储在应用内存中,因此 GKE Sandbox 无法可靠地查找和替换它们。如果工作负载在恢复后依赖于新的环境变量,则必须手动刷新 Pod。新环境变量可在 /proc/gvisor/spec_environ 文件中使用。文件格式与 /proc/<pid>/environ 相同。

多租户和身份

Pod 快照需要为每个 Pod 的 Kubernetes ServiceAccount (KSA) 手动添加 IAM 绑定,才能访问 Cloud Storage。手动 IAM 绑定可能需要一段时间才能传播,如果您需要在创建 Pod 后立即拍摄快照,这可能会成为问题。

为了帮助解决延迟问题并简化多租户管理,您可以选择使用 GKE 节点服务账号按需创建短期令牌,而不是手动将 IAM 绑定到 KSA。如需使用此方法配置 Pod 快照,请在 PodSnapshotStorageConfig 对象中使用 tokenSource 字段,并指定以下值之一:

  • podKSA(默认):将 Pod 的 KSA 手动绑定到 Cloud Storage 存储桶。
  • federatedP4SA:使用由节点服务账号铸造的特定于路径的令牌。

限制和要求

GKE Pod 快照具有以下限制:

  • Pod 必须在 GKE Sandbox 中运行,因为 Pod 快照依赖于 GKE Sandbox 提供的 gVisor 容器运行时。
  • 使用默认 whole-pod 快照范围时,Pod 快照不支持 E2 机器类型。文件系统快照 (rootfs-only) 支持 E2 机器类型。
  • 针对 Pod 快照的 GPU 支持有以下要求和限制:
    • 单 GPU Pod 在单 GPU 节点和多 GPU 节点上均受支持。
    • 多 GPU Pod 仅受 L4 GPU(g2-standard-* 机器类型)支持。
    • 不支持使用多实例 GPU (MIG) 进行 GPU 共享。
    • 在 GKE 版本 1.35.0-gke.1738000 及更低版本中,在多 GPU 节点上运行的 Pod 必须使用该节点上的所有可用 GPU。在 1.35.0-gke.1738000 及更高版本中,Pod 可以使用节点上的部分 GPU。
    • Pod 快照支持以下机器类型:
      • g2-standard-4 (1 x L4)
      • g2-standard-8 (1 x L4)
      • g2-standard-12 (1 x L4)
      • g2-standard-16 (1 x L4)
      • g2-standard-32 (1 x L4)
      • g2-standard-48 (4 x L4)
      • g2-standard-96 (8 x L4)
      • a2-highgpu-1g(1 个 A100-40GB)
      • a2-ultragpu-1g(1 个 A100-80GB)
      • a3-highgpu-1g (1 x H100-80GB)
  • Pod 快照不支持 Cloud Storage FUSE CSI 驱动程序边车容器。
  • Pod 快照不支持 TPU 机器类型。

后续步骤