使用 Agent Sandbox 隔离 AI 代码执行

本文档介绍了如何在 Google Kubernetes Engine (GKE) 集群上安装和运行 Agent Sandbox 控制器。还介绍了如何在集群上部署沙盒环境,以便在其中测试不受信任的 shell 命令。

Agent Sandbox 控制器提供了一个用于创建和管理临时运行时环境的框架。借助此方法,您可以为应用的环境定义模板,然后按需创建该模板的实例。

Agent Sandbox 提供了一个安全且隔离的环境,用于执行不受信任的代码,例如由大语言模型 (LLM) 生成的代码。 直接在集群中运行此类代码会带来安全风险,因为不受信任的代码可能会访问或干扰其他应用或底层集群节点本身。

Agent Sandbox 通过为所运行的代码提供强大的进程、存储和网络隔离来缓解这些风险。这种隔离是通过 gVisor 实现的,该技术可在应用与集群节点的操作系统之间创建安全屏障。您可以改为使用其他沙盒技术,例如 Kata 容器;不过,本文档中的示例仅使用 gVisor。

本文档介绍了如何在 GKE Autopilot 集群或 Standard 集群上运行 Agent Sandbox。

Agent Sandbox 是一个开源项目。如需详细了解如何为该项目做出贡献或查找更深入的技术细节,请参阅 Agent Sandbox 开源项目

费用

按照本教程中的步骤操作会导致您的 Google Cloud账号产生费用。当您创建 GKE 集群时,费用开始产生。这些费用包括按集群收取的 GKE 费用(如价格页面中所述)以及运行 Compute Engine 虚拟机的费用。

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

