Voltar para o blog

OpenKruise Agents: gerenciamento de sandboxes de agentes no Kubernetes

Uma plataforma de agentes precisa executar ferramentas sem transformar cada execução em acesso irrestrito à infraestrutura. Considere um assistente que recebe arquivos, instala dependências e executa Python: além de CPU e memória, a plataforma precisa controlar identidade, conectividade, duração da sessão e destino dos dados.

O OpenKruise Agents aborda o gerenciamento desses ambientes no Kubernetes, com recursos próprios para sandboxes e provisionamento antecipado. Seu escopo inclui ambientes de ferramentas, notebooks e workspaces; não se trata de um framework para definir o raciocínio do agente. (github.com)

Este artigo separa três assuntos que precisam ser avaliados independentemente: ciclo de vida, capacidade disponível e isolamento de segurança. O laboratório demonstra os dois primeiros; as recomendações de produção acrescentam os controles necessários ao terceiro.

O que é o OpenKruise Agents

OpenKruise Agents é um subprojeto do OpenKruise voltado à gestão de workloads de agentes. Oferece APIs Kubernetes e integração compatível com partes do protocolo E2B, além de recursos de pooling e gerenciamento de sessões. Compatibilidade de protocolo não significa implementação integral de todas as funcionalidades do serviço E2B. (github.com)

Os exemplos usam agents.kruise.io/v1alpha1. Essa API não deve ser confundida com a de projetos que também possuem um recurso chamado Sandbox, como o Kubernetes SIG Agent Sandbox. Manifestos não são intercambiáveis apenas porque os nomes dos objetos coincidem. (openkruise.io)

Escopo de versão: a documentação de instalação consultada apresenta a linha 0.6.0. Ela é a referência deste artigo, não uma promessa de compatibilidade com qualquer release posterior. Antes da implantação, confira o schema das CRDs instaladas e fixe charts e imagens aprovados. (openkruise.io)

Conceitos principais

Uma CustomResourceDefinition, ou CRD, estende a API Kubernetes. No OpenKruise Agents, os objetos centrais são:

  • Sandbox: representa uma instância e seu ciclo de vida.
  • SandboxSet: administra um conjunto de sandboxes pré-criadas.
  • SandboxClaim: solicita a alocação de uma sandbox disponível.
  • SandboxTemplate: representa uma revisão imutável de template.
  • Checkpoint: registra estado intermediário conforme as capacidades da plataforma. (openkruise.io)

Um warm pool é o estoque de ambientes preparado antes da solicitação. O ponto importante é separar estoque livre de sessões em uso: spec.replicas do SandboxSet expressa sandboxes não alocadas, incluindo as disponíveis e as que ainda estão sendo criadas. Não representa o limite global de sessões. (raw.githubusercontent.com)

O controller repõe o estoque após uma alocação. Portanto, dimensionar apenas o pool subestima a capacidade necessária quando existem muitas sessões ativas. (openkruise.io)

Arquitetura e fluxo de execução

A arquitetura distingue:

  • sandbox-controller: reconcilia os recursos e fornece admission webhooks.
  • sandbox-manager: atende a API compatível com E2B e coordena operações de gerenciamento.
  • sandbox-gateway: encaminha tráfego de acesso às sandboxes.
  • agent-runtime: fornece operações dentro da sandbox, incluindo comandos e arquivos. (openkruise.io)

Fluxo conceitual pela API Kubernetes:

Backend da plataforma → SandboxClaim → controller → Sandbox disponível → Pod

Pela integração E2B:

Aplicação → sandbox-manager → recursos Kubernetes

Cliente autorizado → sandbox-gateway → sandbox

Esses fluxos são uma síntese da arquitetura documentada, não a descrição de um único caminho de rede obrigatório. (openkruise.io)

Para produção, recomendo manter a autorização de negócio no backend: quem pode iniciar uma sessão, qual template utilizar e quais dados acessar. Não entregue permissões amplas de criação de Pods ao código executado pela sandbox.

Laboratório: pool e alocação declarativa

O exemplo a seguir é intencionalmente limitado: demonstra provisionamento, readiness e claim usando um servidor HTTP Python. Não implementa execução remota E2B e não deve receber código não confiável.

1. Preparar o controller

