使用 Pod 快照保存和恢复智能体沙盒环境

本文档介绍了如何使用 GKE Pod 快照来保存正在运行的 Agent Sandbox 环境的状态。

Agent Sandbox 提供了一个隔离的环境,用于执行不受信任的代码(例如由大语言模型 [LLM] 生成的代码),从而提高安全性。直接在集群中运行此类代码会带来安全风险,因为不受信任的代码可能会访问或干扰其他应用或底层集群节点本身。

借助 GKE Pod 快照,您可以保存和恢复沙盒环境的状态。此功能之所以有用,原因如下:

  • 快速启动:通过从预热的快照恢复来缩短沙盒启动时间。
  • 长时间运行的代理:暂停需要长时间运行的沙盒,稍后再恢复,或将其移至其他节点,而不会丢失进度。
  • 有状态工作负载:通过保存和恢复沙盒环境的状态,持久保留智能体的上下文,例如对话历史记录或中间计算结果。
  • 可重现性:捕获特定状态并将其用作基础,以启动多个具有相同初始状态的新沙盒。

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

  • 手动触发:您创建 PodSnapshotManualTrigger 资源来触发快照。
  • 工作负载触发器:沙盒应用本身会发出信号,表明何时可以保存。

本文档介绍了如何手动触发快照。

准备工作

  1. 在 Google Cloud 控制台的项目选择器页面上,选择或创建 Google Cloud 项目。

    选择或创建项目所需的角色

    • 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
    • 创建项目:如需创建项目,您需要拥有 Project Creator 角色 (roles/resourcemanager.projectCreator),该角色包含 resourcemanager.projects.create 权限。了解如何授予角色

    转到“项目选择器”

  2. 验证是否已为您的 Google Cloud 项目启用结算功能

  3. 启用 Google Kubernetes Engine、Cloud Storage、Identity and Access Management (IAM) API。

    启用 API 所需的角色

    如需启用 API,您需要拥有 Service Usage Admin IAM 角色 (roles/serviceusage.serviceUsageAdmin),该角色包含 serviceusage.services.enable 权限。了解如何授予角色

    启用 API

  4. 在 Google Cloud 控制台中,激活 Cloud Shell。

    激活 Cloud Shell

要求

GKE Pod 快照需要 GKE 1.35.3-gke.1234000 版或更高版本。支持 Autopilot 模式和 Standard 模式。

由于 Pod 快照需要 GKE Sandbox,因此您的环境会受到某些限制。例如,Pod 快照不支持 E2 机器类型。因此,本教程会创建一个由 N2 机器组成的节点池。

如需查看限制的完整列表(包括有关使用基于 GPU 的机器类型的信息),请参阅限制和要求

定义环境变量

为了简化您在本文档中运行的命令,您可以在 Cloud Shell 中设置环境变量。这些变量用于存储项目 ID、将存储快照的 Cloud Storage 存储桶的名称以及 GKE 集群的位置等值。 Google Cloud

定义这些变量后,您可以通过引用变量名称(例如 $CLUSTER_NAME)在多个命令中重复使用它们,而无需每次都重新输入或替换值。这种方法可让流程更易于理解,并降低出错风险。

如需在 Cloud Shell 中定义以下有用的环境变量,请运行以下命令:

export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export GKE_LOCATION="us-central1"
export CLUSTER_VERSION="1.35.3-gke.1234000"
export AGENT_SANDBOX_VERSION="v0.4.6"
export NODE_POOL_NAME="agent-sandbox-node-pool"
export MACHINE_TYPE="n2-standard-2"
export SNAPSHOTS_BUCKET_NAME="agent-sandbox-snapshots-${PROJECT_ID}"
export SNAPSHOT_NAMESPACE="pod-snapshots-ns"
export SNAPSHOT_KSA_NAME="pod-snapshot-sa"
export SNAPSHOT_FOLDER="my-snapshots"
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")