准备工作

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. Enable the Artifact Registry, Google Kubernetes Engine APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  4. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    定义环境变量

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

    export PROJECT_ID=$(gcloud config get project)
    export CLUSTER_NAME="agent-sandbox-cluster"
    export GKE_LOCATION="us-central1"
    export AGENT_SANDBOX_VERSION="v0.1.0"
    export NODE_POOL_NAME="agent-sandbox-node-pool"
    export MACHINE_TYPE="e2-standard-2"
    export PYTHON_CLIENT_VERSION="main"
    

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

    • PROJECT_ID:当前 Google Cloud 项目的 ID。定义此变量有助于确保所有资源(例如 GKE 集群)都在正确的项目中创建。
    • CLUSTER_NAME:GKE 集群的名称,例如 agent-sandbox-cluster
    • GKE_LOCATION:将在其中创建 GKE 集群和 Artifact Registry 仓库的 Google Cloud 区域,例如 us-central1。我们建议将它们放置在同一位置,因为这样可以缩短映像拉取延迟时间。
    • AGENT_SANDBOX_VERSION:要部署到集群的 Agent Sandbox 控制器的版本。
    • NODE_POOL_NAME:将运行沙盒化工作负载的节点池的名称,例如 agent-sandbox-node-pool
    • MACHINE_TYPE:节点池中节点的机器类型,例如 e2-standard-2。如需详细了解不同的机器系列以及如何在不同选项之间进行选择,请参阅机器家族资源和比较指南
    • PYTHON_CLIENT_VERSION:要安装的 Agentic Sandbox Python 客户端的版本。

    部署 Agent Sandbox

    现在,您已设置好 Google Cloud 项目和 Cloud Shell 环境,接下来可以预配必要的基础设施并部署 Agent Sandbox 了。

    创建 GKE 集群

    接下来,您需要创建一个启用了 gVisor 的 GKE 集群。此集群提供您将在其中部署和运行 Agent Sandbox 控制器和示例沙盒应用的 Kubernetes 环境。gVisor 提供沙盒技术,可安全地运行不受信任的代码。

    您可以创建 Autopilot 集群或 Standard 集群。 Autopilot 会自动启用 gVisor,而 Standard 集群需要您手动创建启用了 gVisor 的节点池:

    Autopilot

    如需使用 gcloud CLI 创建 Autopilot 集群,请运行以下命令:

    gcloud container clusters create-auto ${CLUSTER_NAME} \
        --location=${GKE_LOCATION} \
        --project=${PROJECT_ID}
    

    标准

    如需使用 gcloud CLI 创建 Standard 集群,请执行以下步骤:

    1. 创建集群:

      gcloud container clusters create ${CLUSTER_NAME} \
          --location=${GKE_LOCATION}
      
    2. 创建启用了 gVisor 的单独节点池:

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

    检索集群的凭证,以便 kubectl CLI 可以连接到集群。此命令会更新您的 Kubernetes 配置文件,该文件默认存储在 ~/.kube/config 目录中。此配置文件包含 kubectl 与 GKE 集群交互所需的凭证。

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

    将 Agent Sandbox 控制器部署到您的集群

    您可以将正式版清单应用于集群,以部署 Agent Sandbox 控制器及其所需的组件。这些清单是配置文件,用于指示 Kubernetes 下载在集群上部署和运行 Agent Sandbox 控制器所需的所有必要组件。

    运行以下命令,将 Agent Sandbox 控制器部署到 GKE 集群:

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

    验证 Agent Sandbox 控制器

    应用清单后,检查 Agent Sandbox 控制器 Pod 是否在 agent-sandbox-system 命名空间中正常运行:

    kubectl get pods -n agent-sandbox-system
    

    等待 Pod 在状态列中显示“正在运行”,在就绪列中显示“1/1”。当 Pod 正常运行时,输出类似于以下内容:

    NAME                         READY   STATUS    RESTARTS   AGE
    agent-sandbox-controller-0   1/1     Running   0          44d
    

    现在,Agent Sandbox 控制器已在运行,它可以自动为在集群中创建的任何 Sandbox 资源创建和管理沙盒环境。

    部署沙盒环境

    现在,您已在 GKE 集群中运行 Agent Sandbox 控制器,接下来需要部署示例沙盒环境的组件。本部分介绍了如何创建沙盒蓝图 (SandboxTemplate)、部署必要的网络路由器,以及安装用于与沙盒交互的 Python 客户端。

    建议使用 Agentic Sandbox Python 客户端来创建沙盒并与之交互。 此客户端提供了一个接口,可简化沙盒的整个生命周期,从创建到清理。这是一个 Python 库,可用于以程序化方式创建、使用和删除沙盒。

    客户端使用沙盒路由器作为所有流量的中央入口点。在本文档所述的示例中,客户端使用命令 kubectl port-forward 创建通往此路由器的隧道,这样您就不需要公开任何公共 IP 地址。请注意,使用 kubectl port-forward 并非安全解决方案,其使用应仅限于开发环境。

    创建 SandboxTemplateSandboxWarmPool

    现在,您可以通过创建 SandboxTemplateSandboxWarmPool 资源来定义沙盒的配置。SandboxTemplate 充当可重用的蓝图,供 Agent Sandbox 控制器用于创建一致的预配置沙盒环境。SandboxWarmPool 资源可确保指定数量的预热 Pod 始终处于运行状态,并随时可供声明。预热沙盒是已初始化的正在运行的 Pod。这种预初始化可让新沙盒在不到一秒的时间内创建完成,并避免启动常规沙盒时出现的启动延迟:

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

      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
            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"
                  ephemeral-storage: "512Mi"
            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. 应用 SandboxTemplateSandboxWarmPool 清单:

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

    部署沙盒路由器

    您将用于创建沙盒环境并与之交互的 Python 客户端使用名为“沙盒路由器”的组件与沙盒进行通信。

    在此示例中,您将使用客户端的开发者模式进行测试。此模式适用于本地开发,并使用 kubectl port-forward 命令在本地机器与集群中运行的沙盒路由器服务之间建立直接隧道。这种隧道方法无需使用公共 IP 地址或复杂的入站流量设置,并简化了从本地环境与沙盒的交互。

    请按照以下步骤部署沙盒路由器:

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

      # 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: 2 # Run at least two replicas for high availability
        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:v20251124-v0.1.0-10-ge26ddb2
              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: "250m"
                  memory: "512Mi"
                limits:
                  cpu: "1000m"
                  memory: "1Gi"
            securityContext:
              runAsUser: 1000
              runAsGroup: 1000
      
    2. 应用清单以将路由器部署到集群:

      kubectl apply -f sandbox-router.yaml
      

    安装 Python 客户端

    现在,沙盒路由器等集群内组件已部署完毕,最后一步准备工作是在本地机器上安装 Agentic Sandbox Python 客户端。请注意,此客户端是一个 Python 库,可让您以程序化方式创建、使用和删除沙盒。您将在下一部分中使用它来测试环境:

    1. 创建并激活 Python 虚拟环境:

      python3 -m venv .venv
      source .venv/bin/activate
      
    2. agent-sandbox 仓库安装客户端软件包:

      pip install "git+https://github.com/kubernetes-sigs/agent-sandbox.git@${PYTHON_CLIENT_VERSION}#subdirectory=clients/python/agentic-sandbox-client"
      

    测试沙盒

    在所有设置组件就绪后,您现在可以使用 Agentic Sandbox Python 客户端创建沙盒并与之交互。

    1. agent-sandbox 目录中,创建一个名为 test_sandbox.py 的 Python 脚本,其中包含以下内容:

      from agentic_sandbox import SandboxClient
      
      # Automatically tunnels to svc/sandbox-router-svc
      with SandboxClient(
          template_name="python-runtime-template",
          namespace="default"
      ) as sandbox:
          print(sandbox.run("echo 'Hello from the sandboxed environment!'").stdout
      )
      
    2. 在终端中(虚拟环境仍处于活跃状态),运行测试脚本:

      python3 test_sandbox.py
      

    您应该会看到“Hello from the sandboxed environment!”消息,这是沙盒的输出。

    恭喜!您已成功在安全沙盒中运行 shell 命令。使用 sandbox.run() 方法,您可以执行任何 shell 命令,并且 Agent Sandbox 会在安全屏障内运行该命令,从而保护集群的节点和其他工作负载免受不信任代码的侵害。这为 AI 代理或任何自动化工作流提供了一种安全可靠的任务执行方式。

    运行脚本时,SandboxClient 会为您处理所有步骤。它会创建 SandboxClaim 资源来启动沙盒,等待沙盒准备就绪,然后使用 sandbox.run() 方法在安全容器内执行 bash shell 命令。然后,客户端会捕获并输出来自该命令的 stdout。程序运行后,沙盒会自动删除。

    清理资源

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

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

    后续步骤

    • 如需详细了解 Agent Sandbox 开源项目,请访问 GitHub
    • 如需了解为工作负载提供安全隔离的底层技术,请参阅 GKE Sandbox
    • 如需详细了解如何增强集群和工作负载的安全性,请参阅 GKE 安全概览