Salvar e restaurar ambientes de sandbox do agente com snapshots de pod

Neste documento, mostramos como usar os snapshots de pod do GKE para salvar o estado de um ambiente do Agent Sandbox em execução.

O sandbox do agente melhora sua segurança ao fornecer um ambiente isolado para executar códigos não confiáveis, como os gerados por modelos de linguagem grandes (LLMs). Executar esse tipo de código diretamente em um cluster apresenta riscos de segurança, porque o código não confiável pode acessar ou interferir em outros apps ou no próprio nó do cluster.

Os snapshots de pods do GKE permitem salvar e restaurar o estado de ambientes em sandbox. Essa funcionalidade é útil pelos seguintes motivos:

  • Inicialização rápida: reduza o tempo de inicialização do sandbox restaurando um snapshot pré-aquecido.
  • Agentes de longa duração: pause uma sandbox que leva muito tempo para ser executada e retome depois ou mova para um nó diferente sem perder o progresso.
  • Cargas de trabalho com estado: persistem o contexto de um agente, como histórico de conversas ou cálculos intermediários, salvando e restaurando o estado do ambiente isolado.
  • Reprodução: capture um estado específico e use-o como base para iniciar várias novas sandboxes com o mesmo estado inicializado.

Um snapshot pode ser acionado de duas maneiras:

  • Gatilho manual:você cria um recurso PodSnapshotManualTrigger para acionar o snapshot.
  • Gatilho da carga de trabalho:o próprio aplicativo em sandbox sinaliza quando está pronto para ser salvo.

Este documento mostra como acionar um snapshot manualmente.

Antes de começar

  1. No console do Google Cloud , na página do seletor de projetos, selecione ou crie um projeto do Google Cloud .

    Funções necessárias para selecionar ou criar um projeto

    • Selecionar um projeto: não é necessário um papel específico do IAM para selecionar um projeto. Você pode escolher qualquer projeto em que tenha recebido um papel.
    • Criar um projeto: para criar um projeto, é necessário ter o papel de Criador de projetos (roles/resourcemanager.projectCreator), que contém a permissão resourcemanager.projects.create. Saiba como conceder papéis.

    Acessar o seletor de projetos

  2. Verifique se o faturamento está ativado para o projeto do Google Cloud .

  3. Ative as APIs do Google Kubernetes Engine, Cloud Storage e Identity and Access Management (IAM), se alguma delas ainda não estiver ativada.

    Funções necessárias para ativar APIs

    Para ativar APIs, você precisa da permissão serviceusage.services.enable. Se você criou o projeto, provavelmente já tem essa permissão pelo papel de proprietário (roles/owner). Caso contrário, é possível receber essa permissão pelo papel de administrador do Service Usage (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.

    Ativar as APIs

  4. No console do Google Cloud , ative o Cloud Shell.

    Ativar o Cloud Shell

Requisitos

Os snapshots de pods do GKE exigem a versão 1.35.3-gke.1234000 ou mais recente do GKE. Os modos Autopilot e Standard são aceitos.

Como os snapshots de pod exigem o GKE Sandbox, seu ambiente está sujeito a algumas limitações. Por exemplo, os snapshots de pod não são compatíveis com tipos de máquina E2. Consequentemente, este tutorial cria um pool de nós com máquinas N2.

Para conferir uma lista completa de restrições, incluindo informações sobre o uso de tipos de máquinas baseados em GPU, consulte Limitações e requisitos.

Definir variáveis de ambiente

Para simplificar os comandos executados neste documento, defina variáveis de ambiente no Cloud Shell. Essas variáveis armazenam valores como o ID do projeto do Google Cloud , o nome do bucket do Cloud Storage que vai armazenar os snapshots e o local do cluster do GKE.

Depois de definir essas variáveis, é possível reutilizá-las em vários comandos referenciando o nome da variável (por exemplo, $CLUSTER_NAME) em vez de digitar ou substituir valores a cada vez. Essa abordagem facilita o processo e reduz o risco de erros.

Para definir as seguintes variáveis de ambiente úteis no Cloud Shell, execute os comandos abaixo:

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)")

