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 的具体设置请参阅身份提供方设置

将要构建的架构

Google Cloud 上的 Claude 应用网关架构图:Claude Code 客户端通过 HTTPS 连接到网关(Cloud Run 或 GKE);网关在 VPC 内运行,并与使用私有 IP、用于存储会话状态的 Cloud SQL 数据库位于同一网络中。网关通过 OIDC 和 Google Workspace 为用户登录,从 Secret Manager 读取配置与密钥,将模型请求转发到 Google Cloud 的 Agent Platform,并在部署时从 Artifact Registry 拉取镜像。

参考配置会预配:

  • 运行网关容器的 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 项目,并拥有创建上述资源的权限
  • 已安装 gcloud CLI 和本地 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 名称

设置一次项目和区域:

export PROJECT_ID=<your-project>
export REGION=us-east5   # Claude 所需模型已在 Model Garden 中发布的区域
gcloud config set project "$PROJECT_ID"

部署网关

以下步骤使用 gcloud 命令预配完整部署。

1

启用 API

启用演练所需的服务 API:

gcloud services enable \
  aiplatform.googleapis.com \
  artifactregistry.googleapis.com \
  sqladmin.googleapis.com \
  secretmanager.googleapis.com \
  iamcredentials.googleapis.com \
  iam.googleapis.com \
  compute.googleapis.com \
  servicenetworking.googleapis.com \
  run.googleapis.com \
  container.googleapis.com

所需 API 取决于部署方式:

  • computeservicenetworking:使用仅私有 IP 的 Cloud SQL 方案时需要
  • run:仅 Cloud Run 需要
  • container:仅 GKE 需要
2

创建服务账号并授予 IAM 权限

网关使用专用服务账号运行,该账号有权调用 Google Cloud 的 Agent Platform。网关通过 VPC 使用密码用户访问 Cloud SQL,因此不需要 Cloud SQL IAM 角色:

gcloud iam service-accounts create claude-gateway --display-name="Claude apps gateway"
SA="claude-gateway@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud projects add-iam-policy-binding "$PROJECT_ID" \
  --member="serviceAccount:${SA}" --role="roles/aiplatform.user" --condition=None

然后在 Model Garden 中为项目启用 Claude 模型。模型只在特定区域发布,因此请查看各模型卡片。

3

构建镜像并推送到 Artifact Registry

按照容器镜像要求,使用 linux-x64 glibc 二进制文件构建镜像,然后推送:

gcloud artifacts repositories create claude-gateway \
  --repository-format=docker --location="$REGION"
gcloud auth configure-docker "${REGION}-docker.pkg.dev" --quiet

# Cloud Run 要求使用 linux/amd64。--provenance=false 可避免生成 Cloud Run
# 会拒绝的 buildx OCI 镜像索引。
docker build --platform=linux/amd64 --provenance=false \
  -t "${REGION}-docker.pkg.dev/${PROJECT_ID}/claude-gateway/gateway:<version>" .
docker push "${REGION}-docker.pkg.dev/${PROJECT_ID}/claude-gateway/gateway:<version>"
4

预配 Cloud SQL for PostgreSQL

通过 Private Services Access 在 VPC 上创建实例,使其不使用公共 IP;这也满足强制执行 constraints/sql.restrictPublicIp 的项目要求:

VPC=cc-gateway-vpc
gcloud compute networks create "$VPC" --subnet-mode=custom
gcloud compute networks subnets create cc-gateway-subnet \
  --network="$VPC" --region="$REGION" --range=10.0.0.0/24

# Private Services Access:每个 VPC 只需配置一次
gcloud compute addresses create "google-managed-services-${VPC}" \
  --global --purpose=VPC_PEERING --prefix-length=16 --network="$VPC"
gcloud services vpc-peerings connect \
  --service=servicenetworking.googleapis.com \
  --ranges="google-managed-services-${VPC}" --network="$VPC"

gcloud sql instances create claude-gateway-db \
  --database-version=POSTGRES_16 --tier=db-g1-small --region="$REGION" \
  --network="projects/${PROJECT_ID}/global/networks/${VPC}" --no-assign-ip
gcloud sql databases create claude_gateway --instance=claude-gateway-db
PGPASS="$(openssl rand -hex 24)"
gcloud sql users create gateway --instance=claude-gateway-db --password="$PGPASS"

PRIVATE_IP="$(gcloud sql instances describe claude-gateway-db \
  --format='value(ipAddresses[0].ipAddress)')"
GATEWAY_POSTGRES_URL="postgres://gateway:${PGPASS}@${PRIVATE_IP}:5432/claude_gateway?sslmode=require"

Cloud Run 或 GKE 运行时必须位于此 VPC 中,或者能够路由到此 VPC。

5

