Use o Agent Sandbox em snapshots do Google Kubernetes Engine (GKE) em um cluster para preservar o estado dos ambientes de sandbox. Essa abordagem oferece depuração consistente, acelera a iteração de desenvolvimento e facilita a recuperação rápida de configurações complexas. Neste tutorial, você vai implantar e testar esse recurso executando um aplicativo cliente que cria, pausa e retoma ambientes de sandbox de maneira programática dentro do cluster.
Para mais informações sobre como criar snapshots de pods, consulte Restaurar de um snapshot de pod.
Custos
O Agent Sandbox no GKE é um software de código aberto que você pode usar sem custo financeiro adicional. Os preços do GKE se aplicam aos recursos que você cria, incluindo os recursos de computação que o controlador do Agent Sandbox usa.
Antes de começar
-
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ãoresourcemanager.projects.create. Saiba como conceder papéis.
-
Verifique se o faturamento está ativado para o projeto do Google Cloud .
Ative as APIs Artifact Registry, Kubernetes Engine e API Cloud Build, 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.-
No console do Google Cloud , ative o Cloud Shell.
- Verifique se você tem as permissões necessárias para concluir este tutorial.
Funções exigidas
Para receber as permissões necessárias para criar e gerenciar sandboxes, peça ao administrador para conceder a você o papel do IAM de Administrador do Kubernetes Engine (roles/container.admin) no projeto.
Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.
Também é possível conseguir as permissões necessárias usando papéis personalizados ou outros papéis predefinidos.
Limitações
Os snapshots de pods exigem o gVisor e não funcionam com sandboxes de microVM.
Em um cluster regional, os nós em zonas diferentes podem ter microarquiteturas de CPU
diferentes. Como os snapshots capturam o estado da CPU, a restauração de um
snapshot em um nó com recursos de CPU ausentes falha (por exemplo, com o erro
OCI runtime restore failed: incompatible FeatureSet).
Para evitar esse problema, use a configuração adequada para seu ambiente:
- Produção: para preservar a alta disponibilidade no cluster, não fixe cargas de trabalho em uma zona específica. Em vez disso, ajude a garantir a consistência dos recursos de CPU em todas as zonas especificando uma plataforma de CPU mínima. Para mais informações, consulte Escolher uma plataforma de CPU mínima.
- Teste: para simplificar a configuração e evitar erros iniciais de incompatibilidade de CPU, use
um campo
nodeSelectorno manifestoSandboxTemplatepara fixar o pod em uma zona específica, comous-central1-a. O exemplo neste tutorial usa essa configuração de teste.
Definir variáveis de ambiente
Para simplificar os comandos executados neste tutorial, defina variáveis de ambiente no Cloud Shell. No Cloud Shell, defina as seguintes variáveis de ambiente úteis executando estes comandos:
export PROJECT_ID=$(gcloud config get project)
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
export CLUSTER_NAME="test-snapshot"
export LOCATION="us-central1"
export ZONE="us-central1-a"
export BUCKET_LOCATION="us"
export MACHINE_TYPE="n2-standard-2"
export REPOSITORY_NAME="agent-sandbox"
export BUCKET_NAME="${PROJECT_ID}_snapshots"
export CLOUDBUILD_BUCKET_NAME="${PROJECT_ID}_cloudbuild"
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.PROJECT_NUMBER: o número do projeto atual do Google Cloud .CLUSTER_NAME: o nome do cluster do GKE, por exemplo,test-snapshot.LOCATION: a região do Google Cloud para o repositório do Artifact Registry (por exemplo,us-central1). Se você criar um cluster do Autopilot, ele também vai usar essa região.ZONE: a zona do cluster. Se você criar um cluster Standard, defina-o como uma zona na regiãoLOCATION(por exemplo,us-central1-a). O modelo de sandbox que você criar mais adiante neste tutorial executará sandboxes emus-central1-a. Se você usar uma zona diferente, mude a zona no modelo também.BUCKET_LOCATION: o local dos buckets do Cloud Storage, por exemplo,us.BUCKET_NAME: o nome do bucket do Cloud Storage usado para snapshots, por exemplo,PROJECT_ID_snapshots. Os nomes dos buckets precisam ser globalmente exclusivos.CLOUDBUILD_BUCKET_NAME: o nome do bucket do Cloud Storage usado para registros do Cloud Build. Esse valor é o nome padrão do bucket do Cloud Build. Portanto, não o altere.MACHINE_TYPE: o tipo de máquina a ser usado para os nós do cluster e o pool de nós do gVisor, por exemplo,n2-standard-2. Os snapshots de pod não são compatíveis com tipos de máquina E2.REPOSITORY_NAME: o nome do repositório do Artifact Registry, por exemplo,agent-sandbox.
Visão geral das etapas de configuração
Para ativar e testar snapshots de pods do Agent Sandbox em ambientes do GKE no cluster, é necessário realizar várias etapas de configuração. Para entender essas etapas, é útil primeiro entender os componentes envolvidos no fluxo de trabalho geral.
Principais componentes
Neste tutorial, usamos os dois aplicativos Python a seguir para testar o processo de snapshot:
- Aplicativo cliente: um script em Python em execução em um pod padrão no
cluster. Esse aplicativo gerencia o ciclo de vida do sandbox: ele
cria o sandbox de forma programática, o pausa para acionar um snapshot,
retoma o sandbox e verifica se o estado foi preservado. Neste tutorial, você vai criar uma conta de serviço do Kubernetes chamada
agent-sandbox-client-sae conceder a ela permissões de RBAC para que o pod do aplicativo cliente possa gerenciar recursos personalizados de sandbox e objetos de gatilho de snapshot usando a API Kubernetes. - Aplicativo em sandbox: um script em Python que incrementa e imprime um
contador a cada segundo. Esse aplicativo é executado com segurança dentro do ambiente de sandbox isolado para gerar um estado de mudança que o aplicativo cliente pode verificar. Neste tutorial, você vai criar uma conta de serviço dedicada do Kubernetes
chamada
snapshot-sae configurar a Identidade da carga de trabalho para autorizar o pod no sandbox a ler e gravar objetos de snapshot com segurança no Cloud Storage.
Processo de configuração e teste
A lista a seguir resume as etapas necessárias para configurar o ambiente e executar o teste:
- Criar um cluster: crie um cluster do Autopilot ou Standard com os snapshots de pod ativados.
- Crie um repositório do Artifact Registry: crie um repositório do Docker para armazenar a imagem do contêiner do aplicativo cliente.
- Instalar o Agent Sandbox: instale os principais componentes e extensões do Agent Sandbox no cluster.
- Configurar armazenamento e permissões: crie um bucket do Cloud Storage e configure as permissões da Identidade da carga de trabalho para permitir que os snapshots sejam salvos com segurança.
- Configurar snapshots de pod: crie e aplique a configuração de armazenamento de snapshots, a política de snapshots, o modelo de sandbox e o pool de aquecimento.
- Criar o aplicativo cliente: crie a imagem do contêiner para o aplicativo cliente e envie-a para o repositório do Artifact Registry.
- Executar o teste: implante o pod do aplicativo cliente, que cria o sandbox, o pausa para capturar um snapshot, o retoma e verifica se o estado do contador foi restaurado.
Criar um cluster
Crie um novo cluster do GKE com os snapshots de pod ativados. Para compatibilidade total de recursos, especifique o canal de lançamento rápido.
Piloto automático
Crie um cluster do Autopilot com os recursos necessários:
gcloud container clusters create-auto ${CLUSTER_NAME} \
--enable-pod-snapshots \
--release-channel=rapid \
--location=${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} \
--enable-pod-snapshots \
--release-channel=rapid \
--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 gVisor ativado:
gcloud container node-pools create gvisor-pool \
--cluster ${CLUSTER_NAME} \
--machine-type=${MACHINE_TYPE} \
--num-nodes=1 \
--location=${ZONE} \
--project=${PROJECT_ID} \
--sandbox type=gvisor
Crie um repositório do Artifact Registry
Crie um repositório do Docker no Artifact Registry para armazenar a imagem de contêiner do aplicativo cliente (o aplicativo que cria e gerencia o sandbox):
gcloud artifacts repositories create ${REPOSITORY_NAME} \
--repository-format=docker \
--location=${LOCATION} \
--description="Docker repository for Agent Sandbox"
Instalar o Agent Sandbox
Instale os componentes principais e as extensões do Agent Sandbox no cluster. Neste tutorial, usamos a versão 1.0.6:
# Install the core agent-sandbox components and the extensions (e.g., Warm Pools, Claims)
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/v1.0.6/sandbox-with-extensions.yaml
Para mais informações sobre como instalar o Agent Sandbox, consulte Instalar o Agent Sandbox no GKE.
Configurar armazenamento e permissões
Configure um bucket do Cloud Storage para armazenar snapshots de pods e conceda
as permissões necessárias da Identidade da carga de trabalho à conta de serviço snapshot-sa
e ao agente de serviço do GKE. Isso permite que as cargas de trabalho em sandbox
salvem e recuperem objetos de snapshot com segurança:
Crie um novo bucket do Cloud Storage
gcloud storage buckets create "gs://${BUCKET_NAME}" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="${BUCKET_LOCATION}"Crie uma conta de serviço do Kubernetes no namespace
default. O aplicativo em sandbox (o script de contador do Python) usa essa identidade para autenticar em APIs externas e acessar com segurança objetos de snapshot armazenados no Cloud Storage:kubectl create serviceaccount "snapshot-sa" \ --namespace "default"Vincule o papel
storage.bucketViewerà conta de serviço usando a Identidade da carga de trabalho. Esse papel permite que a carga de trabalho em sandbox liste o conteúdo do bucket e localize snapshots específicos:gcloud storage buckets add-iam-policy-binding "gs://${BUCKET_NAME}" \ --member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/default/sa/snapshot-sa" \ --role="roles/storage.bucketViewer"Vincule o papel
storage.objectUserà conta de serviço usando a Identidade da carga de trabalho. Esse papel fornece a permissão para ler, salvar e excluir objetos binários de snapshot no bucket:gcloud storage buckets add-iam-policy-binding "gs://${BUCKET_NAME}" \ --member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/default/sa/snapshot-sa" \ --role="roles/storage.objectUser"Conceda ao agente de serviço do GKE permissões para gerenciar (criar, listar, ler e excluir) objetos de snapshot no bucket:
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:service-${PROJECT_NUMBER}@container-engine-robot.iam.gserviceaccount.com" \ --role="roles/storage.objectUser" \ --condition="expression=resource.name.startsWith(\"projects/_/buckets/${BUCKET_NAME}\"),title=restrict_to_bucket,description=Restricts access to one bucket only"
Configurar snapshots de pods
Crie e aplique os arquivos de configuração para instalar os recursos personalizados do Kubernetes necessários. Esses recursos definem como o cluster armazena e gerencia snapshots de pod:
PodSnapshotStorageConfig: especifica o bucket do Cloud Storage designado para armazenar objetos binários de snapshot.PodSnapshotPolicy: define como os snapshots são acionados manualmente, com que frequência são agrupados e as políticas de retenção deles.SandboxTemplate: define o contêiner, os seletores de nós e as contas de serviço subjacentes para executar a carga de trabalho isolada em sandbox.SandboxWarmPool: mantém um sandbox pré-aquecido, criado com base no recursoSandboxTemplate, pronto para ser reivindicado pelo aplicativo cliente.
Crie um novo diretório para os arquivos do cliente de teste:
mkdir test_clientNavegue até o novo diretório:
cd test_clientCrie um arquivo chamado
snapshot_storage_config.yaml. Essa configuração especifica o bucket de destino do Cloud Storage em que o cluster salva o estado do snapshot binário do pod:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotStorageConfig metadata: name: example-pod-snapshot-storage-config spec: snapshotStorageConfig: gcs: bucket: "$BUCKET_NAME"Substitua o marcador de posição da variável de ambiente no arquivo de configuração:
sed -i "s/\$BUCKET_NAME/${BUCKET_NAME}/g" snapshot_storage_config.yamlAplique o manifesto de configuração de armazenamento:
kubectl apply -f snapshot_storage_config.yamlAguarde até que a configuração de armazenamento esteja pronta:
kubectl wait --for=condition=Ready podsnapshotstorageconfig/example-pod-snapshot-storage-config --timeout=60sCrie um arquivo chamado
snapshot_policy.yaml. Essa configuração estabelece uma regra de retenção que retém no máximo dois snapshots para sua carga de trabalho em sandbox. O tipo de gatilho é definido comomanual: isso permite que o aplicativo cliente controle snapshots sob demanda:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotPolicy metadata: name: example-pod-snapshot-policy namespace: default spec: storageConfigName: example-pod-snapshot-storage-config selector: matchLabels: app: agent-sandbox-workload triggerConfig: type: manual postCheckpoint: resume snapshotGroupingRules: groupByLabelValue: labels: ["agents.x-k8s.io/sandbox-name-hash", "tenant-id", "user-id"] groupRetentionPolicy: maxSnapshotCountPerGroup: 2Aplique o manifesto da política de snapshot:
kubectl apply -f snapshot_policy.yamlCrie um arquivo chamado
python-counter-template.yaml. Essa configuração define o pod de sandbox e atribui a identidade da conta de serviçosnapshot-saa ele. Essa atribuição ajuda a garantir que o sandbox seja executado com segurança. Dentro desse pod, o aplicativo em sandbox (um script Python) imprime continuamente um contador incremental nos registros do contêiner:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxTemplate metadata: name: python-counter-template namespace: default spec: podTemplate: metadata: labels: app: agent-sandbox-workload spec: serviceAccountName: snapshot-sa runtimeClassName: gvisor nodeSelector: topology.kubernetes.io/zone: us-central1-a # Pin to a zone to avoid CPU mismatch during restore containers: - name: python-counter image: python:3.13-slim command: ["python3", "-c"] args: - | import time i = 0 while True: print(f"Count: {i}", flush=True) i += 1 time.sleep(1)Aplique o manifesto do modelo de sandbox:
kubectl apply -f python-counter-template.yamlCrie um arquivo chamado
python-counter-pool.yaml. Essa configuração cria um pool de espera que mantém um sandbox pré-aquecido, criado com base no modelopython-counter-template, pronto para ser reivindicado pelo aplicativo cliente:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxWarmPool metadata: name: python-counter-pool namespace: default spec: replicas: 1 sandboxTemplateRef: name: python-counter-templateAplique o manifesto do pool de aquecimento:
kubectl apply -f python-counter-pool.yaml
Criar o aplicativo cliente
Crie a imagem do contêiner para o aplicativo cliente e faça upload dela para o Artifact Registry.
Crie um arquivo chamado
Dockerfile.client. Esse arquivo define o ambiente de execução do Python e as dependências do aplicativo cliente:FROM python:3.13-slim WORKDIR /app RUN pip install "k8s-agent-sandbox[tracing]==1.0.6" # Copy test script COPY client_test.py /app/client_test.py CMD ["python", "/app/client_test.py"]Crie um arquivo chamado
client_test.py. Esse script gerencia o ciclo de vida do sandbox e verifica se o estado é retomado após a criação de um snapshot:import time import logging import re from kubernetes import config, client from k8s_agent_sandbox.gke_extensions.snapshots import PodSnapshotSandboxClient logging.basicConfig(level=logging.INFO) def get_last_count(pod_name, namespace): v1 = client.CoreV1Api() try: logs = v1.read_namespaced_pod_log(name=pod_name, namespace=namespace) counts = re.findall(r"Count: (\d+)", logs) if counts: return int(counts[-1]) return None except Exception as e: logging.error(f"Failed to read logs for pod {pod_name}: {e}") return None def get_current_count(sandbox): # The sandbox's Pod has the same name as the Sandbox resource. pod_name = sandbox.get_pod_name() if not pod_name: logging.error(f"Could not determine pod name for sandbox {sandbox.sandbox_id}") return None return get_last_count(pod_name, sandbox.namespace) def suspend_sandbox(sandbox): logging.info("Pausing sandbox (using snapshots)...") try: suspend_resp = sandbox.suspend(snapshot_before_suspend=True) if suspend_resp.success: logging.info("Sandbox paused successfully.") if suspend_resp.snapshot_response: logging.info(f"Snapshot created: {suspend_resp.snapshot_response.snapshot_uid}") return suspend_resp else: logging.error(f"Failed to pause: {suspend_resp.error_reason}") exit(1) except Exception as e: logging.error(f"Failed to pause sandbox: {e}") exit(1) def resume_sandbox(sandbox): logging.info("Resuming sandbox (using snapshots)...") try: resume_resp = sandbox.resume() if resume_resp.success: logging.info("Sandbox resumed successfully.") if resume_resp.restored_from_snapshot: logging.info(f"Restored from snapshot: {resume_resp.snapshot_uid}") return resume_resp else: logging.error(f"Failed to resume: {resume_resp.error_reason}") exit(1) except Exception as e: logging.error(f"Failed to resume sandbox: {e}") exit(1) def verify_continuity(count_before, count_after): if count_before is not None and count_after is not None: logging.info(f"Verification: Count before={count_before}, Count after={count_after}") if count_after >= count_before: logging.info("SUCCESS: Sandbox resumed from where it left off (or later).") else: logging.error("FAIL: Sandbox counter reset or went backwards!") else: logging.warning("Could not verify counter continuity.") def main(): try: config.load_incluster_config() except config.ConfigException: config.load_kube_config() client_reg = PodSnapshotSandboxClient() logging.info("Creating sandbox...") sandbox = client_reg.create_sandbox(warmpool="python-counter-pool", namespace="default") logging.info(f"Sandbox created with ID: {sandbox.sandbox_id}") logging.info("Waiting for sandbox to run...") time.sleep(10) count_before = get_current_count(sandbox) logging.info(f"Count before suspend: {count_before}") suspend_sandbox(sandbox) logging.info("Waiting 10 seconds...") time.sleep(10) resume_sandbox(sandbox) logging.info("Waiting for sandbox to be ready again...") time.sleep(10) count_after = get_current_count(sandbox) logging.info(f"Count after resume: {count_after}") verify_continuity(count_before, count_after) logging.info("Snapshot test completed successfully.") if __name__ == "__main__": main()Crie a imagem do contêiner do cliente e faça upload dela para o Artifact Registry. Se o ambiente (como o Cloud Shell) tiver o Docker instalado, use-o para criar a imagem localmente. Se você estiver trabalhando em um ambiente sem o Docker, use o Cloud Build para criar e enviar a imagem remotamente:
Docker
Configure a autenticação do Docker para o Artifact Registry:
gcloud auth configure-docker "${LOCATION}-docker.pkg.dev"Crie e envie a imagem do contêiner do cliente localmente:
docker build -t "${LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/sandbox-client:latest" -f Dockerfile.client . docker push "${LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/sandbox-client:latest"
Cloud Build
Crie um arquivo chamado
cloudbuild.yaml:steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', '$LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/sandbox-client:latest', '-f', 'Dockerfile.client', '.'] images: - '$LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/sandbox-client:latest'Substitua os marcadores de posição variável de ambiente no arquivo de configuração:
sed -i "s/\$REPOSITORY_NAME/${REPOSITORY_NAME}/g" cloudbuild.yaml sed -i "s/\$LOCATION/${LOCATION}/g" cloudbuild.yaml sed -i "s/\$PROJECT_ID/${PROJECT_ID}/g" cloudbuild.yamlCrie o bucket do Cloud Storage para os registros do Cloud Build. Se o projeto já tiver usado o Cloud Build, esse bucket pode já existir, e o comando vai falhar com um erro informando que você já é o proprietário do bucket. Você pode ignorar esse erro com segurança:
gcloud storage buckets create "gs://${CLOUDBUILD_BUCKET_NAME}" \ --location="${BUCKET_LOCATION}"Conceda as permissões necessárias à conta de serviço do Cloud Build.
Os comandos a seguir usam a conta de serviço padrão do Compute Engine (
$PROJECT_NUMBER-compute@developer.gserviceaccount.com), que é o padrão para a maioria dos projetos. Se o projeto usar a conta de serviço legada do Cloud Build, substitua o endereço de e-mail do membro nos comandos a seguir por$PROJECT_NUMBER@cloudbuild.gserviceaccount.com.Como você adicionou uma vinculação condicional do IAM ao projeto anteriormente neste tutorial, inclua a flag
--condition=Noneao adicionar essas novas vinculações. Isso impede quegcloudpause para solicitar uma confirmação interativa:gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.writer" \ --condition=None gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/logging.logWriter" \ --condition=None gcloud storage buckets add-iam-policy-binding "gs://${CLOUDBUILD_BUCKET_NAME}" \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/storage.objectAdmin"Execute o build usando o Cloud Build:
gcloud builds submit --config cloudbuild.yaml
Executar o teste
Implante o aplicativo cliente para criar o sandbox, acionar um snapshot e verificar se o contador interno é retomado do estado salvo.
Crie um arquivo chamado
client_sa.yaml. Esse manifesto define a conta de serviçoagent-sandbox-client-sae as permissões de RBAC necessárias para gerenciar recursos personalizados do sandbox:apiVersion: v1 kind: ServiceAccount metadata: name: agent-sandbox-client-sa namespace: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: agent-sandbox-client-role namespace: default rules: - apiGroups: ["agents.x-k8s.io"] resources: ["sandboxes"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["extensions.agents.x-k8s.io"] resources: ["sandboxclaims"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["podsnapshot.gke.io"] resources: ["podsnapshotmanualtriggers", "podsnapshots"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: [""] resources: ["pods", "pods/log"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: agent-sandbox-client-rolebinding namespace: default subjects: - kind: ServiceAccount name: agent-sandbox-client-sa namespace: default roleRef: kind: Role name: agent-sandbox-client-role apiGroup: rbac.authorization.k8s.ioAplique a conta de serviço do cliente e o manifesto do RBAC:
kubectl apply -f client_sa.yamlCrie um arquivo chamado
client_pod.yaml. Esse manifesto cria o pod do aplicativo cliente usando a imagem do contêiner pré-criada:apiVersion: v1 kind: Pod metadata: name: agent-sandbox-client-pod namespace: default spec: serviceAccountName: agent-sandbox-client-sa containers: - name: client image: $LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/sandbox-client:latest imagePullPolicy: Always restartPolicy: NeverSubstitua os marcadores de posição das variável de ambiente no manifesto:
sed -i "s/\$REPOSITORY_NAME/${REPOSITORY_NAME}/g" client_pod.yaml sed -i "s/\$LOCATION/${LOCATION}/g" client_pod.yaml sed -i "s/\$PROJECT_ID/${PROJECT_ID}/g" client_pod.yamlAguarde até que o sandbox do pool de aquecimento esteja pronto:
kubectl wait sandboxwarmpool python-counter-pool \ --for=jsonpath='{.status.readyReplicas}'=1 \ --timeout=600sNa próxima etapa, o aplicativo cliente cria um recurso
SandboxClaim. Se o aplicativo criar a declaração antes que o sandbox do pool esteja pronto, o controlador poderá criar um novo sandbox para a declaração em vez de atribuir o do pool. Em um cluster do Autopilot, o sandbox pode levar vários minutos para ficar pronto, porque o GKE pode precisar criar um nó para ele.Aplique o manifesto do pod do aplicativo cliente:
kubectl apply -f client_pod.yamlTransmita os registros do pod para verificar o fluxo de execução:
kubectl logs -f agent-sandbox-client-pod
Quando o teste é executado corretamente, a saída é semelhante a esta (encurtada aqui para facilitar a leitura):
2026-04-21 23:02:39,030 - INFO - Creating sandbox...
...
2026-04-21 23:02:51,755 - INFO - Count before suspend: 23
2026-04-21 23:02:51,755 - INFO - Pausing sandbox (using snapshots)...
...
2026-04-21 23:03:07,115 - INFO - Resuming sandbox (using snapshots)...
...
2026-04-21 23:03:21,329 - INFO - Count after resume: 38
2026-04-21 23:03:21,329 - INFO - Verification: Count before=23, Count after=38
2026-04-21 23:03:21,329 - INFO - SUCCESS: Sandbox resumed from where it left off (or later).
A saída mostra que o sandbox preserva o estado quando é suspenso e retomado. O contador para de avançar enquanto o sandbox está suspenso, porque o controlador do Agent Sandbox exclui o pod do sandbox. Quando o sandbox é retomado, o controlador recria o pod, que é restaurado do snapshot, e o contador continua. Sem a suspensão, o contador teria continuado a avançar durante o período de suspensão, e a contagem seria significativamente maior.
Limpar recursos
Para evitar cobranças na sua conta do Google Cloud , exclua os recursos criados:
Exclua o cluster do GKE. Isso também exclui o pool de nós e todas as contas de serviço do Kubernetes dentro dele:
Piloto automático
gcloud container clusters delete ${CLUSTER_NAME} \ --location="${LOCATION}" --quietPadrão
gcloud container clusters delete ${CLUSTER_NAME} \ --location="${ZONE}" --quietExclua o repositório do Artifact Registry para remover o repositório do Docker criado para a imagem de teste:
gcloud artifacts repositories delete ${REPOSITORY_NAME} --location="${LOCATION}" --quietExclua o bucket do Cloud Storage e todos os snapshots dentro dele. Isso remove automaticamente as vinculações do IAM da Identidade da carga de trabalho no nível do bucket aplicadas a ele:
gcloud storage rm --recursive "gs://${BUCKET_NAME}"Remova a vinculação do IAM no nível do projeto para o agente de serviço do GKE:
gcloud projects remove-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:service-${PROJECT_NUMBER}@container-engine-robot.iam.gserviceaccount.com" \ --role="roles/storage.objectUser" \ --condition="expression=resource.name.startsWith(\"projects/_/buckets/${BUCKET_NAME}\"),title=restrict_to_bucket,description=Restricts access to one bucket only"Se você usou o Cloud Build em vez do Docker para criar e enviar a imagem do contêiner, limpe os recursos do Cloud Build. Exclua apenas os recursos criados para este tutorial, porque outras cargas de trabalho no projeto podem depender de recursos que já existiam:
Se o bucket do Cloud Build não existia antes de você iniciar este tutorial, exclua-o:
gcloud storage rm --recursive "gs://${CLOUDBUILD_BUCKET_NAME}"Se a conta de serviço padrão do Compute Engine não tinha os papéis
roles/artifactregistry.writereroles/logging.logWriterantes de você iniciar este tutorial, remova-os:gcloud projects remove-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.writer" \ --condition=None gcloud projects remove-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/logging.logWriter" \ --condition=None
A seguir
- Saiba como isolar a execução de código de IA com o Agent Sandbox no GKE.
- Saiba como salvar e restaurar o Agent Sandbox em ambientes do GKE.
- Para entender as camadas de isolamento que protegem suas cargas de trabalho não confiáveis, consulte GKE Sandbox.
- Confira o projeto de código aberto do Agent Sandbox no GitHub.
- Saiba como usar os Kata Containers de código aberto com o Agent Sandbox no GKE. O Kata Containers não é um produto do Google Cloud . Se você instalar e usar esse software, será responsável pelo gerenciamento e pela solução de problemas. O suporte e os SLAs do Google não se aplicam aos contêineres do Kata.