以下是对这些环境变量的说明:

  • PROJECT_ID:当前 Google Cloud 项目的 ID。定义此变量有助于确保所有资源(例如 GKE 集群)都在正确的项目中创建。
  • CLUSTER_NAME:GKE 集群的名称(例如 agent-sandbox-cluster)。
  • GKE_LOCATION:将创建 GKE 集群的 Google Cloud 区域(例如 us-central1)。
  • CLUSTER_VERSION:GKE 集群的版本,必须为 1.35.3-gke.1234000 或更高版本。
  • AGENT_SANDBOX_VERSION:要部署到集群的 Agent Sandbox 控制器的版本。
  • NODE_POOL_NAME:将运行沙盒化工作负载的节点池的名称(例如 agent-sandbox-node-pool)。
  • MACHINE_TYPE:节点池中节点的机器类型(例如 n2-standard-2)。Pod 快照不支持 E2 机器类型。如果您想为节点池中的节点使用基于 GPU 的机器类型,请参阅限制和要求。 如需详细了解不同的机器系列以及如何在不同选项之间进行选择,请参阅机器家族资源和比较指南
  • SNAPSHOTS_BUCKET_NAME:您将创建的用于存储快照的 Cloud Storage 存储桶的名称。
  • SNAPSHOT_NAMESPACE:您的快照工作负载和服务账号将所在的 Kubernetes 命名空间。
  • SNAPSHOT_KSA_NAME:您的工作负载将用于进行身份验证的 Kubernetes 服务账号的名称。
  • SNAPSHOT_FOLDER:Cloud Storage 存储桶中用于整理快照的目录。
  • PROJECT_NUMBER:项目的唯一数字标识符,用于 IAM 权限绑定。

配置步骤概览

如需启用 Agent Sandbox 环境的 Pod 快照,您需要执行一些配置步骤。为了理解这些步骤,最好先了解一些关键概念,然后再了解快照流程:

主要概念

  • 环境:沙盒化应用在 GKE 集群节点的 Kubernetes Pod 中运行。
  • 身份:Pod 与 Kubernetes 服务账号相关联,并在您创建的特殊命名空间中运行。Kubernetes 服务账号和命名空间共同构成一个唯一身份,用于授予 Pod 对 Google Cloud 资源的安全访问权限。
  • 权限:如需允许将快照保存到 Cloud Storage,必须向 Pod 的身份授予特定的 IAM 权限,使其能够写入 Cloud Storage 存储桶

快照流程

  1. 触发:手动(外部)或由沙盒化工作负载本身启动快照。本文档演示了通过创建 PodSnapshotManualTrigger 资源来启动的手动触发器。
  2. 捕获:GKE 会捕获 Pod 的运行状态,例如 Pod 的内存状态及其文件系统。
  3. 上传:GKE 使用授予给 Pod 的 Kubernetes 服务账号的权限,将捕获的状态作为快照文件上传到指定的 Cloud Storage 存储桶。

如需详细了解 GKE 如何使用 Kubernetes 服务账号和 IAM 角色来访问 Google Cloud 资源,请参阅从 GKE 工作负载向 Google Cloud API 进行身份验证

如需启用 Agent Sandbox 环境的 Pod 快照,请执行以下配置。首先,您需要创建一个启用了 Workload Identity Federation for GKE 和 Pod 快照功能的 GKE 集群,从而准备集群环境。接下来,您需要配置 Cloud Storage 和 IAM 政策,以帮助确保您的快照安全存储,并确保您的沙盒具有必要的权限。最后,您需要创建快照资源,以指定沙盒的存储位置和政策。

下表总结了您需要执行的配置步骤,后续部分将详细介绍每个步骤:

主题 任务
集群设置 1. 创建 GKE 集群,并启用 Pod 快照和 Workload Identity Federation for GKE 功能。
2. 部署 Agent Sandbox。
配置存储空间和权限 1. 创建 Cloud Storage 存储桶和受管理的文件夹。
2. 创建自定义 IAM 角色。
3. 创建 Kubernetes 命名空间和 Kubernetes 服务账号 (KSA)。
4. 将 IAM 角色绑定到 Kubernetes 服务账号。
5. 向快照控制器授予权限。
配置快照资源 1. 创建 PodSnapshotStorageConfig
2. 创建 PodSnapshotPolicy
3. 创建 SandboxTemplate

