在 GKE 上使用智能体沙盒自动评估代码

1. 简介

在此 Codelab 中,您将在 Google Kubernetes Engine (GKE) 上部署 Hackathon Judge 应用,并使用 Kubernetes-sigs Agent Sandbox 安全可靠地运行智能体工作负载。

该平台旨在利用 LLM 代理自动执行黑客马拉松项目的审核、测试和评分流程。由于评判需要评估不受信任的参赛者提交的代码,因此安全的执行沙盒对于防止代码注入、提权或资源滥用至关重要。

您将执行的操作

  • 预配目标 Google Cloud 服务并建立目标 API。
  • 初始化 GKE Autopilot 并安装 Agent Sandbox CRD、集群配置和 Sandbox 路由器。
  • 部署沙盒网关、沙盒声明模板和沙盒 WarmPool。
  • 部署 REST 后端 API、ADK 判断工作器代理和 React 前端界面。
  • 连接外部负载均衡路由,并访问平台以运行安全、沙盒化的评审工作流。

所需条件

  • 网络浏览器,例如 Chrome
  • 启用了结算功能的 Google Cloud 项目。

本 Codelab 中创建的资源的总运行时费用应低于 5 美元。

2. 问题:安全地评估不受信任的代码

黑客马拉松是一种快节奏的创新活动,参与者需要构建并提交项目(通常包括源代码)以供评估。手动评判这些提交内容既耗时又耗费资源。使用 AI 智能体自动评分是一种很有前景的解决方案,但它也带来了一项重大安全挑战:如何安全地运行参与者提供的可能存在 bug、恶意或资源密集型代码?

直接在基础架构上运行不受信任的代码会带来以下风险:

  • 代码注入:恶意脚本可能会尝试访问或修改敏感数据。
  • 权限升级:代码可能会尝试未经授权地访问其他系统或网络资源。
  • 资源滥用:编写不当的代码或拒绝服务攻击可能会消耗过多的 CPU、内存或网络带宽,从而影响其他操作。

为了使用 AI 自动执行黑客马拉松评审,我们需要一种在完全隔离于我们系统的其余部分和其他提交内容的环境中执行提交的代码的方法。

3. 解决方案:GKE 代理沙盒

GKE Agent Sandbox 是一项专门针对此挑战而设计的功能。它有助于管理 GKE 上隔离的、有状态的单副本工作负载,并针对 AI 智能体运行时等应用场景进行了优化,在这些应用场景中,不受信任的代码必须安全高效地执行。

Agent Sandbox 的主要优势包括:

  • 内核级隔离:使用 gVisor 等技术为不受信任的代码提供强大的内核级隔离,防止代码访问主机系统或其他容器。
  • 亚秒级配置:可快速配置沙盒环境(通常不到 1 秒),这对于按需代码评估至关重要。
  • 云原生可扩展性:充分利用 Kubernetes 的强大功能和 GKE 的托管式基础架构。

借助 Agent 沙盒,我们可以为每次黑客马拉松提交创建按需隔离的环境。然后,AI 评判代理可以指示代理沙盒在此安全沙盒中运行测试、编译代码或执行其他评估步骤,而不会影响整个平台的完整性。这提供了一种可扩缩、安全且高效的方式来自动执行黑客马拉松评分。

4. 准备工作

启动 Cloud Shell

点击下方按钮启动 Google Cloud Shell,该 Shell 已预先配置了所需的开发者和云命令行实用程序。

启用 API

在 Cloud Shell 中运行以下命令,以启用运行平台所需的所有目标 Google Cloud API:

gcloud services enable \
  container.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  pubsub.googleapis.com \
  aiplatform.googleapis.com \
  cloudresourcemanager.googleapis.com \
  iam.googleapis.com \
  bigquery.googleapis.com \
  bigqueryconnection.googleapis.com

我们启用这些 API 的原因:Google Cloud 服务默认处于停用状态,以防止未经授权的访问和扣款。我们启用这些特定 API,以激活容器编排 (GKE)、安全容器存储 (Artifact Registry)、无服务器 build 封装 (Cloud Build)、可靠的消息队列 (Pub/Sub)、AI 模型服务 (Vertex AI)、项目配置(Cloud Resource Manager 和 IAM)、无服务器数据分析 (BigQuery) 和数据库级 AI 绑定 (BigQuery Connection)。