Em um cluster de laboratório, com Helm 3 configurado:

helm repo add openkruise https://openkruise.github.io/charts/
helm repo update
helm upgrade --install agents-sandbox-controller openkruise/agents-sandbox-controller --namespace sandbox-system --create-namespace --version 0.6.0
kubectl get crd sandboxsets.agents.kruise.io sandboxclaims.agents.kruise.io

O controller é suficiente para este exercício via CRDs. A interface E2B exige também os componentes de gerenciamento e acesso. A injeção de agent-runtime requer Kubernetes 1.29 ou superior segundo a documentação; isso é um requisito mínimo, não uma recomendação de versão operacional. (openkruise.io)

2. Criar namespace, identidade e pool

Salve como sandbox-pool.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: agent-lab
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sandbox-workload
  namespace: agent-lab
automountServiceAccountToken: false
---
apiVersion: agents.kruise.io/v1alpha1
kind: SandboxSet
metadata:
  name: python-tools
  namespace: agent-lab
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: python-tools
    spec:
      serviceAccountName: sandbox-workload
      automountServiceAccountToken: false
      securityContext:
        runAsNonRoot: true
        runAsUser: 10001
        runAsGroup: 10001
        fsGroup: 10001
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: sandbox
          image: python:3.12-slim-bookworm
          command: [python, -m, http.server, '8080', --bind, 0.0.0.0]
          workingDir: /workspace
          ports:
            - name: http
              containerPort: 8080
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop: [ALL]
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
              ephemeral-storage: 128Mi
            limits:
              cpu: '1'
              memory: 512Mi
              ephemeral-storage: 1Gi
          startupProbe:
            httpGet:
              path: /
              port: http
            periodSeconds: 2
            failureThreshold: 30
          readinessProbe:
            httpGet:
              path: /
              port: http
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /
              port: http
            periodSeconds: 10
            failureThreshold: 3
          volumeMounts:
            - name: workspace
              mountPath: /workspace
            - name: tmp
              mountPath: /tmp
      volumes:
        - name: workspace
          emptyDir:
            sizeLimit: 512Mi
        - name: tmp
          emptyDir:
            sizeLimit: 128Mi

O template descreve o Pod de cada sandbox. replicas: 2 configura o estoque inicial desejado, e o label identifica os Pods do exercício. A estrutura do SandboxSet segue o modelo documentado. (openkruise.io)

Os recursos são valores didáticos: requests participam do agendamento; limites restringem o consumo. Ajuste-os após medir inicialização e execução reais, incluindo armazenamento temporário. (kubernetes.io)

A startup probe protege a inicialização; readiness verifica disponibilidade; liveness pode reiniciar o container. Em uma sessão de agente, um reinício pode interromper trabalho: não transforme dependências externas instáveis em critérios de liveness. (kubernetes.io)

O filesystem raiz é somente leitura, enquanto /workspace e /tmp são graváveis. emptyDir não é persistência durável: seu conteúdo desaparece com a remoção do Pod. Para produção, substitua a imagem demonstrativa por uma imagem aprovada e fixada por digest, e defina explicitamente a persistência dos resultados. (kubernetes.io)

Aplique e acompanhe:

kubectl apply -f sandbox-pool.yaml
kubectl get sandboxsets.agents.kruise.io -n agent-lab
kubectl get sandboxes.agents.kruise.io -n agent-lab
kubectl get pods -n agent-lab

3. Solicitar uma sandbox

Salve como sandbox-claim.yaml:

apiVersion: agents.kruise.io/v1alpha1
kind: SandboxClaim
metadata:
  name: analysis-session-001
  namespace: agent-lab
spec:
  templateName: python-tools
  replicas: 1
  claimTimeout: 2m
  skipInitRuntime: true

templateName referencia o pool no mesmo namespace. skipInitRuntime é necessário neste exercício porque não injetamos agent-runtime. O timeout limita a tentativa de alocação, não a duração da sessão. (openkruise.io)

kubectl apply -f sandbox-claim.yaml
kubectl get sandboxclaims.agents.kruise.io -n agent-lab
kubectl get sandboxes.agents.kruise.io -n agent-lab -l agents.kruise.io/claim-name=analysis-session-001