集群设置

沙盒应用在 GKE 集群节点的 Pod 内运行,因此您需要设置集群环境。本部分介绍了如何创建 GKE 集群并部署代理沙盒控制器。

创建符合要求的新 GKE 集群

创建启用了 Pod 快照的新 GKE 集群。为了实现完整的功能兼容性,请指定集群版本 1.35.3-gke.1234000 或更高版本:

Autopilot

创建具有所需功能的 Autopilot 集群:

gcloud container clusters create-auto ${CLUSTER_NAME} \
   --cluster-version=${CLUSTER_VERSION} \
   --enable-pod-snapshots \
   --location=${GKE_LOCATION}

标准

创建具有所需功能的 Standard 集群:

gcloud container clusters create ${CLUSTER_NAME} \
   --cluster-version=${CLUSTER_VERSION} \
   --enable-pod-snapshots \
   --machine-type=${MACHINE_TYPE} \
   --workload-pool=${PROJECT_ID}.svc.id.goog \
   --workload-metadata=GKE_METADATA \
   --num-nodes=1 \
   --location=${GKE_LOCATION}

创建启用了 GKE Sandbox的节点池。GKE Sandbox 是一项基于开源 gVisor 项目的容器安全功能,可在运行的应用和主机操作系统之间提供额外的隔离层:

gcloud container node-pools create ${NODE_POOL_NAME} \
   --cluster ${CLUSTER_NAME} \
   --num-nodes=1 \
   --location=${GKE_LOCATION} \
   --project=${PROJECT_ID} \
   --machine-type=${MACHINE_TYPE} \
   --sandbox type=gvisor

检索凭据

检索集群的凭证,以便 kubectl CLI 可以连接到集群:

gcloud container clusters get-credentials ${CLUSTER_NAME} \
    --location=${GKE_LOCATION}

将 Agent Sandbox 控制器部署到您的集群

您可以将正式版清单应用于集群,以部署 Agent Sandbox 控制器及其所需的组件。这些清单是配置文件,用于指示 Kubernetes 下载在集群上部署和运行 Agent Sandbox 控制器所需的所有必要组件。

如需将 Agent Sandbox 部署到 GKE 集群,请运行以下命令:

# Apply the main manifest for the controller and its Custom Resource Definitions (CRDs)
kubectl apply \
-f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/manifest.yaml \
-f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/extensions.yaml

验证控制器

应用清单后,检查 Agent Sandbox 控制器 Pod 是否在 agent-sandbox-system 命名空间中正常运行。当您在上一步中应用清单时,这些清单会自动创建 agent-sandbox-system 命名空间。

kubectl get pods -n agent-sandbox-system

等待 Pod 在状态列中显示“正在运行”,在就绪列中显示“1/1”。当 Pod 正常运行时,输出类似于以下内容:

NAME                         READY   STATUS    RESTARTS   AGE
agent-sandbox-controller-0      1/1     Running   0          44d

现在,Agent Sandbox 控制器已在运行,它可以自动为在集群中创建的任何 Sandbox 资源创建和管理沙盒环境。

配置存储空间和权限

本部分介绍如何配置 Pod 快照所需的存储空间和权限。您将创建一个 Cloud Storage 存储桶和一个托管文件夹来存储快照数据。然后,您向沙盒和快照控制器授予访问相应存储空间所需的权限。

创建 Cloud Storage 存储桶

创建一个存储桶来存储快照。为确保快照流程快速且经济高效,我们建议您使用以下设置创建存储桶:

  • 启用分层命名空间:分层命名空间功能可将存储桶整理成文件系统层次结构,而不是扁平的命名空间。此配置可实现更高的读取和写入吞吐量,从而加快保存和恢复快照的速度。
  • 停用软删除功能:软删除功能通过将已删除的文件保留一段时间来保护数据。不过,在上传过程中,快照进程会创建并删除许多临时文件。我们建议您停用软删除,以避免因存储这些临时文件而产生不必要的费用。

