Salvar e restaurar o Sandbox do Agente em ambientes do GKE com snapshots de pod

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

O Agent Sandbox no GKE melhora a segurança ao fornecer um ambiente isolado para executar códigos não confiáveis, como os gerados por modelos de linguagem grandes (LLMs). A execução desse tipo de código diretamente em um cluster representa 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 um sandbox que leva muito tempo para ser executado e retome-o mais tarde ou mova-o para um nó diferente sem perder o progresso.
  • Cargas de trabalho com estado: persistem o contexto de um agente, como o histórico de conversas ou cálculos intermediários, salvando e restaurando o estado do ambiente de sandbox.
  • Reprodutibilidade: capture um estado específico e use-o como base para iniciar vários novos 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 de carga de trabalho: o próprio aplicativo em sandbox sinaliza quando está pronto para ser salvo.

Neste documento, mostramos 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 .

    Papéis necessários para selecionar ou criar um projeto

    • Selecionar um projeto: para selecionar um projeto, não é necessário ter um papel do IAM específico. É possível selecionar qualquer projeto em que você tenha um papel.
    • Criar um projeto: para criar um projeto, é preciso 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, do Cloud Storage e do Identity and Access Management (IAM), se ainda não estiverem ativadas.

    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 conseguir 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 compatíveis.

Os snapshots de pods exigem o gVisor e não funcionam com sandboxes de microVM.

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 os tipos de máquina E2. Portanto, este tutorial cria um pool de nós composto por máquinas N2.

Para uma lista completa de restrições, incluindo informações sobre o uso de tipos de máquina 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 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 novamente ou substituir valores todas as vezes. 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 seguintes comandos:

export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export GKE_LOCATION="us-central1"
export ZONE="us-central1-a"
export AGENT_SANDBOX_VERSION="v1.0.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 projeto atual do Google Cloud . Os comandos neste documento usam esse ID para nomear recursos e conceder permissões do IAM.
  • CLUSTER_NAME: o nome do cluster do GKE (por exemplo, agent-sandbox-cluster).
  • GKE_LOCATION: a região do Google Cloud para o bucket do Cloud Storage (por exemplo, us-central1). Se você criar um cluster do Autopilot, ele também vai usar essa região.
  • ZONE: a zona do cluster do GKE. Se você criar um cluster Standard, defina-o como uma zona na região GKE_LOCATION (por exemplo, us-central1-a). Para reduzir custos, este documento cria um cluster Standard zonal.
  • AGENT_SANDBOX_VERSION: a versão do controlador de código aberto do Agent Sandbox a ser instalada. Este documento usa a versão 1.0.6.
  • 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 os tipos de máquina E2. Se você quiser usar tipos de máquina baseados em GPU para os nós no pool de nós, consulte Limitações e requisitos. Para detalhes sobre as 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 os snapshots de pod do Agent Sandbox em ambientes do GKE, é necessário realizar algumas etapas de configuração. Para entender essas etapas, é útil primeiro entender alguns conceitos importantes e, em seguida, o processo de snapshot:

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 que é 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 do pod.
  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 designado do Cloud Storage.

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 doGoogle Cloud usando cargas de trabalho do GKE.

Para ativar os snapshots de pods do Agent Sandbox em ambientes do GKE, realize a configuração a seguir. 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 o Cloud Storage e as políticas do IAM para garantir que os snapshots sejam armazenados com segurança e que o sandbox tenha as permissões necessárias. Por fim, você cria 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, e cada etapa é explicada nas seções a seguir:

Tópico Tarefa
Configuração do cluster 1. Crie um cluster do GKE e ative os recursos de snapshots de pods e de Federação de Identidade da Carga de Trabalho para GKE.
2. Implantar o Agent Sandbox.
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 do Kubernetes 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 snapshot.
Configurar recursos de snapshot 1. Criar um recurso PodSnapshotStorageConfig
2. Criar um recurso PodSnapshotPolicy
3. Criar os recursos SandboxTemplate, SandboxWarmPool e SandboxClaim

Configuração do cluster

Um app em sandbox é executado em um pod em um nó de cluster do GKE. Portanto, é necessário 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 novo cluster do GKE com os snapshots de pod ativados. Os snapshots de pod exigem o GKE versão 1.35.3-gke.1234000 ou posterior. Os comandos a seguir registram o cluster no canal de lançamento rápido, cuja versão padrão atende a esse requisito:

Piloto automático

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

gcloud container clusters create-auto ${CLUSTER_NAME} \
   --release-channel=rapid \
   --enable-pod-snapshots \
   --location=${GKE_LOCATION}

Padrão

Crie um cluster padrão com os recursos necessários. Para reduzir custos, o comando a seguir cria um cluster zonal, que executa o plano de controle e os nós em uma zona:

gcloud container clusters create ${CLUSTER_NAME} \
   --release-channel=rapid \
   --enable-pod-snapshots \
   --machine-type=${MACHINE_TYPE} \
   --workload-pool=${PROJECT_ID}.svc.id.goog \
   --workload-metadata=GKE_METADATA \
   --num-nodes=1 \
   --location=${ZONE}

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 os aplicativos em execução e o sistema operacional host:

