Abilita Agent Sandbox su GKE

Questo documento spiega come abilitare la sandbox dell'agente su Google Kubernetes Engine (GKE) in un cluster. Spiega anche come creare un ambiente in sandbox sul cluster per eseguire in sicurezza codice non attendibile.

Per una panoramica di come la sandbox dell'agente su GKE isola il codice non attendibile generato con l'AI, consulta Informazioni sulla sandbox dell'agente su GKE.

Costi

La sandbox dell'agente su GKE è offerta senza costi aggiuntivi. I prezzi di GKE si applicano alle risorse che crei.

Per evitare addebiti non necessari, assicurati di disabilitare GKE o eliminare il progetto dopo aver completato questo documento.

Prima di iniziare

  1. Nella Google Cloud console, nella pagina di selezione del progetto, seleziona o crea un Google Cloud progetto.

    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 su cui ti è stato concesso un ruolo.
    • Crea un progetto: per creare un progetto, devi avere il ruolo Autore progetto (roles/resourcemanager.projectCreator), che contiene l' resourcemanager.projects.create autorizzazione. Scopri come concedere i ruoli.

    Vai al selettore di progetti

  2. Verifica che la fatturazione sia attivata per il tuo Google Cloud progetto.

  3. Abilita le API Artifact Registry e Google Kubernetes Engine, se non sono già abilitate.

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi avere l'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 utilizzo servizi (roles/serviceusage.serviceUsageAdmin). Scopri come concedere i ruoli.

    Abilita le API

  4. Nella Google Cloud console, attiva Cloud Shell.

    Attiva Cloud Shell

  5. Assicurati che il cluster esegua GKE versione 1.36.3-gke.1767000 o successive (supporta l'API v1beta1).

Definisci le variabili di ambiente

Per semplificare i comandi che esegui in questo documento, puoi impostare le variabili di ambiente in Cloud Shell. In Cloud Shell, definisci le seguenti variabili di ambiente utili eseguendo i seguenti comandi:

export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export LOCATION="us-central1"
export CLUSTER_VERSION="1.36.3-gke.1767000"
export NODE_POOL_NAME="agent-sandbox-pool"
export MACHINE_TYPE="e2-standard-2"

Ecco una spiegazione di queste variabili di ambiente:

  • PROJECT_ID: l'ID del tuo Google Cloud progetto corrente. La definizione di questa variabile consente di assicurarti che tutte le risorse, come il cluster GKE, vengano create nel progetto corretto.
  • CLUSTER_NAME: il nome del cluster GKE, ad esempio agent-sandbox-cluster.
  • LOCATION: la Google Cloud regione o la zona in cui viene creato il cluster GKE. Imposta questa opzione sulla regione (ad esempio, us-central1) se crei un cluster Autopilot o sulla zona (ad esempio, us-central1-a) se crei un cluster Standard.
  • CLUSTER_VERSION: la versione di GKE che verrà eseguita dal cluster (1.36.3-gke.1767000 o versioni successive).
  • NODE_POOL_NAME: il nome del pool di nodi che eseguirà i workload in sandbox, ad esempio agent-sandbox-pool. Questa variabile è obbligatoria solo se crei un cluster GKE Standard.
  • MACHINE_TYPE: il tipo di macchina dei nodi nel pool di nodi, ad esempio e2-standard-2. Per informazioni dettagliate sulle diverse serie di macchine e sulla scelta tra le diverse opzioni, consulta la guida alle risorse e al confronto per le famiglie di macchine. Questa variabile è obbligatoria solo se crei un cluster GKE Standard.

Abilita la sandbox dell'agente su GKE

Puoi abilitare la sandbox dell'agente su GKE quando crei un nuovo cluster o quando aggiorni un cluster esistente.

Abilita la sandbox dell'agente su GKE durante la creazione di un nuovo cluster

Ti consigliamo di utilizzare un cluster Autopilot per un'esperienza Kubernetes completamente gestita. Per scegliere la modalità operativa GKE più adatta ai tuoi workload, consulta Scegli una modalità operativa GKE.

Autopilot

Per creare un nuovo cluster GKE Autopilot con la sandbox dell'agente su GKE abilitata, includi il flag --enable-agent-sandbox:

gcloud beta container clusters create-auto ${CLUSTER_NAME} \
    --location=${LOCATION} \
    --cluster-version=${CLUSTER_VERSION} \
    --enable-agent-sandbox

Per un cluster Autopilot, assicurati che la variabile di ambiente LOCATION sia impostata su una regione (ad esempio, us-central1).

Standard

Per creare un nuovo cluster GKE Standard con la sandbox dell'agente su GKE abilitata, devi creare il cluster, aggiungere un pool di nodi con gVisor abilitato e poi abilitare la sandbox dell'agente su GKE. Per ridurre i costi, ti consigliamo di creare un cluster di zona con un singolo nodo per pool:

  1. Crea il cluster:

    gcloud beta container clusters create ${CLUSTER_NAME} \
        --location=${LOCATION} \
        --num-nodes=1 \
        --cluster-version=${CLUSTER_VERSION}
    

    Per questo cluster Standard, assicurati che la variabile di ambiente LOCATION sia impostata su una zona (ad esempio, us-central1-a).

  2. Crea un pool di nodi separato con gVisor abilitato:

    gcloud container node-pools create ${NODE_POOL_NAME} \
        --cluster=${CLUSTER_NAME} \
        --machine-type=${MACHINE_TYPE} \
        --location=${LOCATION} \
        --num-nodes=1 \
        --image-type=cos_containerd \
        --sandbox=type=gvisor
    

    La LOCATION deve essere la stessa zona utilizzata durante la creazione del cluster.

  3. Aggiorna il cluster per abilitare la sandbox dell'agente su GKE:

    gcloud beta container clusters update ${CLUSTER_NAME} \
        --location=${LOCATION} \
        --enable-agent-sandbox
    

Abilita la sandbox dell'agente su GKE durante l'aggiornamento di un cluster esistente

Per abilitare la sandbox dell'agente su GKE in un cluster esistente, il cluster deve eseguire la versione 1.36.3-gke.1767000 o successive, che supporta l'API v1beta1.

Assicurati che la variabile di ambiente LOCATION sia impostata sulla regione o sulla zona in cui si trova il cluster esistente.

  1. Se utilizzi un cluster GKE Standard, la sandbox dell'agente su GKE si basa su gVisor. Se il cluster Standard non ha un pool di nodi abilitato per gVisor, devi crearne uno prima:

    gcloud container node-pools create ${NODE_POOL_NAME} \
        --cluster=${CLUSTER_NAME} \
        --machine-type=${MACHINE_TYPE} \
        --location=${LOCATION} \
        --image-type=cos_containerd \
        --sandbox=type=gvisor
    
  2. Aggiorna il cluster per abilitare la sandbox dell'agente su GKE:

    gcloud beta container clusters update ${CLUSTER_NAME} \
        --location=${LOCATION} \
        --enable-agent-sandbox
    

Verifica la configurazione

Puoi verificare se la sandbox dell'agente su GKE è abilitata esaminando la descrizione del cluster.

gcloud beta container clusters describe ${CLUSTER_NAME} \
    --location=${LOCATION} \
    --format="value(addonsConfig.agentSandboxConfig.enabled)"

Se hai creato un cluster Autopilot, la località è la regione (ad esempio, us-central1). Se hai creato un cluster Standard, la località è la zona (ad esempio, us-central1-a).

Se la funzionalità è stata abilitata correttamente, il comando restituisce True.

Requisiti di deployment della sandbox dell'agente su GKE

Per eseguire il deployment di un workload, ad esempio Sandbox o SandboxTemplate, il manifest YAML deve includere impostazioni di sicurezza e configurazione specifiche. GKE applica questi requisiti utilizzando una policy di ammissione di convalida (VAP). Se questi requisiti non vengono soddisfatti, il controller di ammissione rifiuta il deployment.

Configurazione richiesta

Il manifest di deployment deve includere le seguenti impostazioni:

  • runtimeClassName: gvisor: garantisce che il pod venga eseguito in una sandbox gVisor.
  • automountServiceAccountToken: false: impedisce al pod di montare automaticamente il token del account di servizio predefinito.
  • securityContext.runAsNonRoot: true: garantisce che il container non venga eseguito come utente root.
  • securityContext.capabilities.drop: ["ALL"]: elimina tutte le funzionalità Linux dal container.
  • resources.limits: devi specificare i limiti di CPU e memoria per evitare potenziali scenari di denial of service (DoS).
  • nodeSelector: deve essere destinato a sandbox.gke.io/runtime: gvisor.
  • tolerations: deve includere una tolleranza per il taint sandbox.gke.io/runtime=gvisor:NoSchedule.

Configurazione non consentita

Il manifest di deployment non deve includere quanto segue:

  • hostNetwork: true, hostPID: true o hostIPC: true.
  • privileged: true nei contesti di sicurezza dei container.
  • Volumi HostPath.
  • Funzionalità aggiunte (capabilities.add).
  • Impostazioni hostPort.
  • Sysctl personalizzati.
  • Volumi proiettati per token o certificati del account di servizio.

Esegui il deployment di un ambiente in sandbox

Ti consigliamo di eseguire il deployment di un ambiente in sandbox definendo un SandboxTemplate e mantenendo le istanze preinizializzate pronte utilizzando un SandboxWarmPool. Puoi quindi richiedere un'istanza da questo pool di nodi preinizializzato utilizzando un SandboxClaim. In alternativa, puoi creare direttamente una Sandbox, ma questo approccio non supporta i pool preinizializzati.

SandboxTemplate, SandboxWarmPool, SandboxClaim e Sandbox sono risorse personalizzate di Kubernetes.

SandboxTemplate funge da progetto riutilizzabile. SandboxWarmPool consente di garantire che un numero specificato di pod preinizializzati sia sempre in esecuzione e pronto per essere richiesto. L'utilizzo di questa risorsa personalizzata riduce al minimo la latenza di avvio.

Per eseguire il deployment di un ambiente in sandbox creando SandboxTemplate e SandboxWarmPool:

  1. In Cloud Shell, crea un file denominato sandbox-template.yaml con il seguente contenuto:

    apiVersion: extensions.agents.x-k8s.io/v1beta1
    kind: SandboxTemplate
    metadata:
      name: python-runtime-template
      namespace: default
    spec:
      podTemplate:
        metadata:
          labels:
            sandbox-type: python-runtime
        spec:
          runtimeClassName: gvisor # Required
          automountServiceAccountToken: false # Required
          securityContext:
            runAsNonRoot: true # Required
          nodeSelector:
            sandbox.gke.io/runtime: gvisor # Required
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule" # Required
          containers:
          - name: runtime
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            resources:
              requests:
                cpu: "250m"
                memory: "512Mi"
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
          restartPolicy: OnFailure
    
  2. Applica il manifest SandboxTemplate:

    kubectl apply -f sandbox-template.yaml
    
  3. Crea un file denominato sandbox-warmpool.yaml con il seguente contenuto:

    apiVersion: extensions.agents.x-k8s.io/v1beta1
    kind: SandboxWarmPool
    metadata:
      name: python-runtime-warmpool
      namespace: default
      labels:
        app: python-runtime-warmpool
    spec:
      replicas: 2
      sandboxTemplateRef:
        # This must match the name of the SandboxTemplate.
        name: python-runtime-template
    
  4. Applica il manifest SandboxWarmPool:

    kubectl apply -f sandbox-warmpool.yaml
    

Crea un SandboxClaim

SandboxClaim richiede una sandbox dal pool preinizializzato. Poiché hai creato un pool preinizializzato, la sandbox creata adotta un pod in esecuzione dal pool anziché avviare un nuovo pod.

Per richiedere una sandbox dal pool preinizializzato creando un SandboxClaim:

  1. Crea un file denominato sandbox-claim.yaml con il seguente contenuto:

    apiVersion: extensions.agents.x-k8s.io/v1beta1
    kind: SandboxClaim
    metadata:
      name: sandbox-claim
      namespace: default
    spec:
      warmPoolRef:
        # This must match the name of the SandboxWarmPool.
        name: python-runtime-warmpool
    
  2. Applica il manifest SandboxClaim:

    kubectl apply -f sandbox-claim.yaml
    
  3. Verifica che la sandbox, la richiesta e il pool preinizializzato siano pronti:

    kubectl get sandboxwarmpool,sandboxclaim,sandbox,pod
    

Alternativa: crea una sandbox direttamente

Se non hai bisogno dei tempi di avvio rapidi forniti dai pool preinizializzati, puoi eseguire il deployment di una sandbox direttamente senza utilizzare i modelli.

Per eseguire il deployment di un ambiente in sandbox creando una sandbox direttamente:

  1. Crea un file denominato sandbox.yaml con il seguente contenuto:

    apiVersion: agents.x-k8s.io/v1beta1
    kind: Sandbox
    metadata:
      name: sandbox-example-2
    spec:
      replicas: 1
      podTemplate:
        metadata:
          labels:
            sandbox: sandbox-example
        spec:
          runtimeClassName: gvisor
          restartPolicy: OnFailure
          automountServiceAccountToken: false # Required
          securityContext:
            runAsNonRoot: true # Required
            runAsUser: 1000 # Required if image defaults to root (e.g. busybox)
          nodeSelector:
            sandbox.gke.io/runtime: gvisor
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule" # Required
          containers:
          - name: my-container
            image: busybox
            command: ["/bin/sh", "-c"]
            args: ["sleep 3600000; echo 'Container finished successfully'; exit 0"]
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
              allowPrivilegeEscalation: false
            resources:
              limits:
                cpu: "100m"
                memory: "128Mi" # Required
    
  2. Applica il manifest Sandbox:

    kubectl apply -f sandbox.yaml
    
  3. Verifica che la sandbox sia in esecuzione:

    kubectl get sandbox
    

Esegui la migrazione della sandbox dell'agente su GKE da v1alpha1 a v1beta1

Se il cluster è stato sottoposto a deployment con una versione precedente della sandbox dell'agente su GKE utilizzando le risorse personalizzate v1alpha1, puoi eseguire l'upgrade a GKE versione 1.36.3-gke.1767000 o successive con tempi di inattività dei workload quasi nulli.

Nota: questa procedura di migrazione si applica ai cluster che utilizzano la funzionalità gestita della sandbox dell'agente su GKE (--enable-agent-sandbox). Se hai eseguito il deployment della sandbox dell'agente utilizzando i manifest open source, consulta la guida alla migrazione upstream.

Principali differenze tra le API v1alpha1 e v1beta1

Concetto Comportamento di v1alpha1 Comportamento di v1beta1 Impatto della migrazione
Destinazioni SandboxClaim Consente il riferimento diretto a SandboxTemplate senza un pool preinizializzato (avvio a freddo). Richiede un riferimento a un SandboxWarmPool (spec.warmPoolRef.name). Le richieste di avvio a freddo devono essere mappate a un pool preinizializzato shadow (replicas: 0).
Modalità operativa della sandbox Deducibile dai campi delle repliche o dello stato. Valore esplicito per il campo spec.operatingMode (ad esempio, Running o Suspended). Il webhook di conversione mappa e imposta automaticamente questo campo.
Versione di archiviazione CustomResourceDefinition v1alpha1 archiviato in etcd (storage: true). v1beta1 archiviato in etcd (storage: true). Il webhook esegue la conversione in modo dinamico; il passaggio post-upgrade ripristina gli oggetti etcd.
Webhook di conversione Nessuno. Attivo su /convert (porta 9447). Conversione bidirezionale tra v1alpha1 e v1beta1.

Esegui la migrazione utilizzando lo strumento di migrazione

Per creare automaticamente pool preinizializzati shadow e ripristinare l'archiviazione permanente, utilizza lo script di migrazione canonico dal repository della sandbox dell'agente.

Scarica e prepara lo script:

curl -LO https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/v0.5.6/helm/files/migrate.sh
chmod +x migrate.sh

Runbook di migrazione passo passo

Per eseguire la migrazione di un cluster esistente con tempi di inattività dei workload quasi nulli, completa le seguenti tre fasi in ordine:

Fase 1: fase di bootstrap pre-upgrade

  1. Esegui il backup delle risorse esistenti: salva un backup YAML delle risorse dichiarative della sandbox dell'agente su GKE (sandboxtemplates, sandboxwarmpools e sandboxclaims):

    kubectl get sandboxtemplates,sandboxwarmpools,sandboxclaims \
        --all-namespaces -o yaml > agent-sandbox-v1alpha1-backup.yaml
    
  2. Verifica la conformità della sicurezza dei modelli: assicurati che le risorse SandboxTemplate esistenti soddisfino i requisiti di deployment della sandbox dell'agente su GKE. Durante la migrazione dell'archiviazione nella Fase 3, il controller di ammissione rifiuta gli aggiornamenti di tutti i modelli che non rispettano queste policy di sicurezza.

  3. Visualizza l'anteprima dei pool shadow da creare:

    ./migrate.sh --phase=bootstrap --dry-run
    
  4. Esegui la fase di bootstrap:

    ./migrate.sh --phase=bootstrap
    
  5. Verifica i pool shadow creati:

    kubectl get sandboxwarmpools --all-namespaces \
        -o custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,REPLICAS:.spec.replicas,SHADOW:.metadata.annotations.agents\.x-k8s\.io/migration-shadow"
    

Fase 2: esegui l'upgrade del control plane GKE

Esegui l'upgrade del control plane GKE alla versione 1.36.3-gke.1767000 o successive:

gcloud container clusters upgrade ${CLUSTER_NAME} \
    --location=${LOCATION} \
    --master \
    --cluster-version=1.36.3-gke.1767000

Durante il rollout del control plane, tieni presente quanto segue:

  • I pod non subiscono riavvii o tempi di inattività.
  • Il nuovo controller e l'endpoint webhook /convert vengono sottoposti a deployment sul control plane.

Fase 3: migrazione dell'archiviazione post-upgrade

Al termine dell'upgrade del control plane, aggiorna le credenziali e riscrivi gli oggetti etcd archiviati eseguendo la fase di migrazione dell'archiviazione:

./migrate.sh --phase=migrate

Elenco di controllo per la verifica post-migrazione

Voce di controllo Comando Risultato previsto
Versioni di archiviazione CustomResourceDefinition kubectl get crd sandboxes.agents.x-k8s.io sandboxclaims.extensions.agents.x-k8s.io sandboxtemplates.extensions.agents.x-k8s.io sandboxwarmpools.extensions.agents.x-k8s.io -o jsonpath='{range .items[*]}{.metadata.name}{": storedVersions="}{.status.storedVersions}{"\n"}{end}' Tutte e 4 le CustomResourceDefinition mostrano:
storedVersions=["v1beta1"]
Continuità dei pod kubectl get pods -n default -o wide Status: 1/1 Running
Restarts: 0
(si applica ai cluster con sandbox attive in esecuzione)
Associazione delle richieste kubectl get sandboxclaims -n default -o yaml spec.warmPoolRef.name: shadow-pool-...
status.conditions: Ready=True (richiede la conformità del modello ai requisiti di ammissione)
Compatibilità con v1alpha1 kubectl get sandboxes.v1alpha1.agents.x-k8s.io Visualizza l'avviso di ritiro e restituisce la risorsa
CRUD nativo v1beta1 kubectl apply -f sandbox-claim.yaml Si applica con 0 avvisi

Se una CustomResourceDefinition continua a elencare ["v1alpha1", "v1beta1"] in .status.storedVersions al termine della fase di migrazione, questo è il comportamento previsto di Kubernetes. Lo script di migrazione riscrive tutti i record esistenti in v1beta1 in etcd, ma Kubernetes non rimuove automaticamente le versioni ritirate dall'elenco status.storedVersions.

Dopo aver verificato che tutte le risorse siano state sottoposte a migrazione, puoi facoltativamente eliminare v1alpha1 dalle versioni archiviate:

for crd in \
    sandboxes.agents.x-k8s.io \
    sandboxclaims.extensions.agents.x-k8s.io \
    sandboxtemplates.extensions.agents.x-k8s.io \
    sandboxwarmpools.extensions.agents.x-k8s.io; do
  kubectl patch crd "${crd}" --subresource=status --type=merge \
    -p '{"status":{"storedVersions":["v1beta1"]}}'
done

Risolvi i problemi di migrazione

Se riscontri problemi dopo l'upgrade del control plane o l'esecuzione della migrazione dell'archiviazione, risolvili in avanti anziché tentare di eseguire il downgrade del control plane:

  • Richiesta bloccata in WarmPoolNotFound:

    • Se è stata eseguita l'upgrade di una richiesta v1alpha1 di avvio a freddo senza eseguire ./migrate.sh --phase=bootstrap, crea manualmente il pool preinizializzato shadow mancante:

      apiVersion: extensions.agents.x-k8s.io/v1beta1
      kind: SandboxWarmPool
      metadata:
        name: shadow-pool-TEMPLATE_NAME
        namespace: NAMESPACE
        annotations:
          agents.x-k8s.io/migration-shadow: "true"
      spec:
        replicas: 0
        sandboxTemplateRef:
          name: TEMPLATE_NAME
      
    • Se una richiesta ha denominato un pool preinizializzato specifico che non esiste più, crea la risorsa SandboxWarmPool mancante con quel nome oppure aggiorna spec.warmPoolRef.name nella richiesta in modo che faccia riferimento a un pool preinizializzato esistente.

  • Condizione della richiesta Ready=False: esegui kubectl describe sandboxclaim per esaminare gli eventi nella richiesta. Assicurati che il SandboxTemplate a cui viene fatto riferimento soddisfi tutti i requisiti di deployment della sandbox dell'agente su GKE e riapplica il modello, se necessario.

  • Errori di conversione o del controller: verifica che il lease di elezione del leader del control plane sia attivo eseguendo kubectl get leases -n gke-managed-agentsandbox. Se i problemi persistono, contatta l'assistenza clienti Google Cloud.

Disabilita la sandbox dell'agente su GKE

Per disabilitare la sandbox dell'agente su GKE, utilizza il comando gcloud beta container clusters update con il flag --no-enable-agent-sandbox.

gcloud beta container clusters update ${CLUSTER_NAME} \
    --location=${LOCATION} \
    --no-enable-agent-sandbox

Se hai creato un cluster Autopilot, la località è la regione (ad esempio, us-central1). Se hai creato un cluster Standard, la località è la zona (ad esempio, us-central1-a).

Esegui la pulizia delle risorse

Per evitare che al tuo Google Cloud account vengano addebitati costi, elimina il cluster GKE che hai creato.

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

Se hai creato un cluster Autopilot, la località è la regione (ad esempio, us-central1). Se hai creato un cluster Standard, la località è la zona (ad esempio, us-central1-a).

Passaggi successivi