如需使用这些设置创建存储桶,请运行以下命令:

gcloud storage buckets create "gs://${SNAPSHOTS_BUCKET_NAME}" \
    --uniform-bucket-level-access \
    --enable-hierarchical-namespace \
    --soft-delete-duration=0d \
    --location="${GKE_LOCATION}"

创建托管文件夹

创建受管理的文件夹,以便整理存储桶中的快照。借助托管式文件夹,您可以将 IAM 权限应用于特定文件夹,而不是整个存储桶。此文件夹级访问权限会将沙盒的访问权限限制为仅限其自己的快照,并将这些快照与存储桶中的其他数据隔离开来。

如需创建托管文件夹,请运行以下命令:

gcloud storage managed-folders create "gs://${SNAPSHOTS_BUCKET_NAME}/${SNAPSHOT_FOLDER}/"

配置服务账号和 IAM 角色

为了让 GKE 能够安全地保存快照,运行沙盒化工作负载的 Pod 所使用的 Kubernetes 服务账号需要具有向存储桶写入数据的权限。您可以通过将 Google CloudIAM 角色绑定到 Pod 使用的 Kubernetes 服务账号来授予此权限。本部分介绍如何创建自定义 IAM 角色、创建 Kubernetes 服务账号,以及配置必要的权限。

  1. 创建名为 podSnapshotGcsReadWriter 的自定义 IAM 角色,其中包含写入快照数据所需的权限:

    gcloud iam roles create podSnapshotGcsReadWriter \
        --project="${PROJECT_ID}" \
        --permissions="storage.objects.get,storage.objects.create,storage.objects.delete,storage.folders.create"
    

    成功创建角色后,输出如下所示:

    Created role [podSnapshotGcsReadWriter].
    etag: BwZJUfjNbew=
    includedPermissions:
    - storage.folders.create
    - storage.objects.create
    - storage.objects.delete
    - storage.objects.get
    name: projects/${PROJECT_ID}/roles/podSnapshotGcsReadWriter
    stage: ALPHA
    title: podSnapshotGcsReadWriter
    
  2. 创建沙盒及其服务账号所在的命名空间:

    kubectl create namespace "${SNAPSHOT_NAMESPACE}"
    
  3. 在您刚刚创建的命名空间中创建 Kubernetes 服务账号。Kubernetes 服务账号和命名空间共同构成一个唯一身份,用于授予您的沙盒对 Google Cloud 资源的访问权限:

    kubectl create serviceaccount "${SNAPSHOT_KSA_NAME}" \
        --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. roles/storage.bucketViewer 角色授予命名空间中的所有服务账号。此角色允许账号查看存储桶的元数据,但不能读取或写入数据本身:

    gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
        --member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/namespace/${SNAPSHOT_NAMESPACE}" \
        --role="roles/storage.bucketViewer"
    
  5. 向沙盒的 Kubernetes 服务账号授予自定义 podSnapshotGcsReadWriter 角色。此绑定仅允许此特定账号将数据写入受管理的文件夹:

    gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
        --member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${SNAPSHOT_NAMESPACE}/sa/${SNAPSHOT_KSA_NAME}" \
        --role="projects/${PROJECT_ID}/roles/podSnapshotGcsReadWriter"
    
  6. roles/storage.objectUser 角色授予 Kubernetes 服务账号。Pod 快照代理需要此角色才能对托管文件夹执行操作:

    gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
        --member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${SNAPSHOT_NAMESPACE}/sa/${SNAPSHOT_KSA_NAME}" \
        --role="roles/storage.objectUser"
    

向快照控制器授予权限

向 GKE 系统的快照控制器授予 objectUser 角色。此权限允许控制器管理快照生命周期,例如在您删除 PodSnapshot 资源时删除快照对象:

gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
    --member="serviceAccount:service-${PROJECT_NUMBER}@container-engine-robot." \
    --role="roles/storage.objectUser"

配置快照资源

本部分介绍如何为代理沙盒工作负载配置快照资源。

定义快照存储和规则

如需指定 GKE 将快照保存到何处以及哪些规则控制快照进程,请创建以下两个自定义资源:

  • PodSnapshotStorageConfig:此资源指定了 Cloud Storage 存储桶和文件夹位置,GKE 会将您的快照文件保存在其中。
  • PodSnapshotPolicy:此资源根据 Pod 的 Kubernetes 标签定义哪些 Pod 符合快照条件。它还指定了触发规则,例如快照是手动创建还是由沙盒工作负载启动。

如需一步到位地应用这两个资源,请在 Cloud Shell 中运行以下命令。此方法有助于确保正确注入环境变量:

kubectl apply -f - <<EOF
apiVersion: podsnapshot.gke.io/v1
kind: PodSnapshotStorageConfig
metadata:
  name: cpu-pssc-gcs
spec:
  snapshotStorageConfig:
    gcs:
      bucket: "${SNAPSHOTS_BUCKET_NAME}"
      path: "${SNAPSHOT_FOLDER}"
EOF

sleep 5

kubectl apply -f - <<EOF
apiVersion: podsnapshot.gke.io/v1
kind: PodSnapshotPolicy
metadata:
  name: cpu-psp
  namespace: ${SNAPSHOT_NAMESPACE}
spec:
  storageConfigName: cpu-pssc-gcs
  selector:
    matchLabels:
      app: agent-sandbox-workload
  triggerConfig:
    type: manual
    postCheckpoint: resume
EOF

验证配置

应用快照存储配置和政策后,请验证资源是否已准备就绪,可供使用。本部分介绍了如何检查这些自定义资源的状态。

  1. 检查 PodSnapshotStorageConfig 资源的状态:

    kubectl get podsnapshotstorageconfigs.podsnapshot.gke.io cpu-pssc-gcs \
      --namespace "${SNAPSHOT_NAMESPACE}" -o yaml
    

    输出应包含具有 type: Readystatus: "True" 的条件:

    status:
      conditions:
      - lastTransitionTime: "2025-10-31T18:18:02Z"
        message: Valid PodSnapshotStorageConfig
        reason: StorageConfigValid
        status: "True"
        type: Ready
    
  2. 检查 PodSnapshotPolicy 资源的状态:

    kubectl get podsnapshotpolicies.podsnapshot.gke.io cpu-psp \
      --namespace "${SNAPSHOT_NAMESPACE}" -o yaml
    

    输出应包含具有 type: Readystatus: "True" 的条件。它还应指明已找到引用的 PodSnapshotStorageConfig

    status:
      conditions:
      - lastTransitionTime: "2025-10-31T18:19:47Z"
        message: The referenced PodSnapshotStorageConfig "cpu-pssc-gcs" was found
        reason: StorageConfigValid
        status: "True"
        type: Ready
    

创建沙盒模板

现在,存储政策和权限已就绪,您可以创建 SandboxTemplateSandboxClaim 资源了。为了使快照流程正常运行,沙盒必须使用您在本文档前面部分创建的 Kubernetes 服务账号运行。沙盒还必须具有您之前在 PodSnapshotPolicy 中指定的标签。

此示例使用了一个 Python 应用,该应用会将递增的计数器输出到日志中。借助此计数器,您可以验证状态是否已成功保存并在稍后恢复。

Autopilot

