1. 简介
概览
此实验演示了如何使用 Eventarc 和 Pub/Sub 服务安全地实现对部署在 Cloud Run 上的 ADK 代理的事件驱动型调用。在大多数情况下,代理由用户或其他代理直接调用。不过,当代理集成到基于事件的现有工作流中时,直接调用需要更改现有软件。根据事件触发代理调用,可将代理纳入现有工作流,而无需更改工作流。
您将执行的操作
在本实验中,您将创建一个 ZooKeeper 代理应用,该应用具有 AI 代理,并使用多种工具来提供有关虚构动物园中动物的信息。

您将以服务的形式将 ZooKeeper 应用部署到 Cloud Run,后者是一个全托管式无服务器计算平台,可在 Google 的基础设施上运行无状态容器。然后,您将设置一个 Eventarc 触发器,该触发器将调用服务端点来异步处理发布到 Pub/Sub 主题的消息。您将确保部署遵循最佳实践,包括使用指定的 IAM 服务账号、授予最低权限的访问权限,以及仅向 Eventarc 公开 ZooKeeper 应用的端点,从而最大限度地减少潜在的攻击面。您将在 Cloud Shell 和 Cloud 控制台的帮助下完成此操作。您将使用 ADK 和 Cloud SDK 库(适用于 Python)。如需检查行为,您将使用 gcloud CLI。
学习内容
- 将 ADK 代理部署到 Google Cloud Run。
- 将 Eventarc 触发器与在 Google Cloud Run 上运行的 ADK 代理集成。
- 借助 Google Cloud IAM,遵循最小权限原则来保护您的部署和与 Eventarc 的集成。
- 将消息发布到 Pub/Sub 并从 Pub/Sub 拉取消息。
- 最大限度地减少部署到 Google Cloud Run 的应用的公开曝光。
所需条件
- Chrome 网络浏览器†
- 个人 Google 账号 ‡
- 已关联到有效结算账号的 Google Cloud 项目
请注意,您的账号必须具有对项目的 IAM 访问权限,以便您预配资源并配置对这些资源的 IAM 访问权限。
† 使用其他浏览器的用户体验可能与实验中描述的不同。
‡ 使用公司账号或学校账号可能无法执行实验中描述的某些操作。
2. 环境设置
为确保实验室的开发环境功能齐全,您将使用 Google Cloud Shell,其中预安装了所有必需的工具。按照说明设置环境。
如果您没有 Google 账号,请创建 Google 账号。
设置说明
- 使用您的 Google 账号登录 Google Cloud 控制台。
- 👉 打开顶部导航栏中的项目选择器(可能会显示“选择项目”或现有项目名称),或按
Ctrl+O键盘快捷键,然后选择现有项目或创建新项目。创建新项目需要几秒钟的时间。等待项目准备就绪,然后使用项目选择器选择该项目。
- 👉 点击 Google Cloud 控制台顶部的 Cloud Shell 图标。(以红色矩形标记):

