Claude Code 网关与用量
Claude Code 网关与用量
Google Cloud 部署示例
6 分钟阅读
在 Google Cloud 上部署 Claude 应用网关
在 Google Cloud 上运行 Claude 应用网关的完整示例:使用 Cloud Run 或 GKE、Cloud SQL for PostgreSQL、Secret Manager,以及通过服务账号向 Google Cloud 的 Agent Platform 进行身份验证。
本页演示在 Google Cloud 上运行 Claude 应用网关的一种方式。此配置是面向客户自主管理基础设施的可运行示例,并非受支持的生产部署方案;请先用它了解各组件如何协同工作,再根据自身环境进行调整。与平台无关的要求请参阅部署指南。
本示例在 Google Cloud 上预配 Claude 应用网关,以 Google Cloud 的 Agent Platform 作为模型上游,并选择 Cloud Run 或 GKE 提供计算资源。示例身份提供方(IdP)为 Google Workspace,但任何兼容 OpenID Connect(OIDC)的 IdP 均可使用,只需更改 oidc 块。不同 IdP 的具体设置请参阅身份提供方设置。
将要构建的架构
参考配置会预配:
- 运行网关容器的 Cloud Run 服务或 GKE Deployment
- 用于存储网关镜像的 Artifact Registry 仓库
- 仅使用私有 IP 的 Cloud SQL for PostgreSQL 实例,用作网关的存储
- 用于保存
gateway.yaml、JWT 签名密钥、OIDC 客户端密钥和 Postgres URL 的 Secret Manager 密钥 - 拥有
roles/aiplatform.user的服务账号:在 Cloud Run 上直接挂载,或在 GKE 上通过 Workload Identity 绑定 - 提供 HTTPS 的前端:Cloud Run 使用内部 Application Load Balancer,GKE 使用
gce-internal类的内部 GKE Ingress
前提条件
- 已启用结算功能的 GCP 项目,并拥有创建上述资源的权限
- 已安装
gcloudCLI 和本地 Docker,并已通过gcloud auth login完成身份验证 - 对于 GKE 方案:安装
kubectl,并在下文演练创建的 VPC 中准备一个 GKE 集群 - 能够访问 Model Garden 中所需的 Claude 模型,并选择已发布这些模型的区域
- 一个 Google Workspace OAuth 2.0 Web 应用客户端,其重定向 URI 为
https://<gateway-host>/oauth/callback;请参阅身份提供方设置 - 网关使用的 TLS 主机名,通常是指向负载均衡器的内部 DNS 名称
设置一次项目和区域:
部署网关
以下步骤使用 gcloud 命令预配完整部署。
启用 API
启用演练所需的服务 API:
所需 API 取决于部署方式:
compute和servicenetworking:使用仅私有 IP 的 Cloud SQL 方案时需要run:仅 Cloud Run 需要container:仅 GKE 需要
创建服务账号并授予 IAM 权限
网关使用专用服务账号运行,该账号有权调用 Google Cloud 的 Agent Platform。网关通过 VPC 使用密码用户访问 Cloud SQL,因此不需要 Cloud SQL IAM 角色:
然后在 Model Garden 中为项目启用 Claude 模型。模型只在特定区域发布,因此请查看各模型卡片。
构建镜像并推送到 Artifact Registry
按照容器镜像要求,使用 linux-x64 glibc 二进制文件构建镜像,然后推送:
预配 Cloud SQL for PostgreSQL
通过 Private Services Access 在 VPC 上创建实例,使其不使用公共 IP;这也满足强制执行 constraints/sql.restrictPublicIp 的项目要求:
Cloud Run 或 GKE 运行时必须位于此 VPC 中,或者能够路由到此 VPC。
编写 gateway.yaml
upstreams 块通过 auth: {} 指向 Google Cloud 的 Agent Platform,因此网关会使用运行时服务账号提供的 Application Default Credentials 进行身份验证。所有字段请参阅配置参考。
listen 中有两个字段取决于网关前端:
public_url:在 Cloud Run 或 GKE Ingress 后方运行时必填。网关只根据此值构建 IdPredirect_uri和发现文档,绝不使用X-Forwarded-*请求头。trusted_proxies:前端的来源范围。只有当 TCP 对等方位于此列表中时,网关才会接受X-Forwarded-For,然后沿请求链跳过受信任的跃点,使按 IP 的登录速率限制和审计事件记录开发者 IP,而不是负载均衡器 IP。
请根据前端设置 trusted_proxies。下表未列出 gce 类的外部 GKE Ingress:它会预配公共转发规则地址,而 /login 的私有网络检查会拒绝该地址。
| 前端 | trusted_proxies |
|---|---|
| 直接访问 Cloud Run,不使用负载均衡器 | [169.254.0.0/16] |
| Cloud Run 前方的内部 Application Load Balancer | 169.254.0.0/16 加代理专用子网的 CIDR |
gce-internal 类的 GKE 内部 Ingress | 代理专用子网的 CIDR |
以下示例采用“Cloud Run 前方部署内部负载均衡器”时的值。
Google id_token 不包含 groups claim。如果以 Google Workspace 作为 IdP,并希望在 managed.policies 中使用基于组的策略,请配置 oidc.google_groups。该设置会使用已获全域授权的服务账号,通过 Admin SDK Directory API 查询各用户所属的组。否则,请改用 email_domain 匹配。
将密钥存入 Secret Manager
创建四个密钥,并将 roles/secretmanager.secretAccessor 授予 claude-gateway 服务账号:
| 密钥 | 来源 |
|---|---|
gateway-jwt-secret | openssl rand -base64 32 |
gateway-oidc-client-secret | Google Cloud Console → OAuth 客户端 |
gateway-postgres-url | Cloud SQL 步骤中的 $GATEWAY_POSTGRES_URL |
gateway-config | 上一步的完整 gateway.yaml |
将密钥传入容器的方式因部署方案而异:
- 在 GKE 上,通过 Secret Manager CSI driver 将密钥挂载为文件,
gateway.yaml使用${file:/secrets/...}引用。 - 在 Cloud Run 上,无法将多个密钥挂载到同一目录,因此将
gateway.yaml挂载为文件,并将另外三个密钥注入环境变量;gateway.yaml应分别使用${GATEWAY_JWT_SECRET}、${OIDC_CLIENT_SECRET}和${GATEWAY_POSTGRES_URL}引用它们。
部署
- Cloud Run
- GKE
以下命令用于在内部负载均衡器后方进行生产部署。
通过 --network、--subnet 和 --vpc-egress=private-ranges-only 配置 Direct VPC egress 后,服务可以直接访问 Cloud SQL 私有 IP。发往 Google Cloud Agent Platform 端点和 accounts.google.com 的公共出站流量会直接访问互联网,不经过 VPC,因此无需 Cloud NAT。
必须开放或禁用调用方 IAM 检查。网关自行运行 OIDC,客户端也不携带 GCP Token,因此 Cloud Run 调用方检查必须允许未经身份验证的请求。请求到达容器后,由网关的 OIDC 登录进行身份验证,并通过 allowed_email_domains 限制允许登录的域。
有两个标志可以允许未经身份验证的请求:
--no-invoker-iam-check:禁用检查,无需管理allUsers绑定,而且可在 Domain Restricted Sharing 下使用--allow-unauthenticated:向allUsers授予run.invoker角色;如果组织不允许使用--no-invoker-iam-check,请选择此项
通过 --ingress 实施的入站限制是独立于调用方检查的另一层保护;请保留该设置,将服务限制在企业网络内。
默认情况下,Cloud Run 的 *.run.app URL 解析到公共地址,因此会被 /login 的私有网络检查拒绝。以下两种拓扑可以为开发者提供能够解析到私有地址的主机名,但 Cloud Run 不会替你预配:
- 内部 Application Load Balancer,即上述部署命令假定的拓扑:使用
--ingress=internal-and-cloud-load-balancing部署,在服务前方预配带有内部 DNS 名称和证书的内部 Application Load Balancer,并将listen.public_url设为该主机名。 - 仅允许内部入站且不使用负载均衡器:使用
--ingress=internal部署,并让listen.public_url保持为*.run.appURL,即下方参考资源中的默认设置。要让*.run.app解析到私有地址,网络团队必须已经为 Google API 运行 Private Service Connect 端点,配置将*.run.app解析到该端点的 Cloud DNS 私有区域,并建立从本地网络到该端点的路由。
Google 的 Cloud Run 私有网络指南介绍了两种方案所需的基础设施。网关通过私有主机名提供服务后,请验证登录;在此之前,可通过 Cloud Run 日志确认容器已经启动。
首次登录前,请将 OAuth 客户端的授权重定向 URI 更新为 <public_url>/oauth/callback。更改 public_url 后要重新部署,因为网关只根据该设置构建公开来源,并忽略 X-Forwarded-Host 和 X-Forwarded-Proto。用于获取客户端 IP 的 X-Forwarded-For 只有在网关设置了 listen.trusted_proxies 后才会被接受。
将网关 URL 推送到开发者计算机
网关现在已经运行,但在网关 URL 下发到开发者计算机之前,开发者无法通过 /login 访问它。在通过 MDM 部署到每台设备的托管设置文件中设置 forceLoginMethod 和 forceLoginGatewayUrl。登录选择器中没有可供开发者手动选择的网关选项。
Terraform 参考
参考部署资源可自动完成本页的 Cloud Run 方案;其中的配置和镜像资源也适用于两种方案:
setup.sh:幂等的gcloud预配脚本,覆盖从启用 API 到首次部署的完整 Cloud Run 流程terraform/:以基础设施即代码形式实现相同部署,适用于全新环境:先执行定向 apply 创建 Artifact Registry 仓库,再构建并推送镜像,最后执行完整 applygateway.yaml.example以及用于 distroless 运行时镜像的Dockerfile
这些资源默认将 Cloud Run 入站设置为 internal,因此不需要负载均衡器。要匹配本页在 ALB 后方进行生产部署的方式,请运行 setup.sh 并设置 INGRESS=internal-and-cloud-load-balancing,或将 Terraform 变量 ingress 设为 INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER。这些资源还默认通过向 allUsers 授予 run.invoker 来配置调用方层,而不是使用 --no-invoker-iam-check,与本页演练正好相反;两种方式都可行,应根据组织的策略约束进行选择。
这些资源仅作为可运行示例提供,并不是受支持的生产交付物;请评审后根据自身环境进行调整。
故障排除
网关启动和登录错误请参阅与平台无关的故障排除表。以下条目仅适用于 Google Cloud。
| 症状 | 原因 | 修复方法 |
|---|---|---|
Cloud Run 在请求到达容器前返回 403 Forbidden | 调用方 IAM 检查仍处于启用状态 | 使用 --no-invoker-iam-check 部署,或向 allUsers 授予 run.invoker 角色并使用 --allow-unauthenticated |
--no-invoker-iam-check 被拒绝,并显示 invoker_iam_disabled is not currently available | 被 constraints/run.managed.requireInvokerIam 阻止 | 使用 --allow-unauthenticated。如果通过 constraints/iam.allowedPolicyMemberDomains 实施的 Domain Restricted Sharing 也阻止此操作,请使用 GKE 方案;该方案在网络层公开网关,无需 allUsers 绑定。 |
部署时出现 Container manifest type … must support amd64/linux | 镜像在非 amd64 主机上构建,或 buildx 生成了 OCI 镜像索引 | 使用 --platform=linux/amd64 --provenance=false 构建 |
| Cloud Run 上的网关启动时因 Postgres 连接超时而退出 | 服务未关联 VPC,或者 Cloud SQL 在该 VPC 上没有私有 IP;存储会在等待 5 秒后停止 | 使用 --network 和 --subnet 部署以配置 Direct VPC egress,并使用 --no-assign-ip 创建 Cloud SQL 实例,同时让 --network 指向同一个 VPC |
Google Cloud 的 Agent Platform 请求返回 403 PERMISSION_DENIED | 运行时未使用 claude-gateway 服务账号,或未在项目的 Model Garden 中启用该模型 | 在 Cloud Run 上设置 --service-account,或在 GKE 上绑定 Workload Identity,并在目标区域的 Model Garden 中启用每个 Claude 模型 |
| 流式响应在固定时长后中断 | 前端请求超时:GKE Ingress 后方的负载均衡器后端服务默认 30 秒,Cloud Run 默认 300 秒 | 在 GKE 上关联提高了 timeoutSec 的 BackendConfig,或在 Cloud Run 上使用 --timeout=3600 部署 |
后续步骤
- 配置参考:所有
gateway.yaml选项,包括managed.policies和telemetry - 部署和运维:IdP 设置、健康检查、JWT 密钥轮换、升级和安全模型
- Claude 应用网关概述:快速入门和连接开发者
桂公网安备45010502001169号