Pod 快照不支持 E2 机器类型。在 Autopilot 中,GKE 可能会默认使用 E2 节点。为确保工作负载在兼容的硬件上运行,您应使用自定义 ComputeClass 来优先考虑兼容的机器系列。

  1. 将以下清单保存为 non-e2-class.yaml

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: non-e2-class
    spec:
      priorities:
      - machineFamily: n2
      - machineFamily: c3
      activeMigration:
        optimizeRulePriority: false
      whenUnsatisfiable: DoNotScaleUp
    
  2. 应用清单:

    kubectl apply -f non-e2-class.yaml
    
  3. 如需创建 SandboxTemplateSandboxClaim 资源,请应用以下清单。请注意,SandboxTemplate 是指您刚刚使用 cloud.google.com/compute-class: non-e2-class 节点选择器创建的 ComputeClass

    kubectl apply -f - <<EOF
    ---
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxTemplate
    metadata:
      name: python-runtime-template
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      podTemplate:
        metadata:
          labels:
            app: agent-sandbox-workload
        spec:
          serviceAccountName: ${SNAPSHOT_KSA_NAME}
          runtimeClassName: gvisor
          nodeSelector:
            cloud.google.com/compute-class: non-e2-class
          containers:
          - name: my-container
            image: python:3.10-slim
            command: ["python3", "-c"]
            args:
              - |
                import time
                i = 0
                while True:
                  print(f"Count: {i}", flush=True)
                  i += 1
                  time.sleep(1)
    ---
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxClaim
    metadata:
      name: python-sandbox-example
      namespace: ${SNAPSHOT_NAMESPACE}
      labels:
        app: agent-sandbox-workload
    spec:
      sandboxTemplateRef:
        name: python-runtime-template
    EOF
    

标准

如需创建 SandboxTemplateSandboxClaim 资源,请应用以下清单:

kubectl apply -f - <<EOF
---
apiVersion: extensions.agents.x-k8s.io/v1alpha1
kind: SandboxTemplate
metadata:
  name: python-runtime-template
  namespace: ${SNAPSHOT_NAMESPACE}
spec:
  podTemplate:
    metadata:
      labels:
        app: agent-sandbox-workload
    spec:
      serviceAccountName: ${SNAPSHOT_KSA_NAME}
      runtimeClassName: gvisor
      containers:
      - name: my-container
        image: python:3.10-slim
        command: ["python3", "-c"]
        args:
          - |
            import time
            i = 0
            while True:
              print(f"Count: {i}", flush=True)
              i += 1
              time.sleep(1)
---
apiVersion: extensions.agents.x-k8s.io/v1alpha1
kind: SandboxClaim
metadata:
  name: python-sandbox-example
  namespace: ${SNAPSHOT_NAMESPACE}
  labels:
    app: agent-sandbox-workload
spec:
  sandboxTemplateRef:
    name: python-runtime-template
EOF

您的沙盒现在正以正确的身份运行,可以进行快照。

创建快照

本部分介绍了如何手动触发正在运行的沙盒的快照。您创建以沙盒 Pod 为目标的触发器资源,然后验证快照进程是否成功完成。

  1. 检查初始计数器日志:在触发快照之前,查看正在运行的沙盒的日志,了解当前的计数器值。查看日志可建立基准,以便在恢复后进行比较。

    kubectl logs python-sandbox-example --namespace "${SNAPSHOT_NAMESPACE}" --tail=5
    

    输出结果会显示计数器的最后几行,例如:

    Count: 15
    Count: 16
    Count: 17
    

    请注意打印的最后几个“数量”值。

  2. 创建 PodSnapshotManualTrigger 资源:启动快照:

    kubectl apply -f - <<EOF
    apiVersion: podsnapshot.gke.io/v1
    kind: PodSnapshotManualTrigger
    metadata:
      name: cpu-snapshot-trigger
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      targetPod: python-sandbox-example
    EOF
    
  3. 验证手动触发是否成功

    kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io \
      --namespace "${SNAPSHOT_NAMESPACE}"
    

    输出应显示状态为 Complete,表明 GKE 已成功触发目标 Pod 的快照:

    NAME                   TARGET POD               STATUS     AGE
    cpu-snapshot-trigger   python-sandbox-example   Complete   XXs
    
  4. 通过描述触发器查看有关捕获状态的更多详细信息

    kubectl describe podsnapshotmanualtriggers.podsnapshot.gke.io cpu-snapshot-trigger \
      --namespace "${SNAPSHOT_NAMESPACE}"
    

    输出包含一个 Snapshot Created 部分,其中列出了存储在存储桶中的快照文件的唯一名称:

    Status:
      Conditions:
        Last Transition Time:  2026-01-30T19:11:04Z
        Message:               checkpoint completed successfully
        Reason:                Complete
        Status:                True
        Type:                  Triggered
      Observed Generation:     1
      Snapshot Created:
        Name:  <UNIQUE_SNAPSHOT_NAME>
    

