在 GKE 上安装 Agent Sandbox

本文档介绍了如何在 Google Kubernetes Engine (GKE) 集群上安装开源 Agent Sandbox 控制器,以便在专用 Kubernetes Pod 中运行沙盒化工作负载。您还将了解如何在集群上创建沙盒环境,以便安全地执行不受信任的代码。

如需简要了解 GKE 上的 Agent Sandbox 如何隔离不受信任的 AI 生成的代码,请参阅 GKE 上的 Agent Sandbox 简介。

在基于 Pod 的架构和基于 Actor 的架构之间进行选择

在 GKE 上安装 Agent Sandbox 之前,请确认哪种 GKE 架构适合您的 AI 智能体工作负载:

  • GKE 上的 Agent Substrate(基于 actor):对于大多数智能体工作负载,尤其是频繁暂停和恢复的有状态智能体,请使用此架构。活跃代理共享一个温 Pod 池,而不是每个代理保留一个专用 Pod,因此您可以在更少的节点上运行更多代理。GKE 上的 Agent Substrate 可自动暂停和恢复闲置工作负载,并在不到一秒的时间内从存储空间中恢复智能体。相比之下,GKE 上的 Agent Sandbox 需要手动创建 Pod 快照,并且您需要构建应用代码来检测不活动状态并保存智能体的进度。GKE 上的 Agent Substrate 需要 GKE Standard 集群。如需了解详情,请参阅 GKE 上的 Agent Substrate 简介。如需改为安装此选项,请参阅在 GKE 上安装 Agent Substrate。
  • GKE 上的 Agent Sandbox(基于 Pod):当每个智能体都需要在 GKE Autopilot 或 Standard 集群上拥有专用 Kubernetes Pod 时,请使用此架构(您将在本文档中安装此架构)。如果智能体或工作负载持续处于活跃状态,或者需要以下任一功能,请选择此选项:
    • 声明式 Kubernetes API,例如 Sandbox 和 SandboxClaim 自定义资源
    • 完整的 Kubernetes PodSpec 架构,包括自定义边车和初始化容器
    • 直接访问硬件加速器,例如 GPU 或 TPU
    • GKE Autopilot 集群

费用

GKE 上的 Agent Sandbox 是一款开源软件,您可以免费使用。GKE 价格适用于您创建的资源,包括 Agent Sandbox 控制器使用的计算资源。

为避免产生不必要的费用,请务必在完成本文档后停用 GKE 或删除项目。

准备工作

  1. 在 Google Cloud 控制台的项目选择器页面上,选择或创建 Google Cloud 项目。

    选择或创建项目所需的角色

    • 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
    • 创建项目:如需创建项目,您需要拥有 Project Creator 角色 (roles/resourcemanager.projectCreator),该角色包含 resourcemanager.projects.create 权限。了解如何授予角色。

    转到“项目选择器”

  2. 验证是否已为您的 Google Cloud 项目启用结算功能。

  3. 启用 Google Kubernetes Engine API(如果尚未启用)。

    启用 API 所需的角色

    如需启用 API,您需要拥有 serviceusage.services.enable 权限。如果您创建了项目,则可能已经通过 Owner 角色 (roles/owner) 拥有此权限。否则,您可以通过 Service Usage Admin 角色 (roles/serviceusage.serviceUsageAdmin) 获得此权限。了解如何授予角色。

    启用 API

  4. 在 Google Cloud 控制台中,激活 Cloud Shell。

    激活 Cloud Shell

定义环境变量

为了简化您在本文档中运行的命令,您可以在 Cloud Shell 中设置环境变量。在 Cloud Shell 中,运行以下命令来定义以下有用的环境变量:

export CLUSTER_NAME="agent-sandbox-cluster"
export LOCATION="us-central1"
export AGENT_SANDBOX_VERSION="v1.0.6"
export NODE_POOL_NAME="agent-sandbox-pool"
export MACHINE_TYPE="e2-standard-2"