如果系统询问,请在弹出式对话框中点击 **授权**,以批准 Cloud Shell 使用您账号的凭据。
- 👉💻 确保 gcloud CLI 已配置为使用您选择(或创建)的项目。运行以下命令以检查配置的项目 ID:
您应该会看到类似于以下内容的输出:gcloud config get-value project ,其中Your active configuration is: [cloudshell-19597] [PROJECT_ID]
[PROJECT_ID]是您选择或创建的项目 ID。👉💻 如果您看到其他值,请运行以下命令,将您的项目 ID 配置为 gcloud CLI 命令的默认项目 ID: 例如,如果您的项目 ID 为 lab-project-id-example-123,则命令应为:gcloud config set project [YOUR_PROJECT_ID] 🤔💻 如果您不记得项目 ID,请使用以下命令列出您有权访问的所有项目 ID(从最近的项目开始):gcloud config set project lab-project-id-example-123
gcloud projects list \ --format='value(projectId)' \ --sort-by='~createTime'
- 👉💻 在环境变量中设置用于预配资源的位置以及项目 ID 和编号:
export LOCATION="us-central1" export PROJECT_ID=$(gcloud config get-value project) export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)") - 👉💻 启用本实验所需的 Google API。
请耐心等待,此命令可能需要几分钟时间。成功执行该命令后,您应该会看到类似于以下内容的消息:gcloud services enable \ aiplatform.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ pubsub.googleapis.comOperation "operations/ab12345c-6e7f-8ghi-jkl9-m0e1d23456f7" finished successfully.
3. 部署 ZooKeeper 演示应用
以下步骤将预配和配置资源,包括部署代理式 AI 应用。
设置 Pub/Sub 资源
您将创建两个 Pub/Sub 主题。其中一个将由第三方服务用于向您的智能 AI 应用发送事件。另一个用于发布事件处理结果。
- 👉💻 创建用于触发代理 AI 应用的 Pub/Sub 主题:
gcloud pubsub topics create invoke_agent export INVOKE_TOPIC_ID=$(gcloud pubsub topics describe invoke_agent --format="value(name)") - 👉💻 创建一个 Pub/Sub 主题,供应用发布其响应:
这些命令还会为创建的 Pub/Sub 主题创建订阅。当您运行演示版时,系统会使用该订阅来显示结果。gcloud pubsub topics create agent_responses export RESPONSE_TOPIC_ID=$(gcloud pubsub topics describe agent_responses --format="value(name)") gcloud pubsub subscriptions create agent_responses \ --topic=agent_responses
设置服务账号和项目级层 IAM 政策
您将创建两个服务账号,以根据最小权限原则将 Cloud Run 服务和 Eventarc 触发器的访问权限范围限制为最低限度。Cloud Run 服务需要以下权限:写入日志和轨迹、在 Google Vertex AI 上调用 Gemini LLM,以及将结果发布到 Pub/Sub 主题。Eventarc 触发器的最低访问权限需要具备调用 Cloud Run ZooKeeper 服务和访问 Pub/Sub 以读取已发布事件的权限。这些说明将引导您向触发器的服务账号授予模拟 Pub/Sub 系统服务所需的权限。创建 Eventarc 触发器资源后,您将运行以下命令来授予 roles/run.invoker 角色,以使触发器的服务账号能够调用 Cloud Run 服务。
- 👉💻 为 Cloud Run 服务创建服务账号:
gcloud iam service-accounts create zookeeper-cloudrun-sa export ZOOKEEPER_SA="zookeeper-cloudrun-sa@${PROJECT_ID}.iam.gserviceaccount.com" - 👉💻 向服务账号授予以下权限:写入日志和轨迹,以及在 Vertex AI 上使用 Gemini 模型:
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${ZOOKEEPER_SA}" \ --role="roles/logging.logWriter" \ --condition=None gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${ZOOKEEPER_SA}" \ --role="roles/cloudtrace.agent" \ --condition=None gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${ZOOKEEPER_SA}" \ --role="roles/aiplatform.user" \ --condition=None - 👉💻 向服务账号授予向“agent_responses”主题发布消息的权限:
gcloud pubsub topics add-iam-policy-binding agent_responses \ --member="serviceAccount:${ZOOKEEPER_SA}" \ --role="roles/pubsub.publisher" - 👉💻 为 Eventarc 触发器创建服务账号:
gcloud iam service-accounts create zookeeper-trigger-sa export TRIGGER_SA="zookeeper-trigger-sa@${PROJECT_ID}.iam.gserviceaccount.com" - 👉💻 向 Pub/Sub 系统服务账号授予权限,以发出经过身份验证的推送请求:
如果项目是 2021 年 4 月 8 日之后创建的,则此命令是可选的。gcloud iam service-accounts add-iam-policy-binding "${TRIGGER_SA}" \ --member="serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" \ --role="roles/iam.serviceAccountTokenCreator"
将 ZooKeeper 应用部署到 Cloud Run
您将从 GitHub 下载演示应用的相应代码。并将代码部署到 Cloud Run。
- 👉💻 下载代理式 AI 应用:
这些命令使用演示应用文件夹的 Git 稀疏检出,以缩短下载时间。mkdir zoo-keeper-lab && cd zoo-keeper-lab git init git remote add origin https://github.com/GoogleCloudPlatform/devrel-demos git config set core.sparseCheckout true echo "ai-ml/agent-labs/adk_invoke_with_pubsub/" >> .git/info/sparse-checkout git pull origin main --depth 1 cd ai-ml/agent-labs/adk_invoke_with_pubsub/ - 👉💻 将代理型 AI 应用部署到 Cloud Run:
gcloud run deploy zookeeper-agent \ --region="${LOCATION}" \ --source="." \ --no-allow-unauthenticated \ --quiet \ --service-account="${ZOOKEEPER_SA}" \ --set-env-vars="REPLY_TOPIC_ID=${RESPONSE_TOPIC_ID}"
配置 Eventarc 触发器
准备好所有资源(Pub/Sub 主题、IAM 服务账号和 Cloud Run 服务)后,就可以设置 Eventarc 触发器资源了。您将创建 Eventarc 触发器资源,并向触发器的服务账号授予调用 Cloud Run 服务的权限。
- 👉💻 创建 Eventarc 触发器:
gcloud eventarc triggers create invoke-agent \ --location="${LOCATION}" \ --destination-run-service="zookeeper-agent" \ --destination-run-path="/zookeeper" \ --destination-run-region="${LOCATION}" \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --transport-topic="${INVOKE_TOPIC_ID}" \ --service-account="${TRIGGER_SA}" - 👉💻 向触发器的服务账号授予调用 Cloud Run 服务的权限:
gcloud run services add-iam-policy-binding zookeeper-agent \ --region="${LOCATION}" \ --member="serviceAccount:${TRIGGER_SA}" \ --role="roles/run.invoker"
4. 查看解决方案的运作方式
现在,查看您刚刚部署的内容。下图反映了所有资源以及它们如何相互交互。您将使用 gcloud CLI 将消息发布到“invoke_agent”主题。这将模拟第三方服务记录到消息传递服务中的事件,以调用代理式 AI 应用。