Confira uma explicação dessas variáveis de ambiente:

  • PROJECT_ID: o ID do seu projeto atual do Google Cloud . Definir essa variável ajuda a garantir que todos os recursos, como seu cluster do GKE, sejam criados no projeto correto.
  • CLUSTER_NAME: o nome do cluster do GKE (por exemplo, agent-sandbox-cluster).
  • GKE_LOCATION: a região Google Cloud em que o cluster do GKE será criado (por exemplo, us-central1).
  • CLUSTER_VERSION: a versão do cluster do GKE, que precisa ser 1.35.3-gke.1234000 ou mais recente.
  • AGENT_SANDBOX_VERSION: a versão do controlador do sandbox do agente a ser implantada no cluster.
  • NODE_POOL_NAME: o nome do pool de nós que executará cargas de trabalho em sandbox (por exemplo, agent-sandbox-node-pool).
  • MACHINE_TYPE: o tipo de máquina dos nós no pool de nós (por exemplo, n2-standard-2). Os snapshots de pod não são compatíveis com tipos de máquina E2. Se você quiser usar tipos de máquinas baseados em GPU para os nós no pool de nós, consulte Limitações e requisitos. Para detalhes sobre diferentes séries de máquinas e como escolher entre as opções, consulte o Guia de comparação e recursos para famílias de máquinas.
  • SNAPSHOTS_BUCKET_NAME: o nome do bucket do Cloud Storage que você vai criar para armazenar snapshots.
  • SNAPSHOT_NAMESPACE: o namespace do Kubernetes em que a carga de trabalho do snapshot e a conta de serviço vão residir.
  • SNAPSHOT_KSA_NAME: o nome da conta de serviço do Kubernetes que a carga de trabalho usará para autenticação.
  • SNAPSHOT_FOLDER: o diretório dentro do bucket do Cloud Storage em que os snapshots serão organizados.
  • PROJECT_NUMBER: o identificador numérico exclusivo do projeto, usado para vinculações de permissão do IAM.

Visão geral das etapas de configuração

Para ativar snapshots de pods dos ambientes do sandbox do agente, é necessário realizar algumas etapas de configuração. Para entender essas etapas, é útil primeiro conhecer alguns conceitos importantes e depois o processo de captura de tela:

Principais conceitos

  • Ambiente:um aplicativo em sandbox é executado em um pod do Kubernetes em um nó de cluster do GKE.
  • Identidade:o pod é associado a uma conta de serviço do Kubernetes e é executado em um namespace especial que você cria. Juntos, a conta de serviço do Kubernetes e o namespace formam uma identidade exclusiva usada para conceder ao pod acesso seguro aos recursos do Google Cloud .
  • Permissões: para permitir que os snapshots sejam salvos no Cloud Storage, a identidade do pod precisa receber permissões específicas do IAM que permitam que ele grave em um bucket do Cloud Storage.

Processo de snapshot

  1. Gatilho:um snapshot é iniciado manualmente (externamente) ou pela própria carga de trabalho em sandbox. Este documento demonstra um gatilho manual que você inicia criando um recurso PodSnapshotManualTrigger.
  2. Captura:o GKE captura o estado de execução do pod, como o estado da memória e do sistema de arquivos dele.
  3. Upload:usando as permissões concedidas à conta de serviço do Kubernetes do pod, o GKE faz upload do estado capturado como arquivos de snapshot para o bucket do Cloud Storage designado.

Para saber mais sobre como o GKE usa contas de serviço do Kubernetes e papéis do IAM para acessar recursos do Google Cloud , consulte Autenticar-se nas APIs do Google Cloud em cargas de trabalho do GKE.

Para ativar snapshots de pods de ambientes de sandbox do agente, faça a seguinte configuração. Primeiro, prepare um ambiente de cluster criando um cluster do GKE com a Federação de Identidade da Carga de Trabalho para GKE e os recursos de snapshots de pod ativados. Em seguida, configure as políticas do Cloud Storage e do IAM para garantir que os snapshots sejam armazenados com segurança e que o sandbox tenha as permissões necessárias. Por fim, crie os recursos de snapshot que especificam o local de armazenamento e as políticas do sandbox.

A tabela a seguir resume as etapas de configuração que você precisa realizar. Cada etapa é explicada nas seções a seguir:

Tópico Tarefa
Configuração do cluster 1. Crie um cluster do GKE e ative os snapshots de pod e os recursos da Federação de Identidade da Carga de Trabalho para GKE.
2. Implante o sandbox de agente.
Configurar armazenamento e permissões 1. Crie o bucket do Cloud Storage e a pasta gerenciada.
2. Crie o papel personalizado do IAM.
3. Crie o namespace e a conta de serviço do Kubernetes (KSA).
4. Vincule o papel do IAM à conta de serviço do Kubernetes.
5. Conceda permissões ao controlador de instantâneo.
Configurar recursos de snapshot 1. Crie PodSnapshotStorageConfig
2. Criar PodSnapshotPolicy
3. Criar SandboxTemplate

