Usa instantáneas de la zona de pruebas del agente en un clúster de Google Kubernetes Engine (GKE) para preservar el estado de tus entornos de zona de pruebas. Este enfoque proporciona una depuración coherente, acelera la iteración del desarrollo y facilita la recuperación rápida de configuraciones complejas. En este instructivo, implementarás y probarás esta capacidad ejecutando una aplicación cliente que crea, pausa y reanuda de forma programática los entornos de zona de pruebas dentro del clúster.
Para obtener más información sobre cómo tomar instantáneas de Pods, consulta Restablece a partir de una instantánea de Pod.
Costos
La zona de pruebas del agente se ofrece sin cargo adicional en GKE. Los precios de GKE se aplican a los recursos que creas.
Antes de comenzar
-
En la Google Cloud consola de, en la página del selector de proyectos, selecciona o crea un Google Cloud proyecto de.
Roles necesarios para seleccionar o crear un proyecto
- Selecciona un proyecto: Para seleccionar un proyecto, no se requiere un rol de IAM específico. Puedes seleccionar cualquier proyecto en el que se te haya otorgado un rol.
-
Crea un proyecto: Para crear un proyecto, necesitas el rol de creador de proyectos
(
roles/resourcemanager.projectCreator), que contiene elresourcemanager.projects.createpermiso. Obtén más información para otorgar roles.
-
Verifica que la facturación esté habilitada para tu Google Cloud proyecto.
Habilita las APIs de Artifact Registry, Kubernetes Engine y Cloud Build.
Roles necesarios para habilitar las APIs
Para habilitar las APIs, necesitas el rol de IAM de administrador de Service Usage (
roles/serviceusage.serviceUsageAdmin), que contiene el permisoserviceusage.services.enable. Obtén más información para otorgar roles.-
En la Google Cloud consola de, activa Cloud Shell.
- Verifica que tengas los permisos necesarios para completar este instructivo.
Roles obligatorios
Si quieres obtener los permisos que
necesitas para crear y administrar zonas de pruebas,
pídele a tu administrador que te otorgue el
rol de IAM de administrador de Kubernetes Engine (roles/container.admin) en el proyecto.
Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.
También puedes obtener los permisos necesarios mediante roles personalizados o cualquier otro rol predefinido.
Limitaciones
En un clúster regional, los nodos de diferentes zonas pueden tener diferentes microarquitecturas de CPU. Debido a que las instantáneas capturan el estado de la CPU, no se puede restablecer una instantánea en un nodo con funciones de CPU faltantes (por ejemplo, con el error OCI runtime restore failed: incompatible FeatureSet).
Para evitar este problema, usa la configuración adecuada para tu entorno:
- Producción: Para preservar la alta disponibilidad en todo el clúster, no ancles las cargas de trabajo a una zona específica. En cambio, asegúrate de que la función de CPU sea coherente en todas las zonas especificando una plataforma de CPU mínima. Para obtener más información, consulta Elige una plataforma de CPU mínima.
- Pruebas: Para simplificar la configuración y evitar errores iniciales de desajuste de CPU, puedes usar un campo
nodeSelectoren tu manifiestoSandboxTemplatepara anclar el Pod a una zona específica, comous-central1-a. En el ejemplo de este instructivo, se usa esta configuración de prueba.
Define las variables de entorno.
Para simplificar los comandos que ejecutas en este instructivo, puedes establecer variables de entorno en Cloud Shell. En Cloud Shell, define las siguientes variables de entorno útiles ejecutando los siguientes 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 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"
A continuación, se explica el significado de estas variables de entorno:
PROJECT_ID: Es el ID de tu proyecto actual Google Cloud . Definir esta variable ayuda a garantizar que todos los recursos se creen en el proyecto correcto.PROJECT_NUMBER: Es el número de tu proyecto actual. Google CloudCLUSTER_NAME: Es el nombre de tu clúster de GKE, por ejemplo,test-snapshot.LOCATION: Es la Google Cloud región en la que se encuentran tu clúster de GKE y el repositorio de Artifact Registry, por ejemplo,us-central1.BUCKET_LOCATION: Es la ubicación de tus buckets de Cloud Storage, por ejemplo,us.BUCKET_NAME: Es el nombre del bucket de Cloud Storage que se usa para las instantáneas.CLOUDBUILD_BUCKET_NAME: Es el nombre del bucket de Cloud Storage que se usa para los registros de Cloud Build.MACHINE_TYPE: Es el tipo de máquina que se usará para los nodos del clúster, por ejemplo,e2-standard-8.REPOSITORY_NAME: Es el nombre del repositorio de Artifact Registry, por ejemplo,agent-sandbox.
Descripción general de los pasos de configuración
Para habilitar y probar las instantáneas de Pods de los entornos de zona de pruebas del agente desde tu clúster, debes realizar varios pasos de configuración. Para comprender estos pasos, es útil comprender primero los componentes involucrados en el flujo de trabajo general.
Componentes clave
En este instructivo, se usan las siguientes dos aplicaciones de Python para probar el proceso de instantáneas:
- Aplicación cliente: Es una secuencia de comandos de Python que se ejecuta en un Pod estándar en tu
clúster. Esta aplicación administra el ciclo de vida de la zona de pruebas: crea la zona de pruebas de forma programática, la pausa para activar una instantánea, la reanuda y verifica que se haya conservado el estado. En este instructivo, crearás una cuenta de servicio de Kubernetes llamada
agent-sandbox-client-say le otorgarás permisos de RBAC para que el Pod de la aplicación cliente pueda administrar recursos personalizados de zona de pruebas y objetos de activación de instantáneas con la API de Kubernetes. - Aplicación de zona de pruebas: Es una secuencia de comandos de Python que incrementa e imprime un
contador cada segundo. Esta aplicación se ejecuta de forma segura dentro del entorno de zona de pruebas aislado para generar un estado cambiante que la aplicación cliente puede verificar. En este instructivo, crearás una cuenta de servicio de Kubernetes dedicada llamada
snapshot-say configurarás Workload Identity para autorizar al Pod de zona de pruebas a leer y escribir de forma segura objetos de instantáneas en Cloud Storage.
Proceso de configuración y prueba
En la siguiente lista, se resumen los pasos que debes realizar para configurar tu entorno y ejecutar la prueba:
- Crea un clúster: Crea un clúster de Autopilot o Estándar con instantáneas de Pods y la función de zona de pruebas del agente habilitada.
- Crea un repositorio de Artifact Registry: Crea un repositorio de Docker para almacenar la imagen de contenedor de tu aplicación cliente.
- Instala la zona de pruebas del agente: instala los componentes y las extensiones principales de la zona de pruebas del agente en tu clúster.
- Configura el almacenamiento y los permisos: Crea un bucket de Cloud Storage y configura los permisos de Workload Identity para permitir que las instantáneas se guarden de forma segura.
- Configura las instantáneas de Pods: Crea y aplica la configuración de almacenamiento de instantáneas, la política de instantáneas y la plantilla de zona de pruebas.
- Crea la aplicación cliente: crea la imagen de contenedor para la aplicación cliente y envíala a tu repositorio de Artifact Registry.
- Ejecuta la prueba: Implementa el Pod de la aplicación cliente, que crea la zona de pruebas, la pausa para capturar una instantánea, la reanuda y verifica que el estado del contador se haya restablecido correctamente.
Crea un clúster
Crea un clúster de GKE nuevo con las instantáneas de Pods habilitadas. Para obtener compatibilidad total con las funciones, especifica el canal de versiones rápido.
Autopilot
Crea un clúster de Autopilot con las funciones necesarias:
gcloud beta container clusters create-auto ${CLUSTER_NAME} \
--enable-pod-snapshots \
--release-channel=rapid \
--location=${LOCATION}
Estándar
Crea un clúster estándar con las funciones necesarias:
gcloud beta 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=${LOCATION}
Crea un grupo de nodos con gVisor habilitado:
gcloud container node-pools create gvisor-pool \
--cluster ${CLUSTER_NAME} \
--num-nodes=1 \
--location=${LOCATION} \
--project=${PROJECT_ID} \
--sandbox type=gvisor
Crea un repositorio de Artifact Registry
Crea un repositorio de Docker en Artifact Registry para almacenar la imagen de contenedor de tu aplicación cliente (la aplicación que crea y administra la zona de pruebas):
gcloud artifacts repositories create ${REPOSITORY_NAME} \
--repository-format=docker \
--location=${LOCATION} \
--description="Docker repository for Agent Sandbox"
Instala la zona de pruebas del agente
Instala los componentes y las extensiones principales de la zona de pruebas del agente en tu clúster (con la versión v0.4.6 como ejemplo):
# Install the core agent-sandbox components
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/v0.4.6/manifest.yaml
# Install the extensions (e.g., Warm Pools, Claims)
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/v0.4.6/extensions.yaml
Configura el almacenamiento y los permisos
Configura un bucket de Cloud Storage para almacenar instantáneas de Pods y otorga los permisos necesarios de Workload Identity a la cuenta de servicio snapshot-sa y al agente de servicio de GKE. Esto permite que tus cargas de trabajo de zona de pruebas guarden y recuperen objetos de instantáneas de forma segura:
Crea un bucket de Cloud Storage nuevo:
gcloud storage buckets create "gs://${BUCKET_NAME}" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="${BUCKET_LOCATION}"Crea una cuenta de servicio de Kubernetes en el espacio de nombres
default. Tu aplicación de zona de pruebas (la secuencia de comandos del contador de Python) usa esta identidad para autenticarse en las APIs externas y acceder de forma segura a los objetos de instantáneas almacenados en Cloud Storage:kubectl create serviceaccount "snapshot-sa" \ --namespace "default"Vincula el rol
storage.bucketViewera tu cuenta de servicio con Workload Identity. Este rol permite que la carga de trabajo de zona de pruebas enumere el contenido del bucket y ubique instantáneas específicas: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"Vincula el rol
storage.objectUsera tu cuenta de servicio con Workload Identity. Este rol proporciona el permiso para leer, guardar y borrar objetos binarios de instantáneas dentro del 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"Otorga permisos al agente de servicio de GKE para administrar (crear, enumerar, leer y borrar) objetos de instantáneas dentro del 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"
Configura las instantáneas de Pods
Crea y aplica los archivos de configuración para instalar los recursos personalizados de Kubernetes necesarios. Estos recursos definen cómo el clúster almacena y administra las instantáneas de Pods:
- PodSnapshotStorageConfig: Especifica el bucket de Cloud Storage designado para almacenar objetos binarios de instantáneas.
- PodSnapshotPolicy: Define cómo se activan las instantáneas de forma manual, con qué frecuencia se agrupan y sus políticas de retención.
- SandboxTemplate: Define el contenedor subyacente, los selectores de nodos y las cuentas de servicio para ejecutar la carga de trabajo de zona de pruebas aislada.
Crea un directorio nuevo para los archivos del cliente de prueba:
mkdir test_clientNavega al directorio nuevo:
cd test_clientCrea un archivo llamado
snapshot_storage_config.yaml. Esta configuración especifica el bucket de Cloud Storage de destino en el que el clúster guarda el estado binario de la instantánea de Pods:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotStorageConfig metadata: name: example-pod-snapshot-storage-config spec: snapshotStorageConfig: gcs: bucket: "$BUCKET_NAME"Sustituye el marcador de posición de la variable de entorno en el archivo de configuración:
sed -i "s/\$BUCKET_NAME/$BUCKET_NAME/g" snapshot_storage_config.yamlAplica el manifiesto de configuración de almacenamiento:
kubectl apply -f snapshot_storage_config.yamlEspera a que la configuración de almacenamiento esté lista:
kubectl wait --for=condition=Ready podsnapshotstorageconfig/example-pod-snapshot-storage-config --timeout=60sCrea un archivo llamado
snapshot_policy.yaml. Esta configuración establece una regla de retención que conserva un máximo de dos instantáneas para tu carga de trabajo de zona de pruebas. El tipo de activador se establece enmanual: Esto permite que la aplicación cliente controle las instantáneas a pedido: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: 2Aplica el manifiesto de la política de instantáneas:
kubectl apply -f snapshot_policy.yamlCrea un archivo llamado
python-counter-template.yaml. Esta configuración define el Pod de zona de pruebas y le asigna la identidad de la cuenta de serviciosnapshot-sa. Esta asignación ayuda a garantizar que la zona de pruebas se ejecute de forma segura. Dentro de ese Pod, la aplicación de zona de pruebas (una secuencia de comandos de Python) imprime de forma continua un contador de incremento en los registros del contenedor:apiVersion: extensions.agents.x-k8s.io/v1alpha1 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)Aplica el manifiesto de la plantilla de zona de pruebas:
kubectl apply -f python-counter-template.yaml
Crear la aplicación cliente
Crea la imagen de contenedor para la aplicación cliente y súbela a Artifact Registry.
Crea un archivo llamado
Dockerfile.client. Este archivo define el entorno de ejecución de Python y las dependencias de la aplicación cliente:FROM python:3.13-slim WORKDIR /app RUN pip install "k8s-agent-sandbox[tracing]==0.4.6" # Copy test script COPY client_test.py /app/client_test.py CMD ["python", "/app/client_test.py"]Crea un archivo llamado
client_test.py. Esta secuencia de comandos administra el ciclo de vida de la zona de pruebas y verifica que el estado se reanude correctamente después de tomar una instantánea: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_pod_name(sandbox_id, namespace): custom_api = client.CustomObjectsApi() try: sandbox_cr = custom_api.get_namespaced_custom_object( group="agents.x-k8s.io", version="v1alpha1", namespace=namespace, plural="sandboxes", name=sandbox_id ) metadata = sandbox_cr.get("metadata", {}) annotations = metadata.get("annotations", {}) return annotations.get("agents.x-k8s.io/pod-name") except Exception as e: logging.error(f"Failed to get sandbox CR: {e}") return None def get_current_count(sandbox_id, namespace="default"): pod_name = get_current_pod_name(sandbox_id, namespace) if not pod_name: logging.error(f"Could not determine pod name for sandbox {sandbox_id}") return None return get_last_count(pod_name, 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(template="python-counter-template", 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.sandbox_id) 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.sandbox_id) logging.info(f"Count after resume: {count_after}") verify_continuity(count_before, count_after) logging.info("Snapshot test completed successfully.") if __name__ == "__main__": main()Crea la imagen de contenedor del cliente y súbela a Artifact Registry. Si tu entorno (como Cloud Shell) tiene instalado Docker, puedes usar Docker para compilar la imagen de forma local. Si trabajas en un entorno sin Docker, puedes usar Cloud Build para compilar y enviar la imagen de forma remota:
Docker
Configura la autenticación de Docker para Artifact Registry:
gcloud auth configure-docker "${LOCATION}-docker.pkg.dev"Compila y envía la imagen de contenedor del cliente de forma local:
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
Crea un archivo llamado
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'Sustituye los marcadores de posición de las variable de entorno en el archivo de configuración:
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.yamlCrea el bucket de Cloud Storage para los registros de Cloud Build:
gcloud storage buckets create "gs://${CLOUDBUILD_BUCKET_NAME}" \ --location="${BUCKET_LOCATION}"Otorga los permisos necesarios a la cuenta de servicio de Cloud Build.
Los siguientes comandos usan la cuenta de servicio predeterminada de Compute Engine (
$PROJECT_NUMBER-compute@developer.gserviceaccount.com), que es la predeterminada para la mayoría de los proyectos. Si tu proyecto usa la cuenta de servicio heredada de Cloud Build, reemplaza la dirección de correo electrónico del miembro en los siguientes comandos por$PROJECT_NUMBER@cloudbuild.gserviceaccount.com.Debido a que agregaste una vinculación condicional de IAM a tu proyecto anteriormente en este instructivo, debes incluir la marca
--condition=Nonecuando agregues estas vinculaciones nuevas. Esto evita quegcloudse detenga para solicitar una confirmación interactiva:gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.writer" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/logging.logWriter" gcloud storage buckets add-iam-policy-binding "gs://$CLOUDBUILD_BUCKET_NAME" \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/storage.objectAdmin"Ejecuta la compilación con Cloud Build:
gcloud builds submit --config cloudbuild.yaml
Ejecuta la prueba
Implementa la aplicación cliente para crear la zona de pruebas, activar una instantánea y verificar que el contador interno se reanude correctamente desde su estado guardado.
Crea un archivo llamado
client_sa.yaml. Este manifiesto define la cuenta de servicioagent-sandbox-client-say sus permisos de RBAC necesarios para administrar recursos personalizados de zona de pruebas: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.ioAplica la cuenta de servicio del cliente y el manifiesto de RBAC:
kubectl apply -f client_sa.yamlCrea un archivo llamado
client_pod.yaml. Este manifiesto crea el Pod de la aplicación cliente con la imagen de contenedor precompilada: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: NeverSustituye los marcadores de posición de las variable de entorno en el manifiesto:
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.yamlAplica el manifiesto de Pod de la aplicación cliente:
kubectl apply -f client_pod.yamlTransmite los registros de Pods para verificar el flujo de ejecución:
kubectl logs -f agent-sandbox-client-pod
Cuando la prueba se ejecuta correctamente, el resultado es similar al siguiente (aquí se abrevia para facilitar la lectura):
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).
En el resultado, se muestra que la zona de pruebas conserva correctamente su estado cuando se suspende y se reanuda. El contador deja de avanzar mientras la zona de pruebas está suspendida (pausada y escalada a cero) y reanuda el contador cuando se restablece la zona de pruebas. Sin la suspensión, el contador habría seguido avanzando durante el período de suspensión y el recuento sería mucho más alto.
Limpia los recursos
Para evitar que se apliquen cargos a tu Google Cloud cuenta de, borra los recursos que creaste:
Borra el clúster de GKE. Esta acción también borra el grupo de nodos y todas las cuentas de servicio de Kubernetes que contiene:
gcloud beta container clusters delete ${CLUSTER_NAME} --location="${LOCATION}" --quietBorra el repositorio de Artifact Registry para quitar el repositorio de Docker que creaste para la imagen de prueba:
gcloud artifacts repositories delete ${REPOSITORY_NAME} --location="${LOCATION}" --quietBorra el bucket de Cloud Storage y todas las instantáneas que contiene. Esto quita automáticamente las vinculaciones de IAM de Workload Identity a nivel del bucket que se le aplicaron:
gcloud storage rm --recursive "gs://${BUCKET_NAME}"Quita la vinculación de IAM a nivel del proyecto para el agente de servicio de 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"Si usaste Cloud Build en lugar de Docker para compilar y enviar la imagen de contenedor, borra el bucket de registros y quita los permisos de la cuenta de servicio:
gcloud storage rm --recursive "gs://${CLOUDBUILD_BUCKET_NAME}" gcloud projects remove-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.writer" gcloud projects remove-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/logging.logWriter"
¿Qué sigue?
- Obtén información para aislar la ejecución de código de IA: activador externo.
- Obtén información para guardar y restablecer entornos de zona de pruebas del agente.
- Para comprender las capas de aislamiento que protegen tus cargas de trabajo no confiables, consulta GKE Sandbox.
- Explora el proyecto de zona de pruebas del agente de código abierto en GitHub.
- Obtén información para usar contenedores Kata de código abierto con la zona de pruebas del agente. Los contenedores Kata no son un Google Cloud producto. Si instalas y usas este software, eres responsable de la administración y la solución de problemas. La asistencia y los ANS de Google no se aplican a los contenedores Kata.