部署遵循最小权限原则,因此非常安全。Cloud Run 服务强制执行身份验证(请参阅上一部分中第 9 步的 --no-allow-unauthenticated 实参)。只有具有 roles/run.invoker 或类似权限的身份才能调用该服务。此角色仅授予 Eventarc 触发器的服务账号。同样,对“invoke_agent”主题的访问权限也已最小化,以禁止未经授权发布事件。仍然可以直接调用 ZooKeeper 代理,绕过向 Pub/Sub 主题发布消息的步骤。请参阅第 6 部分,了解如何隐藏应用的端点,使其无法公开访问。
运行工作流
您将通过向 ZooKeeper 发布自然语言问题来模拟外部事件。
👉💻 使用以下命令将消息发布到 Pub/Sub 主题:
gcloud pubsub topics publish invoke_agent \
--message='{"user_id": "important_app", "prompt": "How many animals are in the zoo?"}'
实际上,活动信息的可读性可能较差。为了处理该事件,代理型 AI 应用需要获得有关事件格式、数据以及代理应如何处理事件信息的详细说明。
您可以检查代理是否已收到事件、处理请求并将响应发布到“agent_responses”主题。如需读取响应,您将使用“agent_responses”订阅(此 Codelab 为主题和响应订阅使用相同的 ID)。
👉💻 使用以下命令从 Pub/Sub 订阅中读取代理的响应:
gcloud pubsub subscriptions pull agent_responses --auto-ack
输出将打印一个表格,其中包含消息元数据和载荷,载荷中包含“动物园中有 33 个物种”这一答案。--auto-ack 标志会在拉取消息后自动确认消息,因此不会再次传送消息。
运作方式
打开 Cloud Shell 编辑器,然后查看 ~/zoo-keeper-lab 文件夹下的文件,即可查看 agentic AI 应用的源代码。您还可以在 GitHub 上查看源代码。
- main.py 实现了一个基本的 FastAPI Web 应用,其中包含一个处理 Eventarc 事件的处理脚本。
- processor.py 会解析事件的消息,以检索用户 ID 和请求。然后,它会在 ADK 运行程序中创建一个新会话,并调用 Zookeeper 代理来处理请求。代理的响应会发布到“agent_responses”Pub/Sub 主题。
- 子文件夹 zookeeper_agent 包含 ADK 代理的源代码。您可以从应用的根文件夹运行
adk run zookeeper_agent命令,以使用 ADK CLI 与代理互动。
问题排查操作说明
如果上述任何命令失败,请仔细阅读错误消息。如果向 Cloud Run 的部署失败,第一步是确定失败发生在流程的哪个阶段。
- 如果“gcloud run deploy...”命令的输出报告 build 失败,请查看输出中的 build 日志网址,并在单独的窗口中打开该网址。
- 如果输出显示“服务启动失败”或类似内容,则表示服务已部署,但执行失败,健康检查未通过。在这种情况下,请打开日志浏览器,或参阅下段中的 gcloud CLI 命令。读取日志以查找失败的根本原因。
如果您向 Pub/Sub 发布了消息,但代理未响应或响应看起来很奇怪,该怎么办?
👉💻 使用以下命令读取最近一次执行发布的应用日志:
gcloud logging read \
'resource.type = "cloud_run_revision" AND \
resource.labels.service_name = "zookeeper-agent" AND \
resource.labels.location = "us-central1"'
日志会跟踪执行情况并报告错误,例如消息载荷不正确或无法解析、来自 Gemini 模型的响应无效、环境设置无效以及其他可能的问题。
5. 强化部署安全性
您部署的 Cloud Run 服务公开了一个可供互联网上的任何人调用的公共端点。虽然端点受到保护,可防止未经授权的调用,并且会严格验证请求的结构,但它仍然会留下此攻击向量,从而导致拒绝服务和拒绝钱包攻击。由于当前设计中服务的唯一调用路径是通过 Eventarc 触发器,因此服务无需将其端点公开给互联网。
👉💻 通过将对服务的调用限制为仅来自有限的来源集合(包括 Eventarc 触发器)来关闭此攻击途径:
gcloud run services update zookeeper-agent --region=${LOCATION} --ingress=internal
现在,如果您尝试从本地机器调用服务的网址,将会收到“404 找不到网页”错误。
👉💻 使用 curl 向服务端点发送请求:
URL=$(gcloud run services describe zookeeper-agent --region=${LOCATION} --format='value(status.url)')
curl -X POST -d '{}' "${URL}/zookeeper"
您将看到类似于以下内容的输出:
<html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>404 Page not found</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Page not found</h1> <h2>The requested URL was not found on this server.</h2> <h2></h2> </body></html>
更改后,除非您从同一项目中的 VPC、您的修订版本配置为向其发送流量的共享 VPC 网络或属于 VPC Service Controls 边界的主机进行调用,否则无法再通过调用 Cloud Run 服务端点直接调用 ZooKeeper。
6. 总结
恭喜!您已成功设置环境,以异步方式调用由传入事件触发的 agentic AI 应用。
清理
请注意,保留您预配的资源可能会导致您的结算账号产生费用。如果您不打算将此环境用于更多实验,并且为了避免产生即将到来的费用,建议您删除在此 Codelab 期间创建的资源。
您可以通过以下两种方法实现此目的:
方法 1:关停项目
关闭(删除)项目会释放项目的所有资源和数据,并解除结算账号的关联。使用此方法可避免因本 Codelab 中使用的任何资源或数据而产生进一步的费用。使用以下命令关闭项目:
gcloud projects delete $(gcloud config get-value project) --quiet
方法 2:删除项目中的资源
删除 Cloud Run 服务可避免因使用无服务器平台而产生更多费用。请注意,此方法不会完全移除在实验期间生成的所有数据,例如 Cloud Build 和应用日志、容器映像等。运行以下命令以删除服务:
gcloud run services delete zookeeper-agent --region=${LOCATION}
Eventarc 触发器定义和 Pub/Sub 主题不会产生管理费用(如需了解详情,请参阅 Eventarc 价格和 Pub/Sub 价格)。
详细了解如何关停项目。
后续步骤
- 如需详细了解代码,请查看 GitHub 上的演示。
- 查看用于协调对不同企业系统的访问的架构
- 了解如何使用 Eventarc 触发器触发 Cloud Run
- 详细了解 ADK