使用快照进行恢复

捕获快照后,您可以恢复沙盒环境,从其保存的状态继续执行。如需恢复沙盒,请创建引用原始 SandboxTemplate 的新 SandboxClaim。Pod 快照控制器会自动识别并恢复最近的匹配快照。

  1. 创建新的 SandboxClaim 以恢复沙盒:

    kubectl apply -f - <<EOF
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxClaim
    metadata:
      name: python-sandbox-from-snapshot
      namespace: ${SNAPSHOT_NAMESPACE}
      labels:
        app: agent-sandbox-workload
    spec:
      sandboxTemplateRef:
        name: python-runtime-template
    EOF
    
  2. 查看日志,验证是否已执行恢复操作。请注意,计数器会从拍摄快照时的时间点继续计数:

    kubectl logs python-sandbox-from-snapshot --namespace "${SNAPSHOT_NAMESPACE}"
    

    输出应显示计数器恢复,例如:

    Count: 18
    Count: 19
    Count: 20
    Count: 21
    

清理资源

为避免因本文档中使用的资源导致您的 Google Cloud 账号产生费用,请执行以下步骤来删除您创建的资源:

  1. 删除沙盒声明以停止所有正在运行的 Pod,并允许代理沙盒控制器正常终止容器。

    kubectl delete sandboxclaims --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  2. 删除用于创建沙盒和启动快照的沙盒模板和手动触发器。

    # Delete the blueprints
    kubectl delete sandboxtemplates --all --namespace "${SNAPSHOT_NAMESPACE}"
    
    # Delete the snapshot initiation objects
    kubectl delete podsnapshotmanualtriggers --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  3. 删除用于定义命名空间内哪些 Pod 符合快照条件的快照政策。

    kubectl delete podsnapshotpolicy cpu-psp --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. 删除快照存储配置,即快照存储后端的全局定义。由于此资源属于集群级资源,因此请勿使用命名空间标志。

    kubectl delete podsnapshotstorageconfig cpu-pssc-gcs
    
  5. 如果您为 Autopilot 创建了 ComputeClass,请将其删除。

    kubectl delete computeclass non-e2-class
    
  6. 删除 Kubernetes 命名空间,以自动移除 Kubernetes 服务账号和所有剩余的命名空间级元数据。

    kubectl delete namespace "${SNAPSHOT_NAMESPACE}"
    
  7. 删除 GKE 集群,以移除底层基础架构和与本教程关联的所有节点。

    gcloud container clusters delete "${CLUSTER_NAME}" --location="${GKE_LOCATION}" --quiet
    
  8. 如果您想完全重置存储空间,可以使用递归移除命令删除 Cloud Storage 存储桶(可选)。请注意,如果您打算在未来的测试中重复使用已正确配置的存储桶,则可以跳过此步骤。

    gcloud storage rm --recursive "gs://${SNAPSHOTS_BUCKET_NAME:?Error: SNAPSHOTS_BUCKET_NAME is not set. Please re-define the environment variables you defined earlier.}"
    
  9. 如果您想让项目恢复到完全干净的状态,请删除自定义 IAM 角色(可选)。由于 IAM 角色即使在集群被删除后也会保留,因此您必须单独删除它们。

    gcloud iam roles delete podSnapshotGcsReadWriter --project="${PROJECT_ID}"
    

后续步骤