5. 设置基础架构

在此步骤中,您将克隆代码库并执行自动化设置脚本,以部署目标云架构和基准集群组件。

克隆代码库

克隆包含所有应用服务、设置脚本和 Kubernetes 清单声明的代码库:

git clone --depth 1 --filter=blob:none --sparse https://github.com/GoogleCloudPlatform/devrel-demos.git
cd devrel-demos
git sparse-checkout set codelabs/ai-toolkit-lab-2/hackathon-judge
cd codelabs/ai-toolkit-lab-2/hackathon-judge

运行部署脚本

deploy.sh 脚本可自动完成云资源、数据库模型和基准 Kubernetes 集群政策的基础设置。

运行脚本:

./deploy.sh

按照交互式 shell 提示提供配置,例如有效项目 ID 和目标区域。该脚本会自动生成本地 .env 配置、绑定资源、编译容器映像并注册 GKE 基准基础架构。

以下是脚本执行的目标操作:

1. 环境配置设置

该脚本会创建一个 .env 配置文件,用于存储 GKE、Pub/Sub、BigQuery 和项目变量参数。动态获取此文件会填充所有后续 Kubernetes 清单定义。

我们为何要配置此环境文件.env 文件集中了配置参数,可确保我们在后续步骤中手动应用的 GKE 清单使用相同的区域设置、项目名称和资源,从而严格将环境配置与源代码分离。

2. Google Cloud CLI 和目标项目配置

该脚本会验证 gcloudbqkubectlenvsubst 实用程序是否已安装,检查身份验证状态,并将有效配置目标锁定到有效的 Google Cloud 项目。

我们为何以活跃项目为目标:设置活跃目标项目可防止 CLI 命令影响您账号中的其他项目,并执行预检身份验证检查,确保设置命令不会因凭据无效而在部署过程中失败。

3. 启用目标 Google Cloud API

该脚本会执行幂等性检查,以验证并启用目标 Google Cloud 服务 API(GKE、Artifact Registry、Cloud Build、Pub/Sub、Vertex AI、BigQuery 和 IAM)。

我们启用 Google Cloud API 的原因:托管式云服务必须先激活,然后才能访问其端点或创建资源。在开始时启用这些 API 可让区域级 GCP API 网关做好准备,以处理后续的资源配置命令。

4. 预配 Artifact Registry Docker 代码库

该脚本会在所选目标位置预配一个名为 hackathon-judge-repo 的 Docker 容器代码库。

我们为何要创建 Artifact Registry 代码库:GKE 集群需要安全访问同一区域网络中的私有容器注册表,才能快速拉取应用映像。Artifact Registry 提供安全私密的托管服务,用于编目、扫描和存储 Docker 容器映像。

5. 预配 GKE Autopilot 集群

该脚本会预配一个名为 hackathon-judge-cluster 的 Google Kubernetes Engine (GKE) Autopilot 集群。

我们部署 GKE Autopilot 集群的原因:GKE Autopilot 会自动管理节点预配、扩缩、健康状况监控和主机操作系统安全升级。它提供生产级容器平台来编排我们的持久性服务,并按需动态调度安全的工作人员沙盒。

6. 配置 Pub/Sub 主题和订阅

该脚本会预配消息主题(judging-tasksjudging-results)以及相应的工作器和 API 订阅。

我们之所以部署 Pub/Sub 主题和订阅,是因为评估提交的代码既缓慢又耗费大量资源。使用消息队列架构可将面向用户的同步 API 与工作器节点分离。API 后端将作业推送到 judging-tasks 主题,工作器代理会在任务可用时拉取任务,从而防止 API 阻塞并提供自动重试功能。

7. 配置 BigQuery 数据集、表和 AI 连接

该脚本会创建 hackathon_judge 数据集,应用结构化 SQL 数据库架构,加载初始记录,并向 BigQuery ML 连接服务账号授予所需的 AI 和存储角色。