Configuração do cluster

Um app em sandbox é executado em um pod em um nó de cluster do GKE. Portanto, você precisa configurar um ambiente de cluster. Nesta seção, mostramos como criar um cluster do GKE e implantar o controlador do Agent Sandbox.

Criar um cluster do GKE que atenda aos requisitos

Crie um cluster do GKE com snapshots de pods ativados. Para compatibilidade total de recursos, especifique um cluster na versão 1.35.3-gke.1234000 ou mais recente:

Piloto automático

Crie um cluster do Autopilot com os recursos necessários:

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

Padrão

Crie um cluster Standard com os recursos necessários:

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}

Crie um pool de nós com o GKE Sandbox ativado. O GKE Sandbox é um recurso de segurança de contêineres baseado no projeto de código aberto gVisor que fornece uma camada extra de isolamento entre aplicativos em execução e o sistema operacional do host:

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

Recuperar credenciais

Recupere as credenciais do cluster para que a CLI kubectl possa se conectar a ele:

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

Implante o controlador do sandbox do agente no cluster

Para implantar o controlador do Sandbox do agente e os componentes necessários, aplique os manifestos de lançamento oficiais ao cluster. Esses manifestos são arquivos de configuração que instruem o Kubernetes a fazer o download de todos os componentes necessários para implantar e executar o controlador do Agent Sandbox no cluster.

Para implantar o Agent Sandbox no cluster do GKE, execute o seguinte comando:

# 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

Verificar o controlador

Depois de aplicar os manifestos, verifique se o pod do controlador da caixa de sandbox do agente está sendo executado corretamente no namespace agent-sandbox-system. Os manifestos criaram automaticamente o namespace agent-sandbox-system quando você os aplicou na etapa anterior.

kubectl get pods -n agent-sandbox-system

Aguarde até que o pod mostre "Running" na coluna STATUS e "1/1" na coluna READY. Quando o pod está em execução corretamente, a saída é semelhante a esta:

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

Agora que o controlador do Agent Sandbox está em execução, ele pode criar e gerenciar automaticamente ambientes de sandbox para todos os recursos Sandbox criados no cluster.

Configurar armazenamento e permissões

Nesta seção, mostramos como configurar o armazenamento e as permissões necessárias para snapshots de pods. Você cria um bucket do Cloud Storage e uma pasta gerenciada para armazenar os dados do snapshot. Em seguida, conceda ao sandbox e ao controlador de instantâneos as permissões necessárias para acessar esse armazenamento.

Criar o bucket do Cloud Storage

Crie um bucket para armazenar seus snapshots. Para garantir que o processo de snapshot seja rápido e econômico, recomendamos que você crie o bucket com as seguintes configurações:

  • Ativar namespaces hierárquicos:o recurso de namespaces hierárquicos organiza seu bucket em uma hierarquia de sistema de arquivos em vez de um namespace simples. Essa configuração permite maior capacidade de processamento de leitura e gravação e, consequentemente, acelera o salvamento e a restauração de snapshots.
  • Desativar a exclusão reversível:esse recurso protege os dados retendo os arquivos excluídos por um período definido. No entanto, o processo de snapshot cria e exclui muitos arquivos temporários durante o upload. Recomendamos que você desative a exclusão reversível para evitar cobranças desnecessárias pelo armazenamento desses arquivos temporários.

Para criar o bucket com essas configurações, execute o seguinte comando:

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

Criar uma pasta gerenciada

Crie uma pasta gerenciada para organizar snapshots no bucket. Com as pastas gerenciadas, é possível aplicar permissões do IAM a uma pasta específica em vez de a todo o bucket. Esse acesso no nível da pasta limita o acesso do sandbox apenas aos próprios snapshots e os isola de outros dados no bucket.

Para criar uma pasta gerenciada, execute este comando:

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

Configurar a conta de serviço e os papéis do IAM

