Ativar o Agent Sandbox no GKE

Este documento explica como ativar o sandbox de agentes no Google Kubernetes Engine (GKE) em um cluster. Ele também explica como criar um ambiente em sandbox no cluster para executar com segurança códigos não confiáveis.

Para uma visão geral de como o sandbox de agentes no GKE isola códigos gerados com IA não confiáveis, consulte Sobre o sandbox de agentes no GKE.

Custos

O sandbox de agentes no GKE é oferecido sem custo financeiro adicional. Os preços do GKE se aplicam aos recursos criados.

Para evitar cobranças desnecessárias, desative o GKE ou exclua o projeto depois de concluir este documento.

Antes de começar

  1. No Google Cloud console do, na página do seletor de projetos, escolha ou crie um Google Cloud projeto do.

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

    • Selecionar um projeto: a seleção de um projeto não exige um papel específico do IAM. É possível selecionar qualquer projeto em que você tenha recebido um papel.
    • Criar um projeto: para criar um projeto, é necessário ter o papel de criador de projetos (roles/resourcemanager.projectCreator), que contém a resourcemanager.projects.create permissão. Saiba como conceder papéis.

    Acessar o seletor de projetos

  2. Verifique se o faturamento está ativado para o Google Cloud projeto.

  3. Ative as APIs Artifact Registry e Google Kubernetes Engine, se alguma delas ainda não estiver ativada.

    Funções necessárias para ativar APIs

    Para ativar as APIs, é necessário ter a 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 receber essa permissão pelo papel de administrador de uso do serviço (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.

    Ativar as APIs

  4. No Google Cloud console do, ative o Cloud Shell.

    Ativar o Cloud Shell

  5. Verifique se o cluster está executando o GKE versão 1.36.3-gke.1767000 ou mais recente (com suporte à API v1beta1).

Definir as variáveis de ambiente

Para simplificar os comandos executados neste documento, é possível definir variáveis de ambiente no Cloud Shell. No Cloud Shell, defina as seguintes variáveis de ambiente úteis executando os comandos a seguir:

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"

Confira uma explicação dessas variáveis de ambiente:

  • PROJECT_ID: o ID do seu Google Cloud projeto atual. A definição dessa variável ajuda a garantir que todos os recursos, como o cluster do GKE, sejam criados no projeto correto.
  • CLUSTER_NAME: o nome do cluster do GKE, por exemplo, agent-sandbox-cluster.
  • LOCATION: a Google Cloud região ou zona em que o cluster do GKE é criado. Defina isso como a região (por exemplo, us-central1) se você criar um cluster do Autopilot ou a zona (por exemplo, us-central1-a) se criar um cluster padrão.
  • CLUSTER_VERSION: a versão do GKE que o cluster vai executar (1.36.3-gke.1767000 ou mais recente).
  • NODE_POOL_NAME: o nome do pool de nós que vai executar cargas de trabalho em sandbox, por exemplo, agent-sandbox-pool. Essa variável só é necessária se você estiver criando um cluster GKE Standard.
  • MACHINE_TYPE: o tipo de máquina dos nós no pool de nós, por exemplo, e2-standard-2. Para mais detalhes sobre diferentes séries de máquinas e como escolher entre diferentes opções, consulte o Guia de comparação e recursos para famílias de máquinas. Essa variável só é necessária se você estiver criando um cluster padrão do GKE.

Ativar o sandbox de agentes no GKE

É possível ativar o sandbox de agentes no GKE ao criar um novo cluster ou ao atualizar um cluster atual.

Ativar o sandbox de agentes no GKE ao criar um novo cluster

Recomendamos que você use um cluster do Autopilot para ter uma experiência totalmente gerenciada do Kubernetes. Para escolher o modo de operação do GKE mais adequado para suas cargas de trabalho, consulte Escolher um modo de operação do GKE.

Autopilot

Para criar um novo cluster do GKE Autopilot com o sandbox de agentes no GKE ativado, inclua a flag --enable-agent-sandbox:

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

Para um cluster do Autopilot, verifique se a variável de ambiente LOCATION está definida como uma região (por exemplo, us-central1).

Padrão

Para criar um novo cluster GKE Standard com o sandbox de agentes no GKE ativado, é necessário criar o cluster, adicionar um pool de nós com o gVisor ativado e, em seguida, ativar o sandbox de agentes no GKE. Para economizar custos, recomendamos criar um cluster zonal com um único nó por pool:

  1. Crie o cluster:

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

    Para esse cluster padrão, verifique se a variável de ambiente LOCATION está definida como uma zona (por exemplo, us-central1-a).

  2. Crie um pool de nós separado com o gVisor ativado:

    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
    

    O LOCATION precisa ser a mesma zona usada ao criar o cluster.

  3. Atualize o cluster para ativar o sandbox de agentes no GKE:

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

Ativar o sandbox de agentes no GKE ao atualizar um cluster atual

Para ativar o sandbox de agentes no GKE em um cluster atual, o cluster precisa estar executando a versão 1.36.3-gke.1767000 ou mais recente, que oferece suporte à API v1beta1.

Verifique se a variável de ambiente LOCATION está definida como a região ou zona em que o cluster atual está localizado.

  1. Se você estiver usando um cluster GKE Standard, o sandbox de agentes no GKE vai depender do gVisor. Se o cluster padrão não tiver um pool de nós ativado pelo gVisor, será necessário criar um primeiro:

    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. Atualize o cluster para ativar o sandbox de agentes no GKE:

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

Verificar a configuração

É possível verificar se o sandbox de agentes no GKE está ativado inspecionando a descrição do cluster.

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

Se você criou um cluster do Autopilot, o local é a região (por exemplo, us-central1). Se você criou um cluster padrão, o local é a zona (por exemplo, us-central1-a).

Se o recurso for ativado, o comando vai retornar True.

Requisitos de implantação do sandbox de agentes no GKE

Para implantar uma carga de trabalho, como um Sandbox ou SandboxTemplate, o manifesto YAML precisa incluir configurações específicas de segurança e configuração. O GKE aplica esses requisitos usando uma política de admissão de validação (VAP, na sigla em inglês). Se esses requisitos não forem atendidos, o controlador de admissão vai rejeitar a implantação.

Configuração necessária

O manifesto de implantação precisa incluir as seguintes configurações:

  • runtimeClassName: gvisor: garante que o pod seja executado em um sandbox do gVisor.
  • automountServiceAccountToken: false: impede que o pod monte automaticamente o token da conta de serviço padrão.
  • securityContext.runAsNonRoot: true: garante que o contêiner não seja executado como o usuário raiz.
  • securityContext.capabilities.drop: ["ALL"]: descarta todos os recursos do Linux do contêiner.
  • resources.limits: é necessário especificar limites de CPU e memória para evitar possíveis cenários de negação de serviço (DoS).
  • nodeSelector: precisa segmentar sandbox.gke.io/runtime: gvisor.
  • tolerations: precisa incluir uma tolerância para a taint sandbox.gke.io/runtime=gvisor:NoSchedule.

Configuração proibida

O manifesto de implantação não pode incluir nenhum dos seguintes:

  • hostNetwork: true, hostPID: true ou hostIPC: true.
  • privileged: true em contextos de segurança de contêiner.
  • Volumes HostPath.
  • Recursos adicionados (capabilities.add).
  • Configurações hostPort.
  • Sysctls personalizados.
  • Volumes projetados para tokens ou certificados de conta de serviço.

Implantar um ambiente em sandbox

Recomendamos implantar um ambiente em sandbox definindo um SandboxTemplate e mantendo instâncias pré-aquecidas prontas usando um SandboxWarmPool. Em seguida, é possível solicitar uma instância desse pool de nós ativos usando um SandboxClaim. Como alternativa, é possível criar um sandbox diretamente, mas essa abordagem não oferece suporte a pools ativos.

SandboxTemplate, SandboxWarmPool, SandboxClaim e Sandbox são recursos personalizados do Kubernetes.

O SandboxTemplate funciona como um blueprint reutilizável. O SandboxWarmPool ajuda a garantir que um número especificado de pods pré-aquecidos esteja sempre em execução e pronto para ser reivindicado. O uso desse recurso personalizado minimiza a latência de inicialização.

Para implantar um ambiente em sandbox criando o SandboxTemplate e o SandboxWarmPool, siga estas etapas:

  1. No Cloud Shell, crie um arquivo chamado sandbox-template.yaml com o seguinte conteúdo:

    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. Aplique o manifesto SandboxTemplate:

    kubectl apply -f sandbox-template.yaml
    
  3. Crie um arquivo chamado sandbox-warmpool.yaml com o seguinte conteúdo:

    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. Aplique o manifesto SandboxWarmPool:

    kubectl apply -f sandbox-warmpool.yaml
    

Criar um SandboxClaim

O SandboxClaim solicita um sandbox do pool ativo. Como você criou um pool ativo, o sandbox criado adota um pod em execução do pool em vez de iniciar um novo pod.

Para solicitar um sandbox do pool ativo criando um SandboxClaim, siga estas etapas:

  1. Crie um arquivo chamado sandbox-claim.yaml com o seguinte conteúdo:

    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. Aplique o manifesto SandboxClaim:

    kubectl apply -f sandbox-claim.yaml
    
  3. Verifique se o sandbox, a reivindicação e o pool ativo estão prontos:

    kubectl get sandboxwarmpool,sandboxclaim,sandbox,pod
    

Alternativa: criar um sandbox diretamente

Se você não precisar dos tempos de inicialização rápidos fornecidos por pools ativos, poderá implantar um sandbox diretamente sem usar modelos.

Para implantar um ambiente em sandbox criando um sandbox diretamente, siga estas etapas:

  1. Crie um arquivo chamado sandbox.yaml com o seguinte conteúdo:

    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. Aplique o manifesto Sandbox:

    kubectl apply -f sandbox.yaml
    
  3. Verifique se o sandbox está em execução:

    kubectl get sandbox
    

Migrar o sandbox de agentes no GKE da v1alpha1 para a v1beta1

Se o cluster foi implantado com uma versão anterior do sandbox de agentes no GKE usando recursos personalizados v1alpha1, é possível fazer upgrade para o GKE versão 1.36.3-gke.1767000 ou mais recente com tempo de inatividade da carga de trabalho quase zero.

Observação: esse procedimento de migração se aplica a clusters que usam o recurso gerenciado do sandbox de agentes no GKE (--enable-agent-sandbox). Se você implantou o sandbox de agentes usando manifestos de código aberto, consulte o guia de migração upstream.

Principais diferenças de API entre v1alpha1 e v1beta1

Conceito Comportamento da v1alpha1 Comportamento da v1beta1 Impacto da migração
Destinos do SandboxClaim Permite referência direta ao SandboxTemplate sem um pool ativo (inicialização a frio). Exige uma referência a um SandboxWarmPool (spec.warmPoolRef.name). As reivindicações de inicialização a frio precisam ser mapeadas para um pool ativo de sombra (replicas: 0).
Modo de operação do sandbox Inferido de réplicas ou campos de estado. Valor explícito para o campo spec.operatingMode (como Running ou Suspended). O webhook de conversão mapeia e define esse campo automaticamente.
Versão de armazenamento do CustomResourceDefinition v1alpha1 armazenada no etcd (storage: true). v1beta1 armazenada no etcd (storage: true). O webhook converte dinamicamente; a etapa pós-upgrade persiste novamente os objetos etcd.
Webhook de conversão Nenhuma. Ativo em /convert (porta 9447). Conversão bidirecional entre v1alpha1 e v1beta1.

Migrar usando a ferramenta de migração

Para criar automaticamente pools ativos de sombra e persistir novamente o armazenamento permanente, use o script de migração canônico do repositório do sandbox de agentes.

Faça o download e prepare o script:

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

Runbook de migração passo a passo

Para migrar um cluster atual com tempo de inatividade da carga de trabalho quase zero, conclua as três fases a seguir em ordem:

Fase 1: fase de inicialização pré-upgrade

  1. Faça backup dos recursos atuais:salve um backup YAML dos recursos declarativos do sandbox de agentes no GKE (sandboxtemplates, sandboxwarmpools e sandboxclaims):

    kubectl get sandboxtemplates,sandboxwarmpools,sandboxclaims \
        --all-namespaces -o yaml > agent-sandbox-v1alpha1-backup.yaml
    
  2. Verifique a conformidade de segurança do modelo: verifique se os recursos SandboxTemplate atuais atendem aos requisitos de implantação do sandbox de agentes no GKE. Durante a migração de armazenamento na Fase 3, o controlador de admissão rejeita atualizações de modelos que não estão em conformidade com essas políticas de segurança.

  3. Visualize os pools de sombra a serem criados:

    ./migrate.sh --phase=bootstrap --dry-run
    
  4. Execute a fase de inicialização:

    ./migrate.sh --phase=bootstrap
    
  5. Verifique os pools de sombra criados:

    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: fazer upgrade do plano de controle do GKE

Faça upgrade do plano de controle do GKE para a versão 1.36.3-gke.1767000 ou mais recente:

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

Durante a implantação do plano de controle, observe o seguinte:

  • Os pods não têm reinicializações ou tempo de inatividade.
  • O novo controlador e o endpoint do webhook /convert são implantados no plano de controle.

Fase 3: migração de armazenamento pós-upgrade

Depois que o upgrade do plano de controle for concluído, atualize suas credenciais e reescreva os objetos etcd armazenados executando a fase de migração de armazenamento:

./migrate.sh --phase=migrate

Lista de verificação de confirmação pós-migração

Verificar item Comando Resultado esperado
Versões de armazenamento do 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}' Todos os 4 CustomResourceDefinitions mostram:
storedVersions=["v1beta1"]
Continuidade do pod kubectl get pods -n default -o wide Status: 1/1 Running
Restarts: 0
(aplica-se a clusters com sandboxes ativos)
Vinculação de reivindicação kubectl get sandboxclaims -n default -o yaml spec.warmPoolRef.name: shadow-pool-...
status.conditions: Ready=True (exige conformidade do modelo com os requisitos de admissão)
Compatibilidade com a v1alpha1 kubectl get sandboxes.v1alpha1.agents.x-k8s.io Mostra o aviso de suspensão de uso e retorna o recurso
CRUD nativo da v1beta1 kubectl apply -f sandbox-claim.yaml Aplica com 0 avisos