8. 使用 Cloud Build 触发容器构建

该脚本会触发 cloudbuild.yaml 定义,以编译我们的 React 界面、Go REST 服务器、Python ADK worker 和 FastAPI 沙盒,将它们打包到标记有有效代码库 Git 提交 SHA 的隔离容器映像中,并将其保存到 Artifact Registry。

9. 注册 Agent Sandbox 自定义资源定义 (CRD)

该脚本会下载并注册最新的 Kubernetes-sigs Agent Sandbox 自定义资源定义(manifest.yamlextensions.yaml),以扩展 GKE 的核心功能。

我们安装 Agent Sandbox 基础架构的原因:标准 Kubernetes 集群不支持分配受保护的按需沙盒。注册 Agent Sandbox CRD 可扩展 GKE 的控制平面,使 Kubernetes 能够使用自定义资源(例如 SandboxTemplate 和 SandboxClaim)以原生方式编排安全的沙盒微容器。

10. 配置命名空间、服务账号和 Workload Identity

该脚本会预配 hackathon-judge 命名空间、注册 Kubernetes 服务账号 (KSA),并建立 Workload Identity 映射,以向 GKE Pod 授予目标 Google Cloud 权限。

11. 部署沙盒路由器

该脚本应用 k8s/sandbox_router.yaml 清单,启动 Sandbox Router 部署和服务,并等待它们达到健康状态。

我们部署沙盒路由器的原因:沙盒路由器是中央内部控制平面网关。它公开了一个简单的 API,ADK 评判工作器代理会调用该 API 来声明、访问或释放安全沙盒,管理路由映射并从应用逻辑中抽象出集群级 Pod 分配。

6. 配置代理沙盒网关、声明和 WarmPool

在此步骤中,您将手动配置专用沙盒网络网关、注册沙盒声明模板,并部署沙盒 WarmPool 以实现超低延迟沙盒化。

来源环境变量

在应用需要环境变量的模板之前,请运行 setup-env.sh 脚本来解析所有必需的变量并将其导出到您的 shell:

source ./setup-env.sh

应用沙盒网关

部署专门配置用于路由沙盒流量的网关:

kubectl apply -f k8s/sandbox-gateway.yaml

我们部署 Sandbox 网关的原因:Sandbox 网关充当安全、高性能的入站控制器,专门用于沙盒路由。它会隔离沙盒网络,提供安全的本地目标,使工作器代理能够与已声明的沙盒通信,而无需向外部公开端点。

应用沙盒声明模板

使用 envsubst 将有效环境变量填充到沙盒模板定义中,然后应用该定义:

source ./setup-env.sh
envsubst < k8s/sandbox-claim-template.yaml | kubectl apply -f -

我们为何要部署沙盒声明模板:沙盒声明模板充当定义环境的蓝图配置。它指定要运行的容器映像(预先打包了开发者工具)、环境参数 (GCP 项目 ID)、端口和资源限制(CPU/内存目标)。它会配置 GKE 以利用 gVisor(gvisor 运行时)运行这些容器实例,从而保证不受信任的参与者代码在额外的内核虚拟化隔离层下运行。

应用沙盒 WarmPool

应用沙盒 WarmPool 以预先初始化正在运行的沙盒:

kubectl apply -f k8s/sandbox-warmpool.yaml

验证暖池备用实例是否已成功启动:

kubectl get pods -n hackathon-judge -l app=sandbox

我们部署沙盒 WarmPool 的原因:按需预配、调度、拉取映像和启动全新容器 Pod 会带来巨大的启动开销(冷启动时间超过 30 秒)。Sandbox WarmPool 会维护一个备用池,其中包含预热的有效沙盒 pod(默认情况下为 5 个副本)。当工作代理请求评估环境时,沙盒路由器会立即分配一个正在运行的预热 pod,从而将启动延迟缩短到亚秒级。

7. 部署应用组件

在安全沙盒基础设施完全处于活动状态的情况下,您现在将部署中央后端 API、工作代理、React Web 界面和 Ingress 网关映射。