以下是这些环境变量的说明:

  • CLUSTER_NAME:GKE 集群的名称,例如 agent-sandbox-cluster。
  • LOCATION:创建 GKE 集群的 Google Cloud 区域或可用区。如果您创建 Autopilot 集群,请将其设置为区域(例如 us-central1)。Autopilot 集群始终为区域级集群。如果您创建 Standard 集群,请将其设置为可用区(例如 us-central1-a)。为降低费用,本文档会创建一个可用区级集群,该集群使用的节点比区域级集群少。
  • AGENT_SANDBOX_VERSION:要安装的开源 Agent Sandbox 控制器的版本。本文档使用 1.0.6 版。如需查看其他版本,请前往 Agent Sandbox 版本页面。
  • NODE_POOL_NAME:将运行沙盒化工作负载的节点池的名称,例如 agent-sandbox-pool。只有在创建 GKE Standard 集群时,才需要此变量。
  • MACHINE_TYPE:集群的默认节点池和 gVisor 节点池中的节点的机器类型,例如 e2-standard-2。如需详细了解不同的机器系列以及如何在不同选项之间进行选择,请参阅机器家族资源和比较指南。仅当您创建 GKE Standard 集群时,才需要此变量。

创建 GKE 集群

GKE 上的 Agent Sandbox 通过使用 gVisor 或microVMs来隔离沙盒化工作负载。如果您未指定沙盒运行时,沙盒将在没有内核隔离的情况下运行,我们不建议对不受信任的代码使用此设置。本文档使用 gVisor。Autopilot 集群会自动启用 gVisor。在 Standard 集群中,您需要创建一个启用了 gVisor 的节点池。如需改用 microVM,请参阅启用 microVM 沙盒类型。推荐的安全政策仅允许 gVisor,因此它会拒绝使用微型虚拟机 (microVM) 的沙盒。

Autopilot

如需创建 Autopilot 集群,请确保将 LOCATION 环境变量设置为某个区域(例如 us-central1),然后运行以下命令:

gcloud container clusters create-auto ${CLUSTER_NAME} \
    --location=${LOCATION}

标准

如需创建 Standard 集群,请先创建集群,然后添加启用了 gVisor 的节点池。为了降低费用,本文档创建了一个可用区级集群,每个池有一个节点。

  1. 将 LOCATION 环境变量设置为可用区,例如 us-central1-a:

    export LOCATION="us-central1-a"
    
  2. 创建集群:

    gcloud container clusters create ${CLUSTER_NAME} \
        --location=${LOCATION} \
        --machine-type=${MACHINE_TYPE} \
        --num-nodes=1
    
  3. 创建一个启用了 gVisor 的单独节点池:

    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
    

    如需使用 microVM 而不是 gVisor,请按照启用 microVM 沙盒类型中的说明创建节点池。本文档的其余部分使用 gVisor。

如需改用现有 Standard 集群,请确保该集群包含已启用 gVisor 的节点池。如果集群没有此类节点池,请运行上述 gcloud container node-pools create 命令创建一个。

如需使 kubectl 命令行工具能够连接到集群,请获取集群凭据:

gcloud container clusters get-credentials ${CLUSTER_NAME} \
    --location=${LOCATION}

安装 Agent Sandbox

如需安装 Agent Sandbox,请应用 Agent Sandbox GitHub 代码库中的版本清单。sandbox-with-extensions.yaml 清单会安装 Agent Sandbox 控制器以及 Sandbox 资源和 SandboxTemplate、SandboxClaim 和 SandboxWarmPool 扩展资源的 CustomResourceDefinition。

  1. 应用版本清单:

    kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/sandbox-with-extensions.yaml
    

    该清单会创建 agent-sandbox-system 命名空间,并在该命名空间中部署控制器。

  2. 等待控制器准备就绪:

    kubectl rollout status deployment/agent-sandbox-controller \
        --namespace=agent-sandbox-system \
        --timeout=120s
    

您还可以使用 Helm 安装 Agent Sandbox。如需查看相关说明,请参阅 Agent Sandbox Helm chart README。

验证安装

  1. 验证 Agent Sandbox CustomResourceDefinitions 是否已安装:

    kubectl get crd \
        sandboxes.agents.x-k8s.io \
        sandboxtemplates.extensions.agents.x-k8s.io \
        sandboxclaims.extensions.agents.x-k8s.io \
        sandboxwarmpools.extensions.agents.x-k8s.io
    

    输出会列出四个 CustomResourceDefinition。

  2. 验证控制器是否正在运行:

    kubectl get deployment agent-sandbox-controller \
        --namespace=agent-sandbox-system
    

    控制器运行时,READY 列会显示 1/1。

应用建议的安全政策

默认情况下,GKE 上的 Agent Sandbox 不会限制运行沙盒的 Pod 的配置。为帮助强制执行沙盒的隔离设置,请应用 Agent Sandbox GitHub 代码库中推荐的 secure-sandbox-policy ValidatingAdmissionPolicy。此政策会拒绝任何不符合 GKE 上的 Agent Sandbox 部署要求的 Sandbox 资源。

  1. 应用政策:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/examples/policy/vap/secure-sandbox-policy.yaml
    
  2. 应用政策绑定。该绑定会在除系统命名空间(例如 kube-system)之外的所有命名空间中强制执行该政策:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/examples/policy/vap/secure-sandbox-binding.yaml
    