A fase Completed indica conclusão do claim. Inspecione também a sandbox alocada. Não confunda limpeza do objeto SandboxClaim com encerramento da sessão: o ttlAfterCompleted, quando utilizado, remove o claim, não as sandboxes entregues. (openkruise.io)

4. O que muda para E2B

Uma integração funcional precisa de agent-runtime configurado por spec.runtimes, imagem compatível e conectividade interna. A injeção adiciona containers auxiliares, mounts e hooks; valide o Pod resultante, não apenas o template original. O laboratório anterior não deve ser convertido em produção apenas removendo skipInitRuntime. (openkruise.io)

Além disso, run_code exige um ambiente de code interpreter apropriado. Domínio, certificados, autenticação e compatibilidade do SDK devem ser testados como parte da integração, não presumidos pela existência de um Pod saudável. (openkruise.io)

Segurança: sandbox não é sinônimo de fronteira forte

Namespaces e containers não equivalem automaticamente a isolamento adequado para código hostil. Avalie runtimes com isolamento adicional, nós dedicados ou clusters separados conforme o modelo de ameaça. A escolha deve considerar escape de container, acesso lateral e exposição do host. (kubernetes.io)

Como política de produção, recomendo:

  • Role-Based Access Control (RBAC) restrito para backend e operadores.
  • ServiceAccounts sem privilégios para workloads.
  • Bloqueio de containers privilegiados, hostPath e namespaces do host.
  • Secrets fora de imagens e Git, com rotação e criptografia.
  • Transport Layer Security (TLS) nos caminhos de acesso.
  • Validação dos containers injetados pelas mesmas políticas aplicadas ao container principal. (kubernetes.io)

No Amazon EKS, o EKS Pod Identity associa permissões do AWS Identity and Access Management (IAM) a ServiceAccounts. Isso não torna credenciais acessíveis ao processo seguras contra o próprio código executado. Restrinja também o acesso ao serviço de metadados dos nós. Para tarefas sensíveis, prefira um broker autorizado de ferramentas a credenciais amplas dentro da sandbox. (docs.aws.amazon.com)

Política de rede inicial

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sandbox-default-deny
  namespace: agent-lab
spec:
  podSelector:
    matchLabels:
      app: python-tools
  policyTypes:
    - Ingress
    - Egress

Essa política estabelece negação por padrão para os Pods selecionados, desde que o plugin de rede implemente NetworkPolicy. Outras políticas permissivas continuam sendo combinadas. Ela também bloqueia DNS e acesso remoto normal: acrescente regras específicas para os caminhos realmente necessários. Não é uma política completa de integração E2B. (kubernetes.io)

Exemplo corporativo: análise de arquivos por sessão

Problema: uma empresa quer permitir análises de arquivos enviados por usuários sem conceder acesso direto ao PostgreSQL de produção.

Solução proposta: uma API autentica o usuário, aplica quota e solicita uma sandbox de um template aprovado. Uma fila limita concorrência; o acesso aos arquivos ocorre por um serviço intermediário autorizado.

Implementação proposta: manter metadados da sessão no PostgreSQL, resultados em armazenamento de objetos e ambientes de execução separados dos serviços críticos. O backend registra a relação entre usuário, claim e sandbox, aplica timeout de negócio e confirma a persistência antes de encerrar a sessão.

Resultado esperado: provisionamento mais previsível e responsabilidades mais claras. Isso é uma hipótese arquitetural a validar, não um benchmark. Compare o tempo até a primeira operação útil com e sem pool, usando a mesma imagem, carga e infraestrutura.

Capacidade, escalabilidade e FinOps

O PoolAutoscaler ajusta o estoque por capacidade disponível ou agenda. Não substitui o autoscaling dos nós nem controla sozinho o ciclo de vida das sessões alocadas. Evite múltiplos controllers escrevendo simultaneamente em spec.replicas. (openkruise.io)

Para planejamento inicial, proponho esta aproximação:

estoque livre ≈ taxa de chegada no pico × tempo de reposição + margem de rajada

Exemplo hipotético: duas novas sessões por segundo e reposição de 15 segundos sugerem começar o teste com 30 ambientes livres, antes da margem. Essa conta não substitui distribuição de latências, testes de saturação ou medição de concorrência ativa.

Some ao orçamento sessões em execução, pool livre, componentes de controle e margem de falha. Requests superdimensionados dificultam o aproveitamento da capacidade; valores insuficientes tornam o comportamento sob carga menos previsível. (kubernetes.io)

No plano financeiro, recomendo contabilizar nós, armazenamento, snapshots, tráfego, balanceadores e retenção de telemetria. Avalie Spot somente onde interrupção e reexecução forem aceitáveis; mantenha uma base de capacidade para sessões críticas. Não presuma economia até medir custo por sessão concluída, incluindo falhas e ociosidade.

Alta disponibilidade e recuperação

Alta disponibilidade do serviço não significa replicar automaticamente o estado de uma sessão. Um PodDisruptionBudget (PDB) limita determinadas interrupções voluntárias; não impede falhas de nó nem substitui recuperação de dados. (kubernetes.io)

Minha recomendação de produção é distribuir réplicas de manager e gateway entre zonas, validar leader election do controller antes de aumentar suas réplicas e testar perda de nó. Defina admission control para sobrecarga: fila limitada, rejeição explícita e retries com backoff, em vez de criação irrestrita de sessões.

Pause, resume e checkpoints

A API expõe pausa e retomada, mas a preservação de memória e filesystem depende da infraestrutura. A documentação consultada restringe a preservação de memória citada a Alibaba Cloud ACS; não extrapole essa garantia para EKS. Conexões abertas também precisam ser restabelecidas após retomada. (openkruise.io)

Para recuperação, recomendo definir Recovery Point Objective (RPO, perda de dados tolerável) e Recovery Time Objective (RTO, tempo tolerável de restauração). Mantenha backups dos dados duráveis, metadados e configurações; teste restauração. Checkpoint de execução e backup de negócio devem ser avaliados separadamente.

Observabilidade orientada à experiência

Controller e manager expõem métricas Prometheus. O endpoint do controller possui autenticação e autorização; configure o coletor corretamente. A documentação de métricas acompanha o código de desenvolvimento, portanto confirme nomes e labels na versão implantada. (openkruise.io)

Recomendo um painel com:

  • Latência p50, p95 e p99 entre solicitação e primeira operação útil.
  • Claims com erro ou timeout e estoque disponível.
  • Tempo de reposição, fila e sessões ativas.
  • CPU, memória, reinícios, armazenamento temporário e nós saturados.
  • Erros de autenticação, gateway e retomada.

Correlacione logs e traces pelo identificador da sessão; evite registrar conteúdo sensível. Uma arquitetura possível usa Prometheus e Grafana para métricas, Loki para logs e OpenTelemetry para instrumentação. Esses sinais complementam-se; nenhum isoladamente demonstra a disponibilidade percebida pelo usuário. (kubernetes.io)

Upgrades, GitOps e rollback

Separe atualização do operador, mudança de template e migração de sessões ativas. O projeto distingue rolling update do estoque livre de operações sobre sandboxes já alocadas, como as coordenadas por SandboxUpdateOps. (openkruise.io)

Para alterar capacidade manualmente, use o subrecurso scale; para templates, prefira patches em vez de substituição integral do objeto. (openkruise.io)

kubectl scale sandboxsets.agents.kruise.io python-tools -n agent-lab --replicas=4

Como estratégia operacional, recomendo criar um pool canário com outro nome, direcionar novas sessões gradualmente e manter sessões existentes na revisão original. O rollback volta a encaminhar novas solicitações ao pool anterior; isso não desfaz dados alterados nem restaura memória perdida.

No GitOps, estabeleça um único responsável por cada campo dinâmico. Antes de upgrades de CRDs, registre versões, exporte recursos e valide compatibilidade reversa. A reversão de um chart não deve ser tratada como plano completo de recuperação.

Troubleshooting

Comece pela sequência objeto → Pod → nó → rede. Os comandos abaixo consultam recursos e evidências sem assumir nomes de Deployments do chart. (kubernetes.io)

kubectl get sandboxsets.agents.kruise.io -n agent-lab -o yaml
kubectl get sandboxclaims.agents.kruise.io -n agent-lab -o yaml
kubectl get pods -A
kubectl get deployments -n sandbox-system
kubectl get nodes
kubectl get events -n agent-lab --sort-by=.metadata.creationTimestamp
kubectl describe pod <pod> -n agent-lab
kubectl logs <pod> -n agent-lab -c sandbox
kubectl logs <pod> -n agent-lab -c sandbox --previous

