Isolar a execução de código de IA com o sandbox do agente

Este documento fornece instruções para implantar um ambiente de desenvolvimento e usar o cliente Python do Agent Sandbox em um cluster do Google Kubernetes Engine (GKE).

Para uma visão geral de como o recurso Agent Sandbox isola código gerado por IA não confiável, consulte Sobre o GKE Agent Sandbox.

Custos

O Agent Sandbox é oferecido sem custo adicional no GKE. Os preços do GKE são aplicados aos recursos que você cria.

Antes de começar

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

    Funções necessárias para selecionar ou criar um projeto

    • Selecionar um projeto: não é necessário um papel específico do IAM para selecionar um projeto. Você pode escolher qualquer projeto em que 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 permissão resourcemanager.projects.create. Saiba como conceder papéis.

    Acessar o seletor de projetos

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

  3. Ative as APIs Artifact Registry e Kubernetes Engine.

    Funções necessárias para ativar APIs

    Para ativar as APIs, é necessário ter o papel do IAM de administrador de uso do serviço (roles/serviceusage.serviceUsageAdmin), que contém a permissão serviceusage.services.enable. Saiba como conceder papéis.

    Ativar as APIs

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

    Ativar o Cloud Shell

  5. Verifique se você tem as permissões necessárias para concluir este guia.
  6. Você precisa ter um cluster do GKE com o recurso Agent Sandbox ativado. Se você não tiver um, siga as instruções em Ativar o ambiente de simulação do agente no GKE para criar ou atualizar um cluster.

Funções exigidas

Para receber as permissões necessárias para criar e gerenciar sandboxes, peça ao administrador para conceder a você o papel do IAM de Administrador do Kubernetes Engine (roles/container.admin) no seu projeto. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias usando papéis personalizados ou outros papéis predefinidos.

Definir variáveis de ambiente

Para simplificar os comandos executados neste documento, defina variáveis de ambiente no Cloud Shell. No Cloud Shell, defina as seguintes variáveis de ambiente úteis executando os comandos abaixo:

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

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

  • PROJECT_ID: o ID do seu projeto Google Cloud atual. Definir essa variável ajuda a garantir que todos os recursos, como seu 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 está localizado. Defina como a região (por exemplo, us-central1) se você estiver usando um cluster do Autopilot ou a zona (por exemplo, us-central1-a) se estiver usando um cluster padrão.
  • NODE_POOL_NAME: o nome do pool de nós que vai executar cargas de trabalho em sandbox, por exemplo, agent-sandbox-node-pool.
  • MACHINE_TYPE: o tipo de máquina dos nós no pool de nós. Por exemplo, e2-standard-2. Para 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.

Implantar um ambiente em sandbox

Nesta seção, mostramos como criar o blueprint do sandbox (SandboxTemplate), implantar o roteador de rede necessário e instalar o cliente Python que você vai usar para interagir com o sandbox.

A maneira recomendada de criar e interagir com sua sandbox é usando o cliente Python da sandbox de agente. Esse cliente fornece uma interface que simplifica todo o ciclo de vida de um sandbox, desde a criação até a limpeza. É uma biblioteca Python que pode ser usada para criar, usar e excluir sandboxes de forma programática.

O cliente usa um roteador de sandbox como ponto de entrada central para todo o tráfego. No exemplo descrito neste documento, o cliente cria um túnel para esse roteador usando o comando kubectl port-forward para que você não precise expor nenhum endereço IP público. O uso de kubectl port-forward não é uma solução segura e deve ser limitado a ambientes de desenvolvimento.

Criar um SandboxTemplate e um SandboxWarmPool