gcloud container node-pools create ${NODE_POOL_NAME} \
   --cluster ${CLUSTER_NAME} \
   --num-nodes=1 \
   --location=${ZONE} \
   --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 ao cluster:

Piloto automático

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

Padrão

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

Implantar o controlador do Agent Sandbox no cluster

Para implantar o controlador do Agent Sandbox e os componentes necessários, aplique o manifesto de lançamento oficial ao cluster. Esse manifesto é um arquivo de configuração que instrui o Kubernetes a baixar 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 release manifest for the controller and its CustomResourceDefinitions
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/sandbox-with-extensions.yaml

Para mais informações sobre como instalar o Agent Sandbox, consulte Instalar o Agent Sandbox no GKE.

Verificar o controlador

Depois de aplicar o manifesto, verifique se o pod do controlador do Agent Sandbox está em execução corretamente no namespace agent-sandbox-system. O manifesto criou automaticamente o namespace agent-sandbox-system quando você o 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 estiver em execução corretamente, a saída será semelhante a esta:

NAME                                        READY   STATUS    RESTARTS   AGE
agent-sandbox-controller-7d5c9b8f6d-x2k9p   1/1     Running   0          2m

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 que você criar no cluster.

Configurar armazenamento e permissões

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

Criar o bucket do Cloud Storage

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

  • Ativar namespaces hierárquicos: o recurso de namespaces hierárquicos organiza o bucket em uma hierarquia de sistema de arquivos, em vez de um namespace simples. Essa configuração permite maior capacidade de leitura e gravação e, consequentemente, acelera o salvamento e a restauração de snapshots.
  • Desativar a exclusão reversível: o recurso de exclusão reversível 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. 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 os snapshots no bucket. As pastas gerenciadas permitem aplicar permissões do IAM a uma pasta específica, em vez de ao bucket inteiro. 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 a carga de trabalho em sandbox precisa de permissão para gravar no bucket. Para conceder essa permissão, vincule Google Cloud papéis do IAM à 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. Se esse papel já existir no projeto, por exemplo, de uma execução anterior deste documento, pule esta etapa. Caso contrário, execute o seguinte comando:

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

    Quando o papel é criado, a saída é assim:

    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
    

    Se o comando falhar com um erro FAILED_PRECONDITION que diz que o ID do papel foi marcado para exclusão, você excluiu um papel com esse ID recentemente, por exemplo, nas etapas de limpeza de uma execução anterior deste documento. O IAM não permite que você reutilize esse ID por até 37 dias. Execute o comando novamente com um ID de papel diferente, como podSnapshotGcsReadWriter2, e use esse ID em vez de podSnapshotGcsReadWriter no restante deste documento.

  2. Crie o namespace em que o sandbox e a conta de serviço dele 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 ao 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 o papel personalizado podSnapshotGcsReadWriter à conta de serviço do Kubernetes para o sandbox. Essa vinculação permite que apenas essa conta específica grave dados na pasta gerenciada. Um novo papel personalizado pode levar alguns minutos para ficar disponível. Portanto, se esse comando falhar porque o papel não existe, aguarde um minuto e execute o comando novamente:

    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 snapshot 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 no GKE.

Definir armazenamento e regras de snapshot

Para especificar onde o GKE salva os 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. Este exemplo agrupa snapshots pelo rótulo agents.x-k8s.io/sandbox-name-hash, que o controlador do Agent Sandbox adiciona ao pod de cada sandbox. Esse agrupamento significa que o GKE restaura cada sandbox apenas com base nos próprios snapshots.

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
  snapshotGroupingRules:
    groupByLabelValue:
      labels:
      - agents.x-k8s.io/sandbox-name-hash
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 -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 deve indicar que o recurso 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, SandboxWarmPool e SandboxClaim. O recurso SandboxWarmPool mantém um sandbox pré-aquecido em execução, e o recurso SandboxClaim reivindica esse sandbox do pool. Para que o processo de snapshot funcione, o sandbox precisa ser executado com a conta de serviço do Kubernetes que você criou anteriormente neste documento. O sandbox também precisa ter os rótulos que você especificou anteriormente no recurso PodSnapshotPolicy.

Este exemplo usa um app em Python que imprime um contador incremental nos registros. Esse contador permite verificar se o estado foi salvo e restaurado corretamente mais tarde.

Piloto automático

Os snapshots de pod não são compatíveis com os tipos de máquina E2. No Autopilot, o GKE pode usar como padrão tipos de máquina que não são compatíveis com snapshots de pod. Para garantir que as 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 SandboxWarmPool, aplique o manifesto a seguir. Observe que o recurso SandboxTemplate refere-se ao ComputeClass que você acabou de criar usando o seletor de nós cloud.google.com/compute-class: non-e2-class.

    kubectl apply -f - <<EOF
    ---
    apiVersion: extensions.agents.x-k8s.io/v1beta1
    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/v1beta1
    kind: SandboxWarmPool
    metadata:
      name: python-sandbox-warmpool
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      replicas: 1
      sandboxTemplateRef:
        name: python-runtime-template
    EOF
    

