使用 Agent Sandbox 隔离 AI 代码执行

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

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

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

Agent Sandbox 通过为所运行的代码提供强大的进程、存储和网络隔离来缓解这些风险。本文档介绍了如何在 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 REPOSITORY_NAME="python-sandbox-repo"
    export PYTHON_SANDBOX_IMG="${GKE_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/sandbox-runtime:latest"
    export AGENT_SANDBOX_VERSION="v0.1.0"
    

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

    • PROJECT_ID:当前 Google Cloud 项目的 ID。定义此变量有助于确保所有资源(例如 GKE 集群)都在正确的项目中创建。
    • CLUSTER_NAME:GKE 集群的名称,例如 agent-sandbox-cluster
    • GKE_LOCATION:将在其中创建 GKE 集群和 Artifact Registry 仓库的 Google Cloud 区域,例如 us-central1。我们建议将它们放置在同一位置,因为这样可以缩短映像拉取延迟时间。
    • REPOSITORY_NAME:将在其中存储示例 Python 应用的容器映像的Artifact Registry 仓库的名称,例如 python-sandbox-repo
    • PYTHON_SANDBOX_IMG:您将构建和推送的 Python 沙盒容器映像的唯一标识符。
    • AGENT_SANDBOX_VERSION:要部署到集群的 Agent Sandbox 控制器的版本。

    部署 Agent Sandbox

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

    创建 GKE 集群

    接下来,您需要创建 GKE 集群。此集群提供您将在其中部署和运行 Agent Sandbox 控制器和示例沙盒应用的 Kubernetes 环境。

    您可以创建 Autopilot 集群或 Standard 集群:

    Autopilot

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

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

    标准

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

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

    检索集群的凭证,以便 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
    

    验证 Deployment

    应用清单后,检查 Agent Sandbox 控制器 Pod 是否正常运行。

    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 控制器,接下来可以部署一个示例 Web 服务器应用,该应用会提供安全的沙盒环境来执行 shell 命令。

    为此,您首先需要构建应用的容器映像,并将其存储在集群可以访问的私有 Artifact Registry 仓库中。

    映像可用后,您可以使用两步流程来部署它。 首先,您定义一个 SandboxTemplate,它充当沙盒环境的可重用蓝图。然后,您创建一个 SandboxClaim,该请求会指示 Agent Sandbox 控制器拉取容器映像,并根据模板将其作为新 Pod 运行。最后,您测试正在运行的应用,以确认其正常运行。

    创建 Artifact Registry 仓库

    以下步骤介绍了如何创建私有 Artifact Registry 仓库来存储容器映像,以及如何配置 Docker 来访问该仓库。

    1. 创建 Artifact Registry 仓库以存储 Python 沙盒应用的容器映像:

      gcloud artifacts repositories create $REPOSITORY_NAME \
          --repository-format=docker \
          --location=$GKE_LOCATION
      
    2. 使用 Artifact Registry 对 Docker 客户端进行身份验证。此操作可让您使用 Google Cloud 凭证安全地将映像推送到私有仓库并从中拉取映像:

      gcloud auth configure-docker "${GKE_LOCATION}-docker.pkg.dev"
      

    构建并推送示例 Python 应用

    接下来,您需要从 Agent Sandbox 仓库下载示例代码。此代码会构建一个包含基本 Python Web 服务器的容器映像。

    此 Web 服务器旨在演示 Agent Sandbox 的核心功能:它公开了 /execute 端点,该端点接受 shell 命令作为 JSON 载荷。当您向此端点发送命令时,服务器会在安全的沙盒环境中执行该命令并返回输出。

    以下步骤展示了如何克隆仓库、构建容器映像并将其推送到您的私有 Artifact Registry 仓库:

    1. 从 GitHub 克隆 agent-sandbox 仓库。此仓库包含 Python 应用的代码:

      git clone https://github.com/kubernetes-sigs/agent-sandbox.git
      
    2. 前往包含 Python 应用的 Dockerfile 和源代码的目录:

      cd agent-sandbox/examples/python-runtime-sandbox
      
    3. 使用 Docker 为应用构建容器映像。-t 标志会使用本文档开头 PYTHON_SANDBOX_IMG 环境变量中定义的名称标记映像:

      docker build -t $PYTHON_SANDBOX_IMG .
      
    4. 将容器映像推送到您的私有 Artifact Registry 仓库,以便 GKE 集群可以访问该映像:

      docker push $PYTHON_SANDBOX_IMG
      

    创建 SandboxTemplate

    现在,您可以通过创建 SandboxTemplate 资源来定义沙盒的配置。此模板充当可重用的蓝图,供 Agent Sandbox 控制器用于创建一致的预配置沙盒环境。创建 SandboxTemplate 资源后,您只需定义一次沙盒,即可在日后创建多个沙盒实例。

    1. 在 Cloud Shell 中,创建一个名为 sandbox-template.yaml 的文件,其中包含以下内容。以下清单定义了一个 SandboxTemplate 资源,该资源作为创建沙盒的可重用蓝图。 SandboxTemplateSandboxClaim 必须位于同一命名空间中:

      apiVersion: extensions.agents.x-k8s.io/v1alpha1
      kind: SandboxTemplate
      metadata:
        name: python-runtime-template
        namespace: default
      spec:
        podTemplate:
          metadata:
            labels:
              # The selector in the wait command looks for this label.
              sandbox: python-sandbox-example
          spec:
            # Optional, must have gVisor enabled node
            # runtimeClassName: gvisor
            containers:
            - name: python-runtime
              image: IMAGE_PLACEHOLDER
              ports:
              - containerPort: 8888
              readinessProbe:
                httpGet:
                  path: "/"
                  port: 8888
                initialDelaySeconds: 0
                periodSeconds: 1
              resources:
                requests:
                  cpu: "250m"
                  memory: "512Mi"
                  ephemeral-storage: "512Mi"
            restartPolicy: "OnFailure"
      
    2. 使用 Python 应用的映像路径更新清单:

      sed -i "s|IMAGE_PLACEHOLDER|${PYTHON_SANDBOX_IMG}|g" sandbox-template.yaml
      
    3. 应用 SandboxTemplate 清单:

      kubectl apply -f sandbox-template.yaml
      

    通过应用 SandboxClaim 来创建沙盒

    现在,您已经拥有可重用的蓝图,接下来可以通过将 SandboxClaim 资源应用于集群来创建正在运行的沙盒。此声明引用了 SandboxTemplate,并指示 Agent Sandbox 控制器根据模板的配置创建 Sandbox 资源及其对应的 Pod:

    1. 创建名为 sandbox-claim.yaml 且包含以下内容的文件。 SandboxClaim 资源会根据 python-runtime-template 请求新的沙盒。请注意,您可以创建多个 SandboxClaims;不过,每个 SandboxClaim 名称都必须与正在运行的其他 SandboxClaims 不同:

      apiVersion: extensions.agents.x-k8s.io/v1alpha1
      kind: SandboxClaim
      metadata:
        name: python-sandbox-example
        namespace: default
      spec:
        sandboxTemplateRef:
          name: python-runtime-template
      
    2. 如需根据该模板触发沙盒资源的创建,请应用 SandboxClaim 清单:

      kubectl apply -f sandbox-claim.yaml
      
    3. 验证沙盒资源是否已准备就绪:

      kubectl wait --for=condition=Ready sandbox/python-sandbox-example --namespace default --timeout=120s
      

      您将看到如下所示的输出:

      sandbox.agents.x-k8s.io/python-sandbox-example condition met
      
    4. 运行 kubectl get sandbox 命令以查看有关沙盒的详细信息:

      kubectl get sandbox
      
    5. 在继续操作之前,请验证沙盒化 Pod 是否已准备好接受流量:

      kubectl wait --for=condition=ready pod --selector=sandbox=python-sandbox-example --namespace default --timeout=120s
      

      您将看到如下所示的输出:

      pod/python-sandbox-example condition met
      

    测试沙盒

    现在,您的示例应用已在其安全沙盒中运行,接下来您可以对沙盒进行测试,以确认其正常运行。以下步骤展示了如何使用 kubectl port-forward 命令从 Cloud Shell 环境安全地连接到沙盒 Pod。然后,您可以使用克隆的仓库中包含的 tester.py 脚本向应用的 /execute 端点发送测试命令,并验证该脚本是否返回成功响应。

    1. 设置到 Pod 的端口转发:通过端口转发,您可以从本地 Cloud Shell 环境与在沙盒内运行的 Web 服务器应用进行通信:

      POD_NAME="python-sandbox-example"
      kubectl port-forward "pod/${POD_NAME}" 8888:8888 &
      PF_PID=$!
      trap "kill $PF_PID" EXIT
      sleep 3
      
    2. 安装测试脚本所需的 requests 库:

      pip3 install requests
      
    3. 运行 agent-sandbox/examples/python-runtime-sandbox 目录中的 tester.py 脚本,以验证沙盒端点:

      python3 tester.py 127.0.0.1 8888
      

      tester.py 脚本会执行两项关键测试:一项是健康检查,用于确保应用能够响应;另一项是命令执行测试,用于向沙盒发送 echo 'hello world' shell 命令。

      输出类似于以下内容:

          $ python3 tester.py 127.0.0.1 8888
      --- Testing Health Check endpoint ---
      Sending GET request to http://127.0.0.1:8888/
      Handling connection for 8888
      Health check successful!
      Response JSON: {'status': 'ok', 'message': 'Sandbox Runtime is active.'}
      
      --- Testing Execute endpoint ---
      Sending POST request to http://127.0.0.1:8888/execute with payload: {'command': "echo 'hello world'"}
      Handling connection for 8888
      Execute command successful!
      Response JSON: {'stdout': 'hello world\n', 'stderr': '', 'exit_code': 0}
      

    恭喜!您已在 GKE 集群上成功部署了安全的沙盒环境。现在,您可以向此应用的 /execute 端点发送任何 shell 命令,Agent Sandbox 会在安全屏障内运行该命令,以保护集群的节点和其他工作负载免受不受信任的代码的侵害。Agent Sandbox 可为 AI 代理或任何自动化工作流提供安全可靠的任务执行方式。

    删除沙盒

    完成测试后,您应处置沙盒以释放其计算资源:

    1. 删除您创建的 SandboxClaim 资源:

      kubectl delete -f sandbox-claim.yaml
      

      此操作会指示控制器终止正在运行的 Pod 并删除沙盒资源。

    2. 运行以下命令,验证资源是否已移除:

      kubectl get sandbox,pod -n default
      

      稍等片刻,您应该会看到一条 No resources found 消息,确认沙盒环境已成功清理。

    清理资源

    为避免系统向您的 Google Cloud 账号收取费用,您应删除本文档中创建的资源。以下步骤展示了如何删除 GKE 集群、Artifact Registry 仓库及其包含的容器映像。

    1. 删除 GKE 集群:

      gcloud container clusters delete $CLUSTER_NAME --location=$GKE_LOCATION --quiet
      
    2. 删除您推送到 Artifact Registry 的容器映像:

      gcloud artifacts docker images delete $PYTHON_SANDBOX_IMG --delete-tags --quiet
      
    3. 删除 Artifact Registry 代码库:

      gcloud artifacts repositories delete $REPOSITORY_NAME --location=$GKE_LOCATION --quiet
      

    后续步骤

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