Agora, defina a configuração da sua sandbox criando um recurso SandboxTemplate e um SandboxWarmPool. O SandboxTemplate funciona como um blueprint reutilizável que o controlador do sandbox do agente usa para criar ambientes de sandbox consistentes e pré-configurados. O recurso SandboxWarmPool ajuda a garantir que um número especificado de pods pré-aquecidos esteja sempre em execução e pronto para ser reivindicado. Um sandbox pré-aquecido é um pod em execução que já foi inicializado. Essa pré-inicialização permite que novos sandboxes sejam criados em menos de um segundo e evita a latência de inicialização de um sandbox comum:

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

    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxTemplate
    metadata:
      name: python-runtime-template
      namespace: default
    spec:
      podTemplate:
        metadata:
          labels:
            sandbox: python-sandbox-example
        spec:
          runtimeClassName: gvisor
          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: python-runtime
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            readinessProbe:
              httpGet:
                path: "/"
                port: 8888
              initialDelaySeconds: 0
              periodSeconds: 1
            resources:
              requests:
                cpu: "250m"
                memory: "512Mi"
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
          restartPolicy: "OnFailure"
    ---
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxWarmPool
    metadata:
      name: python-sandbox-warmpool
      namespace: default
    spec:
      replicas: 2
      sandboxTemplateRef:
        name: python-runtime-template
    
  2. Aplique os manifestos SandboxTemplate e SandboxWarmPool:

    kubectl apply -f sandbox-template-and-pool.yaml
    

Implante o roteador do sandbox

O cliente Python que você vai usar para criar e interagir com ambientes em sandbox usa um componente chamado roteador de sandbox para se comunicar com os sandboxes.

Neste exemplo, você vai usar o modo de desenvolvedor do cliente para testes. Esse modo é destinado ao desenvolvimento local e usa o comando kubectl port-forward para estabelecer um túnel direto da máquina local para o serviço Sandbox Router em execução no cluster. Essa abordagem de tunelamento evita a necessidade de um endereço IP público ou uma configuração de entrada complexa e simplifica a interação com sandboxes do seu ambiente local.

Siga estas etapas para implantar o roteador de sandbox:

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

    # A ClusterIP Service to provide a stable endpoint for the router pods.
    apiVersion: v1
    kind: Service
    metadata:
      name: sandbox-router-svc
      namespace: default
    spec:
      type: ClusterIP
      selector:
        app: sandbox-router
      ports:
      - name: http
        protocol: TCP
        port: 8080 # The port the service will listen on
        targetPort: 8080 # The port the router container listens on (from the sandbox_router/Dockerfile)
    ---
    # The Deployment to manage and run the router pods.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sandbox-router-deployment
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sandbox-router
      template:
        metadata:
          labels:
            app: sandbox-router
        spec:
          # Ensure pods are spread across different zones for HA
          topologySpreadConstraints:
            - maxSkew: 1
              topologyKey: topology.kubernetes.io/zone
              whenUnsatisfiable: ScheduleAnyway
              labelSelector:
                matchLabels:
                  app: sandbox-router
          containers:
          - name: router
            image: us-central1-docker.pkg.dev/k8s-staging-images/agent-sandbox/sandbox-router:latest-main
            ports:
            - containerPort: 8080
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8080
              initialDelaySeconds: 5
              periodSeconds: 5
            livenessProbe:
              httpGet:
                path: /healthz
                port: 8080
              initialDelaySeconds: 10
              periodSeconds: 10
            resources:
              requests:
                cpu: "100m"
                memory: "512Mi"
              limits:
                cpu: "1000m"
                memory: "1Gi"
          securityContext:
            runAsUser: 1000
            runAsGroup: 1000
    
  2. Aplique o manifesto para implantar o roteador no cluster:

    kubectl apply -f sandbox-router.yaml
    
  3. Verifique se a implantação do roteador do sandbox está sendo executada corretamente:

    kubectl get deployment sandbox-router-deployment
    

    Aguarde até que a implantação mostre 2/2 ou 1/1 na coluna READY.

Instalar o cliente Python

Agora que os componentes no cluster, como o roteador do Sandbox, estão implantados, a etapa preparatória final é instalar o cliente Python do Sandbox de agente na sua máquina local. Lembre-se de que esse cliente é uma biblioteca Python que permite criar, usar e excluir sandboxes de maneira programática. Você vai usá-lo na próxima seção para testar o ambiente:

  1. Crie e ative um ambiente virtual Python:

    python3 -m venv .venv
    source .venv/bin/activate
    
  2. Instale o pacote do cliente:

    pip install k8s-agent-sandbox
    

Testar o sandbox