Se um CustomResourceDefinition continuar listando ["v1alpha1", "v1beta1"] em .status.storedVersions após a conclusão da fase de migração, esse será o comportamento esperado do Kubernetes. O script de migração reescreve todos os registros atuais para v1beta1 no etcd, mas o Kubernetes não remove automaticamente as versões suspensas da lista status.storedVersions.

Depois de confirmar que todos os recursos foram migrados, é possível remover opcionalmente a v1alpha1 das versões armazenadas:

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

Resolver problemas de migração

Se você encontrar problemas após fazer upgrade do plano de controle ou executar a migração de armazenamento, resolva-os em vez de tentar fazer downgrade do plano de controle:

  • Reivindicação presa em WarmPoolNotFound:

    • Se uma reivindicação v1alpha1 de inicialização a frio foi atualizada sem executar ./migrate.sh --phase=bootstrap, crie o pool ativo de sombra ausente manualmente:

      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 uma reivindicação nomeou um pool ativo específico que não existe mais, crie o recurso SandboxWarmPool ausente com esse nome ou atualize spec.warmPoolRef.name na reivindicação para referenciar um pool ativo.

  • Condição de reivindicação Ready=False: execute kubectl describe sandboxclaim para inspecionar os eventos na reivindicação. Verifique se o SandboxTemplate atende a todos os requisitos de implantação do sandbox de agentes no GKE e reaplique o modelo, se necessário.

  • Erros de conversão ou controlador:verifique se o contrato de concessão de eleição do líder do plano de controle está ativo executando kubectl get leases -n gke-managed-agentsandbox. Se os problemas persistirem, entre em contato com o Cloud Customer Care.

Desativar o sandbox de agentes no GKE

Para desativar o sandbox de agentes no GKE, use o comando gcloud beta container clusters update com a flag --no-enable-agent-sandbox.

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

Se você criou um cluster do Autopilot, o local é a região (por exemplo, us-central1). Se você criou um cluster padrão, o local é a zona (por exemplo, us-central1-a).

Limpar recursos

Para evitar cobranças na sua Google Cloud conta, exclua o cluster do GKE criado.

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

Se você criou um cluster do Autopilot, o local é a região (por exemplo, us-central1). Se você criou um cluster padrão, o local é a zona (por exemplo, us-central1-a).

A seguir