Padrão

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

kubectl apply -f - <<EOF
---
apiVersion: extensions.agents.x-k8s.io/v1beta1
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/v1beta1
kind: SandboxWarmPool
metadata:
  name: python-sandbox-warmpool
  namespace: ${SNAPSHOT_NAMESPACE}
spec:
  replicas: 1
  sandboxTemplateRef:
    name: python-runtime-template
EOF

Depois de criar os recursos, reivindique um sandbox do pool de espera:

  1. Aguarde até que o sandbox do pool de aquecimento esteja pronto:

    kubectl wait sandboxwarmpool python-sandbox-warmpool \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=jsonpath='{.status.readyReplicas}'=1 \
      --timeout=600s
    
  2. Crie um recurso SandboxClaim que reivindique o sandbox do pool de aquecimento:

    kubectl apply -f - <<EOF
    apiVersion: extensions.agents.x-k8s.io/v1beta1
    kind: SandboxClaim
    metadata:
      name: python-sandbox-example
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      warmPoolRef:
        name: python-sandbox-warmpool
    EOF
    
  3. Aguarde até que a declaração esteja pronta e salve o nome do sandbox que ela usa. O pod do sandbox tem o mesmo nome do sandbox:

    kubectl wait sandboxclaim python-sandbox-example \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=condition=Ready \
      --timeout=300s
    
    export SANDBOX_NAME=$(kubectl get sandboxclaim python-sandbox-example \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      -o jsonpath='{.status.sandbox.name}')
    echo "${SANDBOX_NAME}"
    

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 do 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 iniciais do contador: 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 uma referência para comparação após a restauração.

    kubectl logs "${SANDBOX_NAME}" --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: ${SANDBOX_NAME}
    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-warmpool-x7k2p   Complete   XXs
    
  4. Veja mais detalhes sobre o estado capturado descrevendo o gatilho:

    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 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 suspender o sandbox para liberar os recursos de computação e, mais tarde, retomá-lo do estado salvo. Quando você suspende um sandbox, o controlador do Agent Sandbox exclui o pod do sandbox, mas mantém o recurso Sandbox. Quando você retoma o sandbox, o controlador recria o pod, e o controlador de snapshot do pod restaura automaticamente o pod com base no snapshot mais recente desse sandbox.

  1. Aguarde até que o snapshot esteja pronto. O GKE restaura um pod apenas de um snapshot que esteja pronto. Se você suspender o sandbox antes que o snapshot esteja pronto, ele será iniciado sem o estado salvo quando você o retomar.

    export SNAPSHOT_NAME=$(kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io cpu-snapshot-trigger \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      -o jsonpath='{.status.snapshotCreated.name}')
    
    kubectl wait podsnapshots.podsnapshot.gke.io "${SNAPSHOT_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=condition=Ready \
      --timeout=600s
    
  2. Para suspender o sandbox, defina o campo operatingMode como Suspended e aguarde até que o controlador exclua o pod do sandbox:

    kubectl patch sandbox "${SANDBOX_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --type=merge \
      -p '{"spec":{"operatingMode":"Suspended"}}'
    
    kubectl wait pod "${SANDBOX_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=delete \
      --timeout=120s
    
  3. Para retomar o sandbox, defina o campo operatingMode como Running e aguarde até que ele esteja pronto:

    kubectl patch sandbox "${SANDBOX_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --type=merge \
      -p '{"spec":{"operatingMode":"Running"}}'
    
    kubectl wait sandbox "${SANDBOX_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=condition=Ready \
      --timeout=300s
    
  4. Verifique se a restauração ocorreu visualizando os registros. Observe que o contador continua do ponto em que o snapshot foi tirado:

    kubectl logs "${SANDBOX_NAME}" --namespace "${SNAPSHOT_NAMESPACE}"
    

    A saída vai mostrar o contador sendo retomado, por exemplo:

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

    Se o contador começar em 0, o pod foi iniciado sem restauração do snapshot.

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 declarações de sandbox e os pools de aquecimento para interromper os pods em execução e permitir que o controlador do Agent Sandbox encerre os contêineres de maneira normal.

    kubectl delete sandboxclaims --all --namespace "${SNAPSHOT_NAMESPACE}"
    kubectl delete sandboxwarmpools --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 snapshots, que é a definição global do back-end de armazenamento de snapshots. 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 todos os metadados restantes com 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.

    Piloto automático

    gcloud container clusters delete "${CLUSTER_NAME}" \
        --location="${GKE_LOCATION}" --quiet
    

    Padrão

    gcloud container clusters delete "${CLUSTER_NAME}" \
        --location="${ZONE}" --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 os papéis do IAM persistem mesmo após a exclusão do cluster, é necessário excluí-los separadamente.

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

A seguir