Para permitir que o GKE salve snapshots com segurança, a conta de serviço do Kubernetes usada pelos pods que executam sua carga de trabalho em sandbox precisa de permissão para gravar no bucket. Para conceder essa permissão, vincule os papéis do IAM do Google Cloud à conta de serviço do Kubernetes usada pelos pods. Nesta seção, mostramos como criar um papel personalizado do IAM, criar a conta de serviço do Kubernetes e configurar as permissões necessárias.

  1. Crie um papel personalizado do IAM chamado podSnapshotGcsReadWriter que contenha as permissões necessárias para gravar dados de snapshot:

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

    Quando a função é criada, a saída é semelhante a esta:

    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. Crie o namespace em que o sandbox e a conta de serviço vão residir:

    kubectl create namespace "${SNAPSHOT_NAMESPACE}"
    
  3. Crie a conta de serviço do Kubernetes no namespace que você acabou de criar. Juntos, a conta de serviço do Kubernetes e o namespace formam uma identidade exclusiva usada para conceder à sua sandbox acesso seguro aos recursos do Google Cloud :

    kubectl create serviceaccount "${SNAPSHOT_KSA_NAME}" \
        --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. Conceda o papel roles/storage.bucketViewer a todas as contas de serviço no namespace. Esse papel permite que as contas visualizem os metadados do bucket, mas não leiam ou gravem os dados em si:

    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. Conceda seu papel podSnapshotGcsReadWriter personalizado à conta de serviço do Kubernetes para seu sandbox. Essa vinculação permite que apenas essa conta específica grave dados na pasta gerenciada:

    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. Conceda o papel roles/storage.objectUser à conta de serviço do Kubernetes. Esse papel é necessário para que o agente de snapshot de pod realize operações em pastas gerenciadas:

    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"
    

Conceder permissões ao controlador de snapshot

Conceda o papel objectUser ao controlador de snapshots do sistema do GKE. Essa permissão permite que o controlador gerencie o ciclo de vida do snapshot, como excluir objetos de snapshot quando você exclui um recurso PodSnapshot:

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

Configurar recursos de snapshot

Nesta seção, mostramos como configurar os recursos de snapshot para sua carga de trabalho do Agent Sandbox.

Definir armazenamento e regras de snapshots

Para especificar onde o GKE salva seus snapshots e quais regras regem o processo de snapshot, crie dois recursos personalizados:

  • PodSnapshotStorageConfig: esse recurso especifica o bucket do Cloud Storage e o local da pasta em que o GKE salva os arquivos de snapshot.
  • PodSnapshotPolicy: esse recurso define quais pods estão qualificados para snapshots com base nos rótulos do Kubernetes. Ele também especifica as regras de acionamento, como se os snapshots são manuais ou iniciados pela carga de trabalho do sandbox.

Para aplicar os dois recursos em uma única etapa, execute o seguinte comando no Cloud Shell. Esse método ajuda a garantir que as variáveis de ambiente sejam injetadas corretamente:

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

Verificar a configuração

Depois de aplicar a configuração e a política de armazenamento de snapshots, verifique se os recursos estão prontos para uso. Nesta seção, mostramos como verificar o status desses recursos personalizados.

  1. Verifique o status do recurso PodSnapshotStorageConfig:

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

    A saída precisa conter uma condição com type: Ready e status: "True":

    status:
      conditions:
      - lastTransitionTime: "2025-10-31T18:18:02Z"
        message: Valid PodSnapshotStorageConfig
        reason: StorageConfigValid
        status: "True"
        type: Ready
    
  2. Verifique o status do recurso PodSnapshotPolicy:

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

    A saída precisa conter uma condição com type: Ready e status: "True". Ele também precisa indicar que o PodSnapshotStorageConfig referenciado foi encontrado:

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

Criar o modelo de sandbox

Agora que as políticas e permissões de armazenamento estão em vigor, crie os recursos SandboxTemplate e SandboxClaim. Para que o processo de snapshot funcione, a sandbox precisa ser executada com a conta de serviço do Kubernetes criada anteriormente neste documento. A sandbox também precisa ter os rótulos que você especificou antes no PodSnapshotPolicy.

Este exemplo usa um app Python que imprime um contador crescente nos registros. Com esse contador, é possível verificar se o estado foi salvo e restaurado depois.

Piloto automático

Os snapshots de pod não são compatíveis com tipos de máquina E2. No Autopilot, o GKE pode usar por padrão tipos de máquinas que não oferecem suporte a snapshots de pods. Para garantir que suas cargas de trabalho sejam executadas em hardware compatível, use uma ComputeClass personalizada para priorizar famílias de máquinas compatíveis.

  1. Salve o seguinte manifesto como 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. Aplique o manifesto:

    kubectl apply -f non-e2-class.yaml
    
  3. Para criar os recursos SandboxTemplate e SandboxClaim, aplique o manifesto a seguir. O SandboxTemplate se refere ao ComputeClass que você acabou de criar usando o seletor de nó cloud.google.com/compute-class: non-e2-class.

    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
    