编写 gateway.yaml

upstreams 块通过 auth: {} 指向 Google Cloud 的 Agent Platform,因此网关会使用运行时服务账号提供的 Application Default Credentials 进行身份验证。所有字段请参阅配置参考

listen 中有两个字段取决于网关前端:

  • public_url:在 Cloud Run 或 GKE Ingress 后方运行时必填。网关只根据此值构建 IdP redirect_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 Balancer169.254.0.0/16 加代理专用子网的 CIDR
gce-internal 类的 GKE 内部 Ingress代理专用子网的 CIDR

以下示例采用“Cloud Run 前方部署内部负载均衡器”时的值。

gateway.yaml
listen:
  host: 0.0.0.0
  port: 8080
  public_url: https://claude-gateway.internal.example.com
  trusted_proxies: [169.254.0.0/16, <your-proxy-only-subnet-cidr>]

oidc:
  issuer: https://accounts.google.com
  client_id: <your-oauth-client-id>
  client_secret: ${OIDC_CLIENT_SECRET}           # GKE:${file:/secrets/oidc-client-secret}
  allowed_email_domains: [example.com]
  # Google 会忽略 offline_access;以下设置会生成 refresh Token:
  scopes: [openid, profile, email]
  extra_auth_params: { access_type: offline, prompt: consent }

session:
  jwt_secret: ${GATEWAY_JWT_SECRET}              # GKE:${file:/secrets/jwt-secret}

store:
  postgres_url: ${GATEWAY_POSTGRES_URL}          # GKE:${file:/secrets/postgres-url}

upstreams:
  - provider: vertex
    region: <your-region>                        # 必须与 $REGION 匹配
    project_id: <your-project>
    auth: {}                                     # 通过运行时服务账号使用 ADC

Google id_token 不包含 groups claim。如果以 Google Workspace 作为 IdP,并希望在 managed.policies 中使用基于组的策略,请配置 oidc.google_groups。该设置会使用已获全域授权的服务账号,通过 Admin SDK Directory API 查询各用户所属的组。否则,请改用 email_domain 匹配。

6

将密钥存入 Secret Manager

创建四个密钥,并将 roles/secretmanager.secretAccessor 授予 claude-gateway 服务账号:

密钥来源
gateway-jwt-secretopenssl rand -base64 32
gateway-oidc-client-secretGoogle Cloud Console → OAuth 客户端
gateway-postgres-urlCloud 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} 引用它们。
7

部署

以下命令用于在内部负载均衡器后方进行生产部署。

gcloud run deploy claude-gateway \
  --image="${REGION}-docker.pkg.dev/${PROJECT_ID}/claude-gateway/gateway:<version>" \
  --region="$REGION" \
  --service-account="claude-gateway@${PROJECT_ID}.iam.gserviceaccount.com" \
  --min-instances=1 \
  --timeout=3600 \
  --ingress=internal-and-cloud-load-balancing \
  --network="$VPC" --subnet=cc-gateway-subnet --vpc-egress=private-ranges-only \
  --set-secrets=/etc/claude/gateway.yaml=gateway-config:latest,GATEWAY_JWT_SECRET=gateway-jwt-secret:latest,OIDC_CLIENT_SECRET=gateway-oidc-client-secret:latest,GATEWAY_POSTGRES_URL=gateway-postgres-url:latest \
  --no-invoker-iam-check

通过 --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.app URL,即下方参考资源中的默认设置。要让 *.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-HostX-Forwarded-Proto。用于获取客户端 IP 的 X-Forwarded-For 只有在网关设置了 listen.trusted_proxies 后才会被接受。

8

将网关 URL 推送到开发者计算机

网关现在已经运行,但在网关 URL 下发到开发者计算机之前,开发者无法通过 /login 访问它。在通过 MDM 部署到每台设备的托管设置文件中设置 forceLoginMethodforceLoginGatewayUrl。登录选择器中没有可供开发者手动选择的网关选项。

Terraform 参考

参考部署资源可自动完成本页的 Cloud Run 方案;其中的配置和镜像资源也适用于两种方案:

  • setup.sh:幂等的 gcloud 预配脚本,覆盖从启用 API 到首次部署的完整 Cloud Run 流程
  • terraform/:以基础设施即代码形式实现相同部署,适用于全新环境:先执行定向 apply 创建 Artifact Registry 仓库,再构建并推送镜像,最后执行完整 apply
  • gateway.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 availableconstraints/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 部署

后续步骤

博极客AI是专业人工智能学习平台,提供通俗易懂的AI入门教程、大模型应用、实战项目与行业动态,全站内容免费阅览,零基础也能轻松学AI,适配学生、职场新人及技术爱好者。

© 版权所有 2026 博极客AI,保留一切权利。