部署后端

部署编排器 REST API 后端:

source ./setup-env.sh
envsubst < k8s/backend.yaml | kubectl apply -f -

部署代理

部署 ADK 评判工作器代理:

source ./setup-env.sh
envsubst < k8s/agent.yaml | kubectl apply -f -

部署前端

部署交互式 Web 界面:

source ./setup-env.sh
envsubst < k8s/frontend.yaml | kubectl apply -f -

配置外部网关和路由

部署主网关和 Ingress HTTP 路由,以映射外部客户端流量:

kubectl apply -f k8s/gateway.yaml

我们部署外部 Ingress Gateway 的原因:外部 Gateway 使用 Kubernetes Gateway API 公开我们的服务。它会预配一个负载均衡的公共 IP 地址,并根据路径规则映射路由,将 /api/* 下的 API 请求定向到 Go 后端,并将所有其他客户端 Web 流量 (/) 映射到 React 前端,从而确保公共集群访问安全。

验证发布

阻止 shell 执行,并等待所有三个核心服务部署达到健康、就绪的推出状态:

kubectl rollout status deployment/backend -n hackathon-judge --timeout=300s
kubectl rollout status deployment/agent -n hackathon-judge --timeout=300s
kubectl rollout status deployment/frontend -n hackathon-judge --timeout=300s

8. 验证并使用应用

访问界面

提取新配置的主负载平衡器网关的外部公共 IP 地址:

如需实时查看配置状态,请运行带有 watch 标志 (-w) 的命令,并等待 ADDRESS 字段中填充公共 IP 地址:

kubectl get gateway -n hackathon-judge hackathon-judge-gateway -w

成功完成配置后,您应该会看到类似如下所示的输出:

NAME                      CLASS    ADDRESS          PROGRAMMED   AGE
hackathon-judge-gateway   gke-l7   34.120.120.120   True         3m

当您在 ADDRESS 列中看到有效的公共 IP 地址,并且 PROGRAMMED 状态为 True 时,请按 Ctrl+C 停止监视。

获取网关状态的原因:Gateway API 处理公共入站流量。检查网关状态会返回 Google Cloud 的外部全球负载平衡器分配给集群的公开、经过负载均衡的外部 IP 地址,该地址代表平台的公开地址。

在浏览器中打开分配的公共 IP 地址,以加载黑客马拉松评审员信息中心。

提交任务

  • 使用前端界面前往信息中心,然后选择黑客马拉松。

信息中心

  • 在任何项目中,您都可以点击 Run Agent,让代理根据评分准则对整个项目进行评估。

项目

观看 Privacy Sandbox 启动

监控 hackathon-judge 命名空间中的活跃 pod,以查看沙盒 pod 是否动态声明并预配用于判断执行情况:

kubectl get pods -n hackathon-judge -w

检查工作器代理 Pod 的日志,以了解 ADK 判断评估逻辑的各个步骤:

kubectl logs -l app=agent -n hackathon-judge

检查代理日志的原因:检查工作器代理日志可以实时显示评估流水线的详细内部步骤。您可以跟踪 ADK 代理提取任务、请求沙盒容器、执行编译目标、使用 Gemini 分析报告以及发布统计信息摘要的整个过程。

9. (可选)运作方式

Agent Sandbox 架构

虽然 BigQuery AI 函数非常适合评估基于文本的提交内容和 README 声明,但判断工程项目需要编译代码、安装第三方库和运行实际的测试套件。

运行原始用户代码会带来巨大的安全风险,包括主机遭到入侵、容器逃逸和未经授权的资源访问。GKE 代理 Sandbox 框架通过使用 gVisor (runsc) 虚拟化来编排隔离的 Sandbox 工作负载,从而缓解这些风险。

系统互动流程

下图展示了在安全沙盒化判题执行期间,我们基于事件的系统的各个元素如何进行通信:

互动式工具和组件如何协同工作

  • React 前端界面:提供一个交互式界面,供用户配置条件模型、注册团队、提交项目网址,以及查看最终的评分卡,包括完整的文件差异和工程注释。
  • Go REST 后端 API:用于管理全局 API 端点。它将项目配置存储在 BigQuery 中,并将评判作业推送到 Pub/Sub,以分离繁重的计算执行流水线。
  • Google Pub/Sub:面向消息的代理,可安全地将任务消息保留在队列中,并以异步方式协调 API 与活跃工作器实例之间的通信。
  • Python ADK Worker(主管代理):从 Pub/Sub 中提取任务的后台工作器。它利用 Google 智能体开发套件 (ADK) 启动高级主管智能体,该智能体负责编排评估。主管会调用其主要工具 evaluate_repository 来委托进行深度原始命令测试。
  • Sandbox 路由器和网关 (GKE 控制平面):一种内部控制网关,用于注册标准 Sandbox 自定义资源定义 (SandboxClaimsSandboxTemplates)。它会协调 GKE 网络来分配和保护 Pod,并将连接流返回给工作器客户端。
  • 沙盒 WarmPool:为避免 GKE 容器启动时间过长(“冷启动”时间超过 30 秒),WarmPool 会维护活跃的备用 Pod。当沙盒被声明时,路由器会立即在不到一秒的时间内对其进行映射,然后在释放时安排回收。
  • gVisor (runsc) 隔离:充当安全沙盒边界的用户空间虚拟内核。它会拦截从容器空间到 GKE 节点内核的系统调用,确保危险的原始命令(例如系统脚本或软件包设置)在绝对虚拟化隔离下运行。
  • FastAPI 沙盒运行时:在沙盒容器内运行的轻量级 Python API 服务器。它公开了安全端点(/execute/upload/download),允许外部工作器工具操作文件和触发 shell 任务。
  • Gemini CLI (@google/gemini-cli):安装在沙盒内的自主代理脚本。当使用开发者环境运行时标志 (--yolo) 触发时,它会使用严格的评分说明表 (prompt.md) 和标准定义 (criteria.md) 来执行以下操作:
    • 动态分析代码库层次结构(使用 treeripgrep 等工具)。
    • 自动安装要求(通过 npm installpip installgo build 等命令)。
    • 运行实际的开发测试(例如 npm testpytest)以验证功能。
    • 调用 Vertex AI 模型(通过容器的 Workload Identity 绑定凭据)来评估文件逻辑、对照自述文件交叉检查声明、检测幽灵功能、记录质量问题,以及将结构化统计信息摘要报告写入 evaluation.json
  • 标准开发者环境:在沙盒容器映像中捆绑了 node、npm、yarn、pnpm、python、pip、uv、go、gh、git、tree、ripgrep 和 playwright,为自主分代理提供完整的测试工作区。

10. 清理

为避免系统向您的 Google Cloud 账号持续收取费用,请删除本 Codelab 中创建的资源。

./destroy.sh

清理资源的原因:Google Cloud 采用资源利用率结算模式。即使处于闲置状态,GKE Autopilot 集群、网络负载平衡器和永久性磁盘等有效资源也会产生持续费用。运行此步骤会删除集群命名空间以清除 Kubernetes 对象,并删除 GKE Autopilot 集群主机本身以立即终止所有相关结算费用。

11. 恭喜

恭喜!您已成功在 GKE 上部署了具有代理沙盒的 Hackathon Judge 应用!

您已实现一个安全、现代的事件驱动型 AI 平台,该平台能够在隔离的容器化安全限制下测试和评估不受信任的代码库提交。

您学到的内容

  • GKE 基础架构:如何预配 GKE Autopilot 和支持的 Google Cloud 服务(例如 Pub/Sub 和 BigQuery)。
  • Agent Sandbox 配置:如何配置自定义资源定义、SandboxTemplate、SandboxClaim 和高性能 Sandbox WarmPool。
  • 微服务 Deployment:如何配置 Workload Identity 绑定并部署多组件微服务架构(前端 React、REST Go、工作器 ADK 代理和隔离的沙盒)。
  • 安全沙盒化:如何利用 gVisor 虚拟化容器在 GKE 节点上安全地运行不受信任的第三方命令。

后续步骤

参考文档