Utilizza Agent Sandbox sugli snapshot di Google Kubernetes Engine (GKE) all'interno di un cluster per preservare lo stato degli ambienti in sandbox. Questo approccio fornisce un debug coerente, accelera l'iterazione dello sviluppo e facilita il recupero rapido di configurazioni complesse. In questo tutorial, eseguirai il deployment e testerai questa funzionalità eseguendo un'applicazione client che crea, mette in pausa e riprende in modo programmatico gli ambienti in modalità sandbox all'interno del cluster.
Per saperne di più su come acquisire snapshot dei pod, consulta Ripristina da uno snapshot del pod.
Costi
Agent Sandbox su GKE è un software open source che puoi utilizzare senza costi aggiuntivi. I prezzi di GKE si applicano alle risorse che crei, incluse le risorse di computing utilizzate dal controller di Agent Sandbox.
Prima di iniziare
-
Nella console Google Cloud , nella pagina di selezione del progetto, seleziona o crea un progetto Google Cloud .
Ruoli richiesti per selezionare o creare un progetto
- Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per cui ti è stato concesso un ruolo.
-
Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (
roles/resourcemanager.projectCreator), che contiene l'autorizzazioneresourcemanager.projects.create. Scopri come concedere i ruoli.
-
Verifica che la fatturazione sia attivata per il tuo progetto Google Cloud .
Abilita le API Artifact Registry, Kubernetes Engine e API Cloud Build, se non sono già abilitate.
Ruoli richiesti per abilitare le API
Per abilitare le API, devi disporre dell'autorizzazione
serviceusage.services.enable. Se hai creato il progetto, probabilmente hai già questa autorizzazione tramite il ruolo Proprietario (roles/owner). In caso contrario, puoi ottenere questa autorizzazione tramite il ruolo Amministratore Service Usage (roles/serviceusage.serviceUsageAdmin). Scopri come concedere i ruoli.-
Nella console Google Cloud , attiva Cloud Shell.
- Verifica di disporre delle autorizzazioni necessarie per completare questo tutorial.
Ruoli obbligatori
Per ottenere le autorizzazioni necessarie per creare e gestire le sandbox, chiedi all'amministratore di concederti il ruolo IAM Kubernetes Engine Admin (roles/container.admin) nel progetto.
Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.
Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.
Limitazioni
Gli snapshot dei pod richiedono gVisor e non funzionano con le sandbox microVM.
In un cluster a livello di regione, i nodi in zone diverse potrebbero avere microarchitetture della CPU diverse. Poiché gli snapshot acquisiscono lo stato della CPU, il ripristino di uno snapshot su un nodo con funzionalità della CPU mancanti non va a buon fine (ad esempio, con l'errore OCI runtime restore failed: incompatible FeatureSet).
Per evitare questo problema, utilizza la configurazione appropriata per il tuo ambiente:
- Produzione: per preservare l'alta affidabilità nel cluster, non assegnare i workload a una zona specifica. Per garantire la coerenza delle funzionalità della CPU in tutte le zone, specifica una piattaforma CPU minima. Per saperne di più, consulta Scegli una piattaforma CPU minima.
- Test: per semplificare la configurazione ed evitare errori iniziali di mancata corrispondenza della CPU, puoi utilizzare un campo
nodeSelectornel manifestSandboxTemplateper assegnare il pod a una zona specifica, ad esempious-central1-a. L'esempio in questo tutorial utilizza questa configurazione di test.
Definisci le variabili di ambiente
Per semplificare i comandi che esegui in questo tutorial, puoi impostare le variabili di ambiente in Cloud Shell. In Cloud Shell, definisci le seguenti variabili di ambiente utili eseguendo questi comandi:
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"
Ecco una spiegazione di queste variabili di ambiente:
PROJECT_ID: l'ID del progetto Google Cloud corrente. I comandi in questo documento utilizzano questo ID per assegnare un nome alle risorse e concedere le autorizzazioni IAM.PROJECT_NUMBER: il numero del progetto Google Cloud corrente.CLUSTER_NAME: il nome del tuo cluster GKE, ad esempiotest-snapshot.LOCATION: la regione Google Cloud per il tuo repository Artifact Registry (ad esempio,us-central1). Se crei un cluster Autopilot, anche il cluster utilizza questa regione.ZONE: la zona del tuo cluster. Se crei un cluster Standard, impostalo su una zona nella regioneLOCATION(ad esempious-central1-a). Il template della sandbox che crei in un secondo momento in questo tutorial esegue le sandbox inus-central1-a. Se utilizzi una zona diversa, modifica anche la zona nel template.BUCKET_LOCATION: la località dei bucket Cloud Storage, ad esempious.BUCKET_NAME: il nome del bucket Cloud Storage utilizzato per gli snapshot, ad esempioPROJECT_ID_snapshots. I nomi dei bucket devono essere univoci a livello globale.CLOUDBUILD_BUCKET_NAME: il nome del bucket Cloud Storage utilizzato per i log di Cloud Build. Questo valore è il nome predefinito del bucket Cloud Build, quindi non modificarlo.MACHINE_TYPE: il tipo di macchina da utilizzare per i nodi del cluster e il pool di nodi gVisor, ad esempion2-standard-2. Gli snapshot dei pod non supportano i tipi di macchine E2.REPOSITORY_NAME: il nome del repository Artifact Registry, ad esempioagent-sandbox.
Panoramica dei passaggi di configurazione
Per abilitare e testare gli snapshot dei pod di Agent Sandbox negli ambienti GKE dall'interno del cluster, devi eseguire diversi passaggi di configurazione. Per comprendere questi passaggi, è utile innanzitutto comprendere i componenti coinvolti nel workflow complessivo.
Componenti chiave
Questo tutorial utilizza le seguenti due applicazioni Python per testare il processo di snapshot:
- Applicazione client: uno script Python in esecuzione in un pod standard nel tuo cluster. Questa applicazione gestisce il ciclo di vita della sandbox: crea la sandbox in modo programmatico, la mette in pausa per attivare uno snapshot, la riprende e verifica che lo stato sia stato conservato. In questo tutorial, creerai un account di servizio Kubernetes denominato
agent-sandbox-client-sae gli concederai le autorizzazioni RBAC in modo che il pod dell'applicazione client possa gestire le risorse personalizzate della sandbox e gli oggetti trigger degli snapshot utilizzando l'API Kubernetes. - Applicazione in sandbox: uno script Python che incrementa e stampa un contatore ogni secondo. Questa applicazione viene eseguita in modo sicuro all'interno dell'ambiente sandbox isolato per generare uno stato mutevole che l'applicazione client può verificare. In questo tutorial, creerai un service account Kubernetes dedicato denominato
snapshot-sae configurerai Workload Identity per autorizzare il pod in sandbox a leggere e scrivere in modo sicuro gli oggetti snapshot in Cloud Storage.
Procedura di configurazione e test
L'elenco seguente riassume i passaggi da eseguire per configurare l'ambiente ed eseguire il test:
- Crea un cluster: crea un cluster Autopilot o Standard con gli snapshot dei pod abilitati.
- Crea un repository Artifact Registry: crea un repository Docker per archiviare l'immagine container per la tua applicazione client.
- Installa Agent Sandbox: installa i componenti e le estensioni principali di Agent Sandbox nel tuo cluster.
- Configura lo spazio di archiviazione e le autorizzazioni: crea un bucket Cloud Storage e configura le autorizzazioni di Workload Identity per consentire il salvataggio sicuro degli snapshot.
- Configura gli snapshot dei pod: crea e applica la configurazione dello spazio di archiviazione degli snapshot, la policy degli snapshot, il template della sandbox e il pool caldo.
- Crea l'applicazione client: crea l'immagine container per l'applicazione client ed eseguine il push nel repository Artifact Registry.
- Esegui il test: esegui il deployment del pod dell'applicazione client, che crea la sandbox, la mette in pausa per acquisire uno snapshot, la riprende e verifica che lo stato del contatore sia stato ripristinato correttamente.
Crea un cluster
Crea un nuovo cluster GKE con gli snapshot dei pod abilitati. Per la compatibilità completa delle funzionalità, specifica il canale di rilascio rapido.
Autopilot
Crea un cluster Autopilot con le funzionalità richieste:
gcloud container clusters create-auto ${CLUSTER_NAME} \
--enable-pod-snapshots \
--release-channel=rapid \
--location=${LOCATION}
Standard
Crea un cluster Standard con le funzionalità richieste. Per ridurre i costi, il seguente comando crea un cluster di zona, che esegue il control plane e i nodi in una 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}
Crea un pool di nodi con gVisor abilitato:
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
Crea un repository Artifact Registry
Crea un repository Docker in Artifact Registry per archiviare l'immagine container per la tua applicazione client (l'applicazione che crea e gestisce la sandbox):
gcloud artifacts repositories create ${REPOSITORY_NAME} \
--repository-format=docker \
--location=${LOCATION} \
--description="Docker repository for Agent Sandbox"
Installa Agent Sandbox
Installa i componenti principali e le estensioni di Agent Sandbox sul tuo cluster. Questo tutorial utilizza la versione 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
Per saperne di più sull'installazione di Agent Sandbox, consulta Installa Agent Sandbox su GKE.
Configura lo spazio di archiviazione e le autorizzazioni
Configura un bucket Cloud Storage per l'archiviazione degli snapshot dei pod e concedi
le autorizzazioni di Workload Identity richieste al account di servizio snapshot-sa
e all'agente di servizio GKE. In questo modo, i workload in sandbox possono salvare e recuperare in modo sicuro gli oggetti snapshot:
Crea un nuovo bucket Cloud Storage:
gcloud storage buckets create "gs://${BUCKET_NAME}" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="${BUCKET_LOCATION}"Crea un account di servizio Kubernetes nello spazio dei nomi
default. La tua applicazione in sandbox (lo script del contatore Python) utilizza questa identità per autenticarsi con le API esterne e accedere in modo sicuro agli oggetti snapshot archiviati in Cloud Storage:kubectl create serviceaccount "snapshot-sa" \ --namespace "default"Associa il ruolo
storage.bucketVieweral tuo account di servizio utilizzando Workload Identity. Questo ruolo consente al workload in sandbox di elencare i contenuti del bucket e individuare snapshot specifici: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"Associa il ruolo
storage.objectUseral tuo account di servizio utilizzando Workload Identity. Questo ruolo fornisce l'autorizzazione per leggere, salvare ed eliminare gli oggetti binari degli snapshot all'interno 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"Concedi all'agente di servizio GKE le autorizzazioni per gestire (creare, elencare, leggere ed eliminare) gli oggetti snapshot all'interno 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 gli snapshot dei pod
Crea e applica i file di configurazione per installare le risorse personalizzate Kubernetes richieste. Queste risorse definiscono il modo in cui il cluster archivia e gestisce gli snapshot dei pod:
PodSnapshotStorageConfig: specifica il bucket Cloud Storage designato per l'archiviazione degli oggetti binari degli snapshot.PodSnapshotPolicy: definisce il modo in cui gli snapshot vengono attivati manualmente, la frequenza con cui vengono raggruppati e le relative policy di conservazione.SandboxTemplate: definisce il container, i selettori dei nodi e i service account sottostanti per l'esecuzione del workload in sandbox isolato.SandboxWarmPool: mantiene una sandbox pre-riscaldata, creata dalla risorsaSandboxTemplate, pronta per essere richiesta dall'applicazione client.
Crea una nuova directory per i file del client di test:
mkdir test_clientVai alla nuova directory:
cd test_clientCrea un file denominato
snapshot_storage_config.yaml. Questa configurazione specifica il bucket Cloud Storage di destinazione in cui il cluster salva lo stato dello snapshot binario dei pod:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotStorageConfig metadata: name: example-pod-snapshot-storage-config spec: snapshotStorageConfig: gcs: bucket: "$BUCKET_NAME"Sostituisci il segnaposto della variabile di ambiente nel file di configurazione:
sed -i "s/\$BUCKET_NAME/${BUCKET_NAME}/g" snapshot_storage_config.yamlApplica il manifest di configurazione dello spazio di archiviazione:
kubectl apply -f snapshot_storage_config.yamlAttendi che la configurazione dello spazio di archiviazione sia pronta:
kubectl wait --for=condition=Ready podsnapshotstorageconfig/example-pod-snapshot-storage-config --timeout=60sCrea un file denominato
snapshot_policy.yaml. Questa configurazione stabilisce una regola di conservazione che conserva un massimo di due snapshot per il workload in sandbox. Il tipo di trigger è impostato sumanual: ciò consente all'applicazione client di controllare gli snapshot on demand: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: 2Applica il manifest della policy snapshot:
kubectl apply -f snapshot_policy.yamlCrea un file denominato
python-counter-template.yaml. Questa configurazione definisce il pod della sandbox e gli assegna l'identità del account di serviziosnapshot-sa. Questa assegnazione contribuisce a garantire che la sandbox venga eseguita in modo sicuro. All'interno del pod, l'applicazione in sandbox (uno script Python) stampa continuamente un contatore incrementale nei log del container: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)Applica il manifest del template della sandbox:
kubectl apply -f python-counter-template.yamlCrea un file denominato
python-counter-pool.yaml. Questa configurazione crea un pool caldo che mantiene una sandbox pre-riscaldata, creata dal templatepython-counter-template, pronta per essere richiesta dall'applicazione client:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxWarmPool metadata: name: python-counter-pool namespace: default spec: replicas: 1 sandboxTemplateRef: name: python-counter-templateApplica il manifest del pool caldo:
kubectl apply -f python-counter-pool.yaml
Crea l'applicazione client
Crea l'immagine container per l'applicazione client e caricala in Artifact Registry.
Crea un file denominato
Dockerfile.client. Questo file definisce l'ambiente di runtime Python e le dipendenze per l'applicazione client: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"]Crea un file denominato
client_test.py. Questo script gestisce il ciclo di vita della sandbox e verifica che lo stato venga ripristinato correttamente dopo l'acquisizione di uno 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()Crea l'immagine container del client e caricala in Artifact Registry. Se nel tuo ambiente (ad esempio Cloud Shell) è installato Docker, puoi utilizzarlo per creare l'immagine localmente. Se lavori in un ambiente senza Docker, puoi utilizzare Cloud Build per creare l'immagine ed eseguirne il push da remoto:
Docker
Configura l'autenticazione Docker per Artifact Registry:
gcloud auth configure-docker "${LOCATION}-docker.pkg.dev"Crea ed esegui il push dell'immagine container del client in locale:
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 file denominato
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'Sostituisci i segnaposto variabile di ambiente nel file di configurazione:
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 il bucket Cloud Storage per i log di Cloud Build. Se il tuo progetto ha già utilizzato Cloud Build, questo bucket potrebbe già esistere e il comando non va a buon fine con un errore che indica che il bucket è già di tua proprietà. Puoi ignorare questo errore:
gcloud storage buckets create "gs://${CLOUDBUILD_BUCKET_NAME}" \ --location="${BUCKET_LOCATION}"Concedi le autorizzazioni necessarie al account di servizio Cloud Build.
I seguenti comandi utilizzano il account di servizio predefinito di Compute Engine (
$PROJECT_NUMBER-compute@developer.gserviceaccount.com), che è l'impostazione predefinita per la maggior parte dei progetti. Se il tuo progetto utilizza il account di servizio Cloud Build legacy, sostituisci l'indirizzo email del membro nei comandi seguenti con$PROJECT_NUMBER@cloudbuild.gserviceaccount.com.Poiché in precedenza in questo tutorial hai aggiunto un'associazione IAM condizionale al tuo progetto, devi includere il flag
--condition=Nonequando aggiungi queste nuove associazioni. In questo modo,gcloudnon si interrompe per chiedere una conferma interattiva: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"Esegui la build utilizzando Cloud Build:
gcloud builds submit --config cloudbuild.yaml
Esegui il test
Esegui il deployment dell'applicazione client per creare la sandbox, attivare uno snapshot e verificare che il contatore interno riprenda correttamente dallo stato salvato.
Crea un file denominato
client_sa.yaml. Questo manifest definisce il account di servizioagent-sandbox-client-sae le autorizzazioni RBAC richieste per la gestione delle risorse personalizzate della 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.ioApplica il account di servizio client e il manifest RBAC:
kubectl apply -f client_sa.yamlCrea un file denominato
client_pod.yaml. Questo manifest crea il pod dell'applicazione client utilizzando l'immagine container predefinita: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: NeverSostituisci i segnaposto variabile di ambiente nel manifest:
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.yamlAttendi che la sandbox del pool caldo sia pronta:
kubectl wait sandboxwarmpool python-counter-pool \ --for=jsonpath='{.status.readyReplicas}'=1 \ --timeout=600sNel passaggio successivo, l'applicazione client crea una risorsa
SandboxClaim. Se l'applicazione crea la richiesta prima che la sandbox del pool sia pronta, il controller potrebbe creare una nuova sandbox per la richiesta anziché assegnare quella del pool. In un cluster Autopilot, la sandbox può richiedere diversi minuti per essere pronta perché GKE potrebbe dover creare un nodo.Applica il manifest del pod dell'applicazione client:
kubectl apply -f client_pod.yamlTrasmetti in streaming i log del pod per verificare il flusso di esecuzione:
kubectl logs -f agent-sandbox-client-pod
Quando il test viene eseguito correttamente, l'output è simile al seguente (abbreviato qui per leggibilità):
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).
L'output mostra che la sandbox conserva correttamente il suo stato quando viene sospesa e ripresa. Il contatore smette di avanzare mentre la sandbox è sospesa, perché il controller di Agent Sandbox elimina il pod della sandbox. Quando la sandbox riprende, il controller ricrea il pod, che viene ripristinato dallo snapshot, e il contatore continua. Senza la sospensione, il contatore avrebbe continuato ad avanzare durante il periodo di sospensione e il conteggio sarebbe stato significativamente più alto.
Esegui la pulizia delle risorse
Per evitare che al tuo account Google Cloud vengano addebitati costi, elimina le risorse che hai creato:
Elimina il cluster GKE. In questo modo vengono eliminati anche il pool di nodi e tutti i service account Kubernetes al suo interno:
Autopilot
gcloud container clusters delete ${CLUSTER_NAME} \ --location="${LOCATION}" --quietStandard
gcloud container clusters delete ${CLUSTER_NAME} \ --location="${ZONE}" --quietElimina il repository Artifact Registry per rimuovere il repository Docker che hai creato per l'immagine di test:
gcloud artifacts repositories delete ${REPOSITORY_NAME} --location="${LOCATION}" --quietElimina il bucket Cloud Storage e tutti gli snapshot al suo interno. In questo modo, le associazioni IAM di Workload Identity a livello di bucket applicate vengono rimosse automaticamente:
gcloud storage rm --recursive "gs://${BUCKET_NAME}"Rimuovi l'associazione IAM a livello di progetto per l'agente di servizio 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 hai utilizzato Cloud Build anziché Docker per creare ed eseguire il push dell'immagine container, esegui la pulizia delle risorse di Cloud Build. Elimina solo le risorse che hai creato per questo tutorial, perché altri workload nel tuo progetto potrebbero dipendere da risorse esistenti in precedenza:
Se il bucket Cloud Build non esisteva prima di iniziare questo tutorial, eliminalo:
gcloud storage rm --recursive "gs://${CLOUDBUILD_BUCKET_NAME}"Se il account di servizio predefinito di Compute Engine non disponeva dei ruoli
roles/artifactregistry.writereroles/logging.logWriterprima di iniziare questo tutorial, rimuovili: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
Passaggi successivi
- Scopri come isolare l'esecuzione di codice AI con Agent Sandbox su GKE.
- Scopri come salvare e ripristinare Agent Sandbox negli ambienti GKE.
- Per comprendere i livelli di isolamento che proteggono i workload non attendibili, consulta GKE Sandbox.
- Esplora il progetto Agent Sandbox open source su GitHub.
- Scopri come utilizzare Kata Containers open source con Agent Sandbox su GKE. Kata Containers non è un prodotto Google Cloud . Se installi e utilizzi questo software, sei responsabile della gestione e della risoluzione dei problemi. L'assistenza e gli SLA di Google non si applicano a Kata Containers.