Padrão

Para criar os recursos SandboxTemplate e SandboxClaim, aplique o seguinte manifesto:

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

Seu sandbox agora está em execução com a identidade correta e pronto para ser capturado.

Criar um snapshot

Nesta seção, mostramos como acionar manualmente um snapshot da sua sandbox em execução. Você cria um recurso de gatilho que segmenta o pod de sandbox e, em seguida, verifica se o processo de snapshot foi concluído.

  1. Verifique os registros do contador inicial:antes de acionar o snapshot, confira os registros do sandbox em execução para ver o valor atual do contador. A visualização dos registros estabelece um valor de referência para comparar após a restauração.

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

    A saída mostra as últimas linhas do contador, por exemplo:

    Count: 15
    Count: 16
    Count: 17
    

    Observe os últimos valores de "Count" mostrados.

  2. Crie um recurso PodSnapshotManualTrigger:inicie o snapshot:

    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. Verifique se o gatilho manual foi bem-sucedido:

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

    A saída vai mostrar o status Complete, indicando que o GKE acionou o snapshot do pod de destino:

    NAME                   TARGET POD               STATUS     AGE
    cpu-snapshot-trigger   python-sandbox-example   Complete   XXs
    
  4. Confira mais detalhes sobre o estado capturado descrevendo o acionador:

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

    A saída contém uma seção Snapshot Created com o nome exclusivo dos arquivos de snapshot armazenados no seu bucket:

    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>
    

Restaurar a partir de um snapshot

Depois de capturar um snapshot, é possível restaurar o ambiente de sandbox para retomar a execução do estado salvo. Para restaurar o sandbox, crie um novo SandboxClaim que faça referência ao SandboxTemplate original. O controlador de snapshot de pod identifica e restaura automaticamente o snapshot correspondente mais recente.

  1. Crie um novo SandboxClaim para restaurar o sandbox:

    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. Verifique se a restauração foi realizada analisando os registros. O contador continua do ponto em que o snapshot foi tirado:

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

    A saída vai mostrar a retomada do contador, por exemplo:

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

Limpar recursos

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste documento, siga estas etapas para excluir os recursos criados:

  1. Exclua as reivindicações de sandbox para interromper todos os pods em execução e permitir que o controlador do sandbox do agente encerre os contêineres sem problemas.

    kubectl delete sandboxclaims --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  2. Exclua os modelos de sandbox e os gatilhos manuais usados para criar sandboxes e iniciar snapshots.

    # Delete the blueprints
    kubectl delete sandboxtemplates --all --namespace "${SNAPSHOT_NAMESPACE}"
    
    # Delete the snapshot initiation objects
    kubectl delete podsnapshotmanualtriggers --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  3. Exclua as políticas de snapshot que definem quais pods estão qualificados para snapshots no namespace.

    kubectl delete podsnapshotpolicy cpu-psp --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. Exclua a configuração de armazenamento de snapshot, que é a definição global do back-end de armazenamento de snapshot. Como esse recurso tem escopo de cluster, não use uma flag de namespace.

    kubectl delete podsnapshotstorageconfig cpu-pssc-gcs
    
  5. Se você criou uma para o Autopilot, exclua a ComputeClass.

    kubectl delete computeclass non-e2-class
    
  6. Exclua o namespace do Kubernetes para remover automaticamente a conta de serviço do Kubernetes e os metadados restantes do namespace.

    kubectl delete namespace "${SNAPSHOT_NAMESPACE}"
    
  7. Exclua o cluster do GKE para remover a infraestrutura subjacente e todos os nós associados ao tutorial.

    gcloud container clusters delete "${CLUSTER_NAME}" --location="${GKE_LOCATION}" --quiet
    
  8. Exclua o bucket do Cloud Storage (opcional) usando o comando de remoção recursiva se quiser redefinir totalmente o armazenamento. É possível pular essa etapa se você pretende reutilizar o bucket configurado corretamente para testes futuros.

    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. Exclua o papel personalizado do IAM (opcional) se quiser retornar o projeto a um estado completamente limpo. Como as funções do IAM permanecem mesmo depois que o cluster é excluído, elas precisam ser excluídas separadamente.

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

A seguir