Com todos os componentes de configuração no lugar, agora você pode criar e interagir com um sandbox usando o cliente Python do sandbox de agente.

  1. No diretório agent-sandbox, crie um script Python chamado test_sandbox.py com o seguinte conteúdo:

    from k8s_agent_sandbox import SandboxClient
    from k8s_agent_sandbox.models import SandboxLocalTunnelConnectionConfig
    
    # Automatically tunnels to svc/sandbox-router-svc
    client = SandboxClient(
        connection_config=SandboxLocalTunnelConnectionConfig()
    )
    
    sandbox = client.create_sandbox(template="python-runtime-template", namespace="default")
    try:
        print(sandbox.commands.run("echo 'Hello from the sandboxed environment!'").stdout)
    except Exception as e:
        print(f"An error occurred: {e}")
    
  2. No terminal (com o ambiente virtual ainda ativo), execute o script de teste:

    python3 test_sandbox.py
    

Você vai ver a mensagem "Hello from the sandboxed environment!", que é a saída da sandbox.

Parabéns! Você executou um comando shell em um sandbox seguro. Usando o método sandbox.run(), é possível executar qualquer comando do shell, e o sandbox do agente executa o comando em uma barreira segura que protege os nós do cluster e outras cargas de trabalho contra código não confiável. Isso oferece uma maneira segura e confiável para um agente de IA ou qualquer fluxo de trabalho automatizado executar tarefas.

Quando você executa o script, o SandboxClient processa todas as etapas. Ele cria o recurso SandboxClaim para iniciar o sandbox, aguarda que ele fique pronto e usa o método sandbox.run() para executar comandos do shell bash dentro do contêiner seguro. Em seguida, o cliente captura e imprime o stdout desse comando. A sandbox é excluída automaticamente após a execução do programa.

Quando um recurso SandboxClaim é criado, um pod disponível é atribuído do pool quente ao objeto Sandbox, e a solicitação é marcada como pronta. O SandboxWarmPool é reabastecido automaticamente para manter o número configurado de réplicas.

Para verificar se uma sandbox específica foi reivindicada ou está disponível, confira o ownerReferences nos metadados do pod da sandbox. Se o valor do campo kind for Sandbox, o pod estará em uso. Se o valor do campo kind for SandboxWarmPool, o pod estará inativo e aguardando reivindicação.

Executar sandboxes em produção

Neste documento, você interage com os sandbox de fora do cluster usando o Cloud Shell. O cliente Python usa suas credenciais de usuário para autenticar no cluster e gerenciar recursos de sandbox, além de usar o comando kubectl port-forward para estabelecer uma conexão com os sandboxes. Essas etapas funcionam bem para cenários de desenvolvimento.

Em um cenário de produção, um aplicativo controlador (como um orquestrador de IA) é responsável por criar e gerenciar recursos de sandbox. Para usar o sandbox do agente em produção, considere o seguinte:

  • Autenticação: seu aplicativo de controlador precisa se autenticar no servidor da API do cluster para executar sandboxes. A configuração da autenticação depende de onde o aplicativo controlador é executado, da seguinte maneira:

  • Roteamento: as solicitações do cliente Python no aplicativo controlador precisam chegar ao roteador da caixa de areia no cluster. Em produção, use um dos seguintes métodos para estabelecer uma conexão de rede:

    • Se o aplicativo controlador for executado no mesmo cluster, use a função SandboxDirectConnectionConfig para segmentar o URL e a porta que o serviço do roteador da caixa de simulação usa.
    • Se o aplicativo controlador for executado fora do cluster, use a API Gateway do GKE para criar um balanceador de carga interno ou externo. No código do cliente, use a função SandboxGatewayConnectionConfig para referenciar o gateway.

    Para mais informações sobre esses métodos de roteamento, consulte os exemplos de uso no GitHub e as etapas de implantação do gateway para o roteador.

  • Acesso do sandbox a recursos do Google Cloud : se o código do sandbox precisar enviar solicitações para APIs do Google Cloud , como o Cloud Storage, use uma política do IAM com a federação de identidade da carga de trabalho para GKE para dar à ServiceAccount do Kubernetes que o pod do sandbox usa as permissões necessárias para esse acesso.

Limpar recursos

Para evitar cobranças na sua conta do Google Cloud , exclua o cluster do GKE que você criou:

gcloud container clusters delete $CLUSTER_NAME --location=$LOCATION --quiet

A seguir