该政策会验证 Sandbox 资源。当您创建 SandboxWarmPool 资源或 SandboxClaim 资源时,控制器会根据 SandboxTemplate 资源创建 Sandbox 资源。如果模板不符合要求,该政策会拒绝 Sandbox 资源,并且错误会显示在控制器日志中。如需查看日志,请运行以下命令:

kubectl logs deployment/agent-sandbox-controller \
    --namespace=agent-sandbox-system

您拥有此政策,并可以对其进行修改以适应您的工作负载。如需了解详情,请参阅沙盒安全政策。

GKE 上的 Agent Sandbox 部署要求

如果您应用推荐的安全政策,则工作负载清单(例如 Sandbox 或 SandboxTemplate 资源)必须包含特定的安全和配置设置。如果 Sandbox 资源不满足这些要求,准入控制器会拒绝该资源。容器要求适用于 Pod 中的所有容器,包括 init 容器和临时容器。

所需的配置

您的部署清单必须包含以下设置:

  • runtimeClassName: gvisor:确保 Pod 在 gVisor 沙盒中运行。该政策会拒绝使用任何其他运行时(包括 microVM)的沙盒。
  • automountServiceAccountToken: false:防止 Pod 自动装载默认服务账号令牌。
  • securityContext.runAsNonRoot: true:确保容器不以根用户身份运行。
  • securityContext.capabilities.drop: ["ALL"]:从容器中丢弃所有 Linux 功能。
  • resources.limits:您必须指定 CPU 和内存限制,以防止潜在的拒绝服务 (DoS) 场景。
  • nodeSelector:必须以 sandbox.gke.io/runtime: gvisor 为目标。
  • tolerations:必须包含对 sandbox.gke.io/runtime=gvisor:NoSchedule 污点的容忍。

禁止的配置

您的部署清单不得包含以下任何内容:

  • hostNetwork: true、hostPID: true或 hostIPC: true。
  • 容器安全上下文中的 privileged: true。
  • 容器安全上下文中的 procMount: Unmasked。
  • HostPath 卷。
  • 添加了功能 (capabilities.add)。
  • “hostPort”的设置。
  • 自定义 sysctl。
  • 服务账号令牌或证书的投影卷。

部署沙盒路由器(可选)

沙盒路由器是一个 HTTP 代理,用于将来自客户端(例如 Agent Sandbox Python 客户端)的请求路由到运行沙盒的 Pod。如果您计划使用 Python 客户端(例如,如在 GKE 上使用 Agent Sandbox 隔离 AI 代码执行中所述),请部署路由器。

您在 agent-sandbox-system 命名空间中部署路由器。默认情况下,Agent Sandbox on GKE 为每个 SandboxTemplate 资源创建的网络政策仅允许来自此命名空间中的路由器 Pod 的传入流量进入沙盒。

  1. 创建路由器的服务账号和 RBAC 权限,以便路由器查找沙盒 Pod:

    kubectl apply \
        -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/serviceaccount.yaml \
        -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/rbac.yaml
    
  2. 部署路由器。以下命令会将路由器映像设置为与控制器相同的版本:

    curl -sSL https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/deployment.yaml \
        | sed "s|sandbox-router-go:latest|sandbox-router-go:${AGENT_SANDBOX_VERSION}|" \
        | kubectl apply -f -
    
  3. 创建路由器的 Service:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/service.yaml
    
  4. 等待路由器准备就绪:

    kubectl rollout status deployment/sandbox-router \
        --namespace=agent-sandbox-system \
        --timeout=120s
    

此路由器配置适用于开发和测试。如需了解生产设置(例如 TLS、副本数量和路由器的网络政策),请参阅沙盒路由器部署自述文件。

部署沙盒化环境

我们建议通过定义 SandboxTemplate 资源来部署沙盒化环境,并使用 SandboxWarmPool 资源使预热实例保持就绪状态。然后,您可以使用 SandboxClaim 资源从此温池请求实例。或者,您也可以直接创建 Sandbox 资源,但此方法不支持温池。

SandboxTemplate、SandboxWarmPool、SandboxClaim 和 Sandbox 是 Kubernetes 自定义资源。