Claim demora ou falha

Sintoma → solicitação não conclui.

Possível causa → estoque indisponível, Pod sem readiness ou inicialização de runtime incompatível.

Investigação → examine status do claim, sandboxes disponíveis e eventos.

Correção → trate o bloqueio de provisionamento; no laboratório, confirme skipInitRuntime. Não use esse campo para mascarar falhas de uma integração que necessita do runtime. (openkruise.io)

Pods permanecem Pending ou reiniciam

Sintoma → ambientes não ficam utilizáveis.

Possível causa → capacidade insuficiente, imagem inacessível ou falha do processo.

Investigação → consulte describe, eventos e logs anteriores.

Correção → ajuste a causa demonstrada pelas evidências antes de aumentar timeouts ou réplicas. (kubernetes.io)

Pod saudável, mas acesso falha

Sintoma → timeout ao acessar a sessão.

Possível causa → política de rede bloqueando o caminho necessário.

Investigação → revise seletores e permissões de entrada e saída.

Correção → acrescente a permissão mínima; não remova toda a política de isolamento. (kubernetes.io)

Desenvolvimento versus produção

DimensãoDesenvolvimentoProdução proposta
CapacidadePool pequeno e ajuste manualLimites, autoscaling e teste de rajadas
DadosResultados descartáveisPersistência, retenção e restauração testada
DisponibilidadeFalhas toleradas manualmenteRedundância e procedimentos de recuperação
SegurançaDados sintéticos e acesso localIdentidade, isolamento e auditoria
MudançasExperimentação controladaCanário, versões fixadas e rollback

Evite promover o laboratório diretamente: ausência de quotas, credenciais hardcoded, exposição pública, probes copiadas sem validação, falta de observabilidade e encerramento indefinido de sessões são motivos para bloquear a entrada em produção.

Quando usar e quais alternativas considerar

Considere OpenKruise Agents quando sessões isoladas, estoque pré-aquecido e gestão declarativa justificarem operar uma plataforma especializada. Minha recomendação é exigir capacidade de suporte, testes de isolamento e um responsável pelo ciclo de vida antes da adoção.

Para processamento finito e pouco interativo, Kubernetes Jobs podem ser mais simples: são recursos orientados à execução até conclusão, não à gestão de sessões interativas. (kubernetes.io)

O Kubernetes SIG Agent Sandbox também oferece abstrações para workloads isolados e stateful. Compare APIs, extensões, runtimes e operação; não o trate como substituição automática de manifestos. (github.com)

Um serviço gerenciado deve entrar na avaliação quando reduzir responsabilidade operacional for mais importante que controlar toda a infraestrutura. Nesse caso, compare custo por sessão, residência de dados, portabilidade e garantias contratuais. Para poucas tarefas ocasionais, o custo de manter o operador e um pool ocioso pode não se justificar.

Resumo prático

  • Separe sandbox, pool livre e sessão alocada.
  • Valide os recursos existentes na versão instalada.
  • Trate o YAML demonstrativo como laboratório, não como fronteira contra código hostil.
  • Dimensione capacidade total, não apenas replicas do pool.
  • Teste persistência, retomada, encerramento e rollback antes da exposição aos usuários.

Conclusão

Minha recomendação é introduzir OpenKruise Agents como um produto interno de Platform Engineering: templates aprovados, contratos de acesso, orçamento de capacidade e critérios de confiabilidade explícitos.

Para DevOps, isso significa mudanças reproduzíveis. Para SRE, significa objetivos mensuráveis e recuperação testada. Para arquitetura cloud, significa escolher conscientemente onde compartilhar infraestrutura e onde separar riscos. O objetivo não deve ser apenas criar ambientes rapidamente, mas oferecer sessões cujo comportamento, custo e falhas possam ser explicados e controlados.

Quer aplicar isso no seu ambiente?

Agende uma conversa de 30 minutos sem compromisso. Eu olho o seu cenário e digo por onde começar.

Agendar uma conversa

Receba os novos artigos por e-mail

Um e-mail quando sair artigo novo sobre infraestrutura, backend e IA. Sem spam, cancele quando quiser.