SandboxTemplate 资源充当可重用蓝图。SandboxWarmPool 资源有助于确保指定数量的预热沙盒始终处于运行状态,并随时可供声明。使用此自定义资源可最大限度地缩短启动延迟时间。

如需通过创建 SandboxTemplate 和 SandboxWarmPool 资源来部署沙盒化环境,请完成以下步骤:

  1. 在 Cloud Shell 中,创建一个名为 sandbox-template.yaml 的文件,其中包含以下内容:

    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. 应用 SandboxTemplate 清单:

    kubectl apply -f sandbox-template.yaml
    
  3. 创建一个名为 sandbox-warmpool.yaml 的文件,其中包含以下内容:

    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. 应用 SandboxWarmPool 清单:

    kubectl apply -f sandbox-warmpool.yaml
    
  5. 等待预热池的沙盒准备就绪:

    kubectl wait sandboxwarmpool python-runtime-warmpool \
        --for=jsonpath='{.status.readyReplicas}'=2 \
        --timeout=600s
    

    如果您在池的沙盒准备就绪之前创建 SandboxClaim 资源,则控制器可能会为声明创建新沙盒,而不是从池中分配一个沙盒。在 Autopilot 集群中,沙盒可能需要几分钟才能准备就绪,因为 GKE 可能需要为其创建节点。

创建 SandboxClaim 资源

SandboxClaim 资源请求会从温池请求沙盒。由于您创建了温池,控制器会将池中正在运行的沙盒分配给声明,而不是创建新沙盒。

如需通过创建 SandboxClaim 资源从温池请求沙盒,请完成以下步骤:

  1. 创建一个名为 sandbox-claim.yaml 的文件,其中包含以下内容:

    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. 应用 SandboxClaim 清单:

    kubectl apply -f sandbox-claim.yaml
    
  3. 验证沙盒、声明和温池是否已准备就绪:

    kubectl get sandboxwarmpool,sandboxclaim,sandbox,pod
    

替代方案:直接创建 Sandbox 资源

如果您不需要预热池提供的快速启动时间,则可以直接部署 Sandbox 资源,而无需使用模板。

如需通过直接创建 Sandbox 资源来部署沙盒化环境,请完成以下步骤:

  1. 创建一个名为 sandbox.yaml 的文件,其中包含以下内容:

    apiVersion: agents.x-k8s.io/v1beta1
    kind: Sandbox
    metadata:
      name: sandbox-example-2
    spec:
      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 (for example, 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. 应用 Sandbox 清单:

    kubectl apply -f sandbox.yaml
    
  3. 验证沙盒是否正在运行:

    kubectl get sandbox
    

升级 Agent Sandbox

如需升级 Agent Sandbox,请应用新版本的发布清单:

export AGENT_SANDBOX_VERSION="NEW_VERSION"
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/sandbox-with-extensions.yaml

将 NEW_VERSION 替换为您要安装的版本,例如 Agent Sandbox 版本页面上列出的版本。

在升级之前,请查看新版本的版本说明。如果您的集群运行的 Agent Sandbox 版本低于 1.0.0,则必须在升级之前将资源迁移到 v1beta1 API,因为 1.0.0 版本移除了 v1alpha1 API。如需查看相关说明,请参阅 API 迁移指南。

如果您部署了沙盒路由器或应用了建议的安全政策,请针对新版本重复这些步骤。

卸载 Agent Sandbox

  1. 检查仍在使用的 Agent Sandbox 资源:

    kubectl get sandboxes,sandboxclaims,sandboxwarmpools,sandboxtemplates \
        --all-namespaces
    
  2. 如果您应用了推荐的安全政策,请删除政策绑定和政策:

    kubectl delete validatingadmissionpolicybinding secure-sandbox-binding
    kubectl delete validatingadmissionpolicy secure-sandbox-policy
    
  3. 如果您部署了 Sandbox Router,请删除其集群级 RBAC 资源:

    kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/rbac.yaml
    

    路由器的其他资源位于 agent-sandbox-system 命名空间中,下一步会将其删除。

  4. 如需删除 Agent Sandbox 控制器、其命名空间及其 CustomResourceDefinition,请删除您安装的版本的发布清单:

    kubectl delete -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/sandbox-with-extensions.yaml
    

清理资源

为避免系统向您的 Google Cloud 账号收取费用,请删除您创建的 GKE 集群。

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

如果您创建了 Autopilot 集群,则位置为区域(例如 us-central1)。如果您创建了 Standard 集群,则位置为可用区(例如 us-central1-a)。

后续步骤