SpyBara
Go Premium

claude-apps-gateway-on-gcp.md 2026-11-10 21:57 UTC to 2026-11-11 22:59 UTC

This page contains 52 additions and 52 deletions.

2026
Fri 6 23:01 Wed 11 22:59

Deploy gateway aplikasi Claude di Google Cloud

Contoh praktis menjalankan gateway aplikasi Claude di Google Cloud: Cloud Run atau GKE, Cloud SQL untuk PostgreSQL, Secret Manager, dan autentikasi service-account ke Agent Platform Google Cloud.

[!NOTE]

Halaman ini menjelaskan satu cara untuk menjalankan gateway aplikasi Claude di Google Cloud. Konfigurasi ini adalah contoh kerja untuk infrastruktur yang dikelola pelanggan daripada penyebaran produksi yang didukung; gunakan ini untuk melihat bagaimana potongan-potongan cocok bersama sebelum menyesuaikannya dengan lingkungan Anda sendiri. Untuk persyaratan yang tidak bergantung pada platform, lihat panduan penyebaran.

Contoh ini menyediakan gateway aplikasi Claude di Google Cloud dengan Agent Platform Google Cloud sebagai upstream model, menggunakan Cloud Run atau GKE untuk komputasi. Google Workspace adalah penyedia identitas contoh (IdP), tetapi penyedia IdP yang sesuai dengan OpenID Connect (OIDC) apa pun berfungsi; hanya blok oidc yang berubah. Lihat Penyiapan penyedia identitas untuk detail per-IdP.

Apa yang akan Anda bangun

Diagram gateway aplikasi Claude di Google Cloud: klien Claude Code terhubung melalui HTTPS ke gateway (Cloud Run atau GKE), yang berjalan di dalam VPC bersama database Cloud SQL IP pribadi untuk status sesi. Gateway menandatangani pengguna melalui OIDC terhadap Google Workspace, membaca konfigurasi dan rahasia dari Secret Manager, meneruskan permintaan model ke Agent Platform, dan menarik gambarnya dari Artifact Registry saat penyebaran.

Deployment ini terdiri dari:

  • Layanan Cloud Run atau GKE Deployment yang menjalankan kontainer gateway
  • Repositori Artifact Registry untuk gambar gateway
  • Instans Cloud SQL untuk PostgreSQL, IP pribadi saja, untuk store gateway
  • Rahasia Secret Manager untuk gateway.yaml, kunci penandatanganan JWT, rahasia klien OIDC, dan URL Postgres
  • Service account dengan roles/aiplatform.user, terlampir langsung di Cloud Run atau terikat melalui Workload Identity di GKE
  • Front end HTTPS yang Anda sediakan: internal Application Load Balancer di depan Cloud Run, yang menjadi acuan konfigurasi gateway dalam panduan ini tetapi tidak dibuat oleh panduan ini, atau GKE Ingress internal dari kelas gce-internal di GKE

Prasyarat

  • Proyek GCP dengan penagihan diaktifkan, dan izin untuk membuat sumber daya di atas
  • CLI gcloud, diautentikasi dengan gcloud auth login, dan Docker dipasang secara lokal
  • Untuk jalur GKE: kubectl, dan kluster GKE di VPC yang dibuat dalam panduan di bawah
  • Akses ke model Claude yang Anda butuhkan di Model Garden, di wilayah yang menerbitkannya
  • Klien aplikasi web OAuth 2.0 Google Workspace dengan URI pengalihan https://<gateway-host>/oauth/callback; lihat Penyiapan penyedia identitas
  • Nama host TLS untuk gateway, biasanya nama DNS internal yang menunjuk ke load balancer

Atur proyek dan wilayah sekali:

export PROJECT_ID=<your-project>
export REGION=us-east5   # a region where the Claude models you need are published in Model Garden
gcloud config set project "$PROJECT_ID"

Men-deploy gateway

Langkah-langkah di bawah ini menyediakan deployment lengkap dengan perintah gcloud.

1. Aktifkan API

Aktifkan API layanan yang digunakan dalam panduan ini:

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 yang Anda perlukan bergantung pada jalur deployment:

  • compute dan servicenetworking: diperlukan untuk jalur Cloud SQL dengan IP privat
  • run: hanya Cloud Run
  • container: hanya GKE

2. Buat service account dan berikan IAM

Gateway berjalan sebagai service account khusus dengan izin untuk memanggil Agent Platform milik Google Cloud. Gateway menjangkau Cloud SQL melalui VPC dengan pengguna berbasis kata sandi, sehingga tidak diperlukan peran IAM Cloud SQL:

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

Kemudian aktifkan model Claude untuk proyek di Model Garden; model dipublikasikan ke region tertentu, jadi periksa setiap kartu model.

3. Build dan push image ke Artifact Registry

Build image sesuai persyaratan image container, menggunakan binary glibc linux-x64, lalu push image tersebut:

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

# Cloud Run requires linux/amd64. --provenance=false avoids a buildx OCI
# image index that Cloud Run rejects.
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. Sediakan Cloud SQL untuk PostgreSQL

Buat instance pada VPC melalui Private Services Access sehingga instance tidak memiliki IP publik; ini juga memenuhi persyaratan proyek yang memberlakukan 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: one-time per 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"

Runtime Cloud Run atau GKE harus berada di VPC ini, atau dirutekan ke dalamnya.

5. Tulis gateway.yaml

Blok upstreams mengarah ke Agent Platform milik Google Cloud dengan auth: {}, sehingga gateway melakukan autentikasi melalui Application Default Credentials dari service account runtime. Lihat referensi konfigurasi untuk setiap field.

Dua field listen menjelaskan apa yang berada di depan gateway:

  • public_url: origin https:// eksternal, wajib untuk setiap bind non-loopback; lihat referensi listen. Gateway membangun redirect_uri IdP dan dokumen discovery-nya hanya dari nilai ini, tidak pernah dari header X-Forwarded-*.
  • trusted_proxies: rentang sumber front end. Gateway hanya menghormati X-Forwarded-For ketika peer TCP ada dalam daftar ini, lalu menelusuri rantai melewati hop tepercaya, sehingga rate limit masuk per IP dan peristiwa audit mencatat IP developer alih-alih IP load balancer.

Atur trusted_proxies agar sesuai dengan front end Anda. GKE Ingress eksternal dengan class gce tidak tercantum: Ingress tersebut menyediakan alamat forwarding-rule publik, yang ditolak oleh pemeriksaan jaringan privat /login.

Front end trusted_proxies
Cloud Run dijangkau langsung, tanpa load balancer [169.254.0.0/16]
Internal Application Load Balancer di depan Cloud Run 169.254.0.0/16 ditambah CIDR proxy-only subnet Anda
GKE internal Ingress, class gce-internal CIDR proxy-only subnet Anda

Contoh di bawah ini menggunakan nilai untuk load balancer internal di depan Cloud Run.

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 ignores offline_access; these yield refresh tokens:
  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}
  # readiness_grace_seconds: 300                 # keep passing the readiness probe
# through a Cloud SQL failover

upstreams:
  - provider: vertex
    region: <your-region>                        # must match $REGION
    project_id: <your-project>
    auth: {} # ADC via the runtime service account

[!NOTE]

id_token Google tidak membawa klaim groups. Untuk menggunakan kebijakan berbasis grup di managed.policies dengan Google Workspace sebagai IdP, konfigurasikan oidc.google_groups, yang mencari grup setiap pengguna melalui Admin SDK Directory API menggunakan service account dengan domain-wide delegation. Tanpa itu, lakukan pencocokan berdasarkan email_domain sebagai gantinya.

6. Simpan secret di Secret Manager

Buat empat secret dan berikan roles/secretmanager.secretAccessor kepada service account claude-gateway:

Secret Sumber
gateway-jwt-secret openssl rand -base64 32
gateway-oidc-client-secret Google Cloud Console → OAuth client
gateway-postgres-url $GATEWAY_POSTGRES_URL dari langkah Cloud SQL
gateway-config gateway.yaml lengkap dari langkah sebelumnya

Cara secret mencapai container berbeda menurut jalurnya:

  • Di GKE, secret di-mount sebagai file melalui Secret Manager CSI driver, dan gateway.yaml mereferensikan ${file:/secrets/...}.
  • Di Cloud Run, yang tidak dapat me-mount beberapa secret ke dalam satu direktori, gateway.yaml di-mount sebagai file dan tiga secret lainnya diinjeksikan sebagai environment variable, sehingga gateway.yaml mereferensikan ${GATEWAY_JWT_SECRET}, ${OIDC_CLIENT_SECRET}, dan ${GATEWAY_POSTGRES_URL} sebagai gantinya.

7. Deploy

[tab] Cloud Run

Perintah di bawah ini men-deploy untuk produksi di belakang load balancer internal.

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 \
  --max-instances=8 \
  --timeout=3600 \
  --ingress=internal \
  --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

Direct VPC egress, melalui --network, --subnet, dan --vpc-egress=private-ranges-only, memungkinkan layanan menjangkau IP privat Cloud SQL secara langsung. Egress publik ke endpoint Agent Platform milik Google Cloud dan accounts.google.com langsung menuju internet alih-alih melalui VPC, sehingga Cloud NAT tidak diperlukan.

[!NOTE]

Setiap instance menampung hingga store.max_connections koneksi Postgres, lima secara default. Gunakan Menentukan ukuran connection pool untuk memeriksa --max-instances=8 terhadap koneksi yang tersisa di database Anda untuk gateway, dan sertakan instance tambahan yang dimulai oleh rolling update.

Pemeriksaan invoker IAM harus terbuka atau dinonaktifkan. Gateway menjalankan OIDC-nya sendiri dan klien-kliennya tidak membawa token GCP, sehingga pemeriksaan invoker Cloud Run harus menerima permintaan yang tidak terautentikasi. Proses masuk OIDC gateway mengautentikasi permintaan setelah permintaan tersebut mencapai container, dengan allowed_email_domains yang membatasi domain mana yang boleh masuk.

Dua flag menerima permintaan yang tidak terautentikasi:

  • --no-invoker-iam-check: menonaktifkan pemeriksaan tanpa binding allUsers yang perlu dikelola, dan berfungsi di bawah Domain Restricted Sharing
  • --allow-unauthenticated: memberikan peran run.invoker kepada allUsers; gunakan ini jika organisasi Anda tidak mengizinkan --no-invoker-iam-check

Pembatasan ingress melalui --ingress adalah lapisan terpisah dan independen dari pemeriksaan invoker; tetap atur untuk membatasi layanan ke jaringan perusahaan Anda.

Secara default, URL Cloud Run *.run.app di-resolve ke alamat publik, yang ditolak oleh pemeriksaan jaringan privat /login. Dua topologi memberikan developer hostname yang dapat di-resolve secara privat, dan Cloud Run tidak menyediakan keduanya untuk Anda:

  • Internal Application Load Balancer, topologi yang diasumsikan oleh gateway.yaml di halaman ini: sediakan internal Application Load Balancer di depan layanan dengan nama DNS internal dan sertifikat, lalu atur listen.public_url ke hostname tersebut. Pengaturan ingress internal sudah menerima traffic dari internal Application Load Balancer; internal-and-cloud-load-balancing juga menerima external Application Load Balancer, yang alamat publiknya ditolak oleh pemeriksaan jaringan privat /login, sehingga tidak ada topologi di halaman ini yang memerlukannya.
  • Ingress khusus internal tanpa load balancer: biarkan perintah deploy apa adanya dan biarkan listen.public_url sebagai URL *.run.app, yang merupakan default di aset referensi di bawah. Agar *.run.app dapat di-resolve secara privat, tim jaringan Anda harus sudah mengoperasikan endpoint Private Service Connect untuk Google API, zona privat Cloud DNS yang me-resolve *.run.app ke endpoint tersebut, dan perutean on-premises ke endpoint tersebut.

Panduan jaringan privat untuk Cloud Run dari Google mencakup infrastruktur yang diperlukan oleh kedua opsi. Verifikasi proses masuk setelah gateway melayani pada hostname privat; hingga saat itu, konfirmasikan bahwa container telah berjalan dari log-nya di Cloud Run.

Perbarui authorized redirect URI pada OAuth client menjadi <public_url>/oauth/callback sebelum proses masuk pertama. Deploy ulang setelah mengubah public_url, karena gateway membangun origin publiknya hanya dari pengaturan tersebut dan mengabaikan X-Forwarded-Host serta X-Forwarded-Proto. X-Forwarded-For dihormati untuk IP klien hanya ketika listen.trusted_proxies diatur.

[tab] GKE

Cluster harus berada di $VPC yang dibuat pada langkah Cloud SQL agar pod dapat menjangkau IP privat database; VPC peering saja tidak berfungsi, karena IP privat Cloud SQL sendiri merupakan jaringan yang di-peering dan peering bersifat non-transitif. Untuk membuat cluster baru di VPC tersebut, teruskan --network="$VPC" --subnetwork=cc-gateway-subnet ke gcloud container clusters create.

Aktifkan Workload Identity pada cluster dan node pool-nya, lalu ikat service account Google ke service account Kubernetes agar pod mewarisi kredensialnya:

gcloud container clusters update <cluster> --region="$REGION" \
  --workload-pool="${PROJECT_ID}.svc.id.goog"
# On a Standard cluster, existing node pools also need GKE_METADATA;
# Autopilot enables this by default.
gcloud container node-pools update <pool> --cluster=<cluster> \
  --region="$REGION" --workload-metadata=GKE_METADATA

kubectl create namespace claude-gateway
kubectl create serviceaccount gateway -n claude-gateway

gcloud iam service-accounts add-iam-policy-binding \
  "claude-gateway@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:${PROJECT_ID}.svc.id.goog[claude-gateway/gateway]"

kubectl annotate serviceaccount gateway -n claude-gateway \
  iam.gke.io/gcp-service-account="claude-gateway@${PROJECT_ID}.iam.gserviceaccount.com"

Deploy gateway sebagai Deployment standar ditambah Service dan Ingress internal, class gce-internal, seperti yang dijelaskan di deployment Kubernetes, dengan:

  • serviceAccountName: gateway
  • Secret Manager CSI driver yang me-mount secret di /secrets
  • readiness probe yang diarahkan ke GET /readyz

Lampirkan BackendConfig dengan timeoutSec yang dinaikkan ke Service gateway: layanan backend load balancer di belakang GKE Ingress secara default memiliki timeout 30 detik, yang memotong respons streaming yang panjang.

Jangan menerapkan NetworkPolicy egress yang memblokir 169.254.169.254 pada cluster Workload Identity; pod harus menjangkau metadata server untuk mendapatkan kredensial. Perlindungan SSRF bawaan gateway merupakan pertahanan di sana.

Gateway mencatat peringatan saat boot bahwa endpoint metadata dapat dijangkau dan menyarankan penerapan NetworkPolicy egress. Di bawah Workload Identity, peringatan tersebut memang diharapkan, karena pod membutuhkan endpoint tersebut.

8. Kirim URL gateway ke mesin developer

Gateway kini sudah berjalan, tetapi developer tidak dapat menjangkaunya dari /login hingga URL gateway ada di mesin mereka. Deploy cuplikan pengaturan terkelola lengkap, dengan forceLoginMethod, forceLoginGatewayUrl, dan opt-in parentSettingsBehavior: "merge", ke setiap perangkat melalui MDM. Tidak ada opsi gateway di pemilih login yang dapat dipilih developer secara manual.

Referensi Terraform

Aset penyebaran referensi mengotomatisasi jalur Cloud Run di halaman ini; aset konfigurasi dan gambar berlaku untuk kedua jalur:

  • setup.sh: penyedia gcloud idempoten yang berjalan melalui jalur Cloud Run lengkap, dari mengaktifkan API melalui penyebaran pertama
  • terraform/: penyebaran yang sama sebagai infrastruktur-sebagai-kode, untuk penyebaran greenfield: penerapan bertarget untuk membuat repositori Artifact Registry, kemudian membangun dan mendorong gambar, kemudian penerapan penuh
  • gateway.yaml.example dan Dockerfile untuk gambar runtime distroless

Artefak menetapkan default ingress Cloud Run ke internal, sesuai dengan perintah deploy di halaman ini; pengaturan tersebut berfungsi dengan atau tanpa internal Application Load Balancer di depan layanan, dan artefak juga tidak membuat load balancer tersebut. Artefak juga default lapisan invoker ke pemberian run.invoker allUsers daripada --no-invoker-iam-check, kebalikan dari panduan halaman ini; keduanya berfungsi, dan pilihan bergantung pada batasan kebijakan organisasi Anda.

Aset disediakan sebagai contoh kerja, bukan sebagai artefak produksi yang didukung; tinjau dan sesuaikan dengan lingkungan Anda.

Troubleshooting

Untuk boot gateway dan kesalahan login, lihat tabel troubleshooting yang tidak bergantung pada platform. Entri di bawah khusus untuk Google Cloud.

Gejala Penyebab Perbaikan
Cloud Run mengembalikan 403 Forbidden sebelum mencapai kontainer Pemeriksaan IAM invoker masih diaktifkan Terapkan dengan --no-invoker-iam-check, atau berikan peran run.invoker kepada allUsers dengan --allow-unauthenticated
--no-invoker-iam-check ditolak dengan invoker_iam_disabled is not currently available Diblokir oleh constraints/run.managed.requireInvokerIam Gunakan --allow-unauthenticated. Jika Domain Restricted Sharing melalui constraints/iam.allowedPolicyMemberDomains juga memblokir itu, gunakan jalur GKE, yang mengekspos gateway di lapisan jaringan tanpa ikatan allUsers.
Container manifest type … must support amd64/linux saat penyebaran Gambar dibangun di host non-amd64, atau buildx memancarkan indeks gambar OCI Bangun dengan --platform=linux/amd64 --provenance=false
Boot gateway keluar dengan kesalahan timeout koneksi Postgres di Cloud Run Layanan tidak terlampir ke VPC, atau Cloud SQL tidak memiliki IP pribadi di VPC itu Terapkan dengan --network dan --subnet untuk egress VPC Langsung, dan buat instans Cloud SQL dengan --no-assign-ip dan --network menunjuk ke VPC yang sama
Permintaan Agent Platform mengembalikan 403 PERMISSION_DENIED Runtime tidak menggunakan service account claude-gateway, atau model tidak diaktifkan di Model Garden untuk proyek Atur --service-account di Cloud Run atau ikat Workload Identity di GKE, dan aktifkan setiap model Claude di Model Garden untuk wilayah target
Respons streaming terpotong setelah durasi tetap Timeout permintaan front-end: layanan backend load balancer di belakang GKE Ingress default ke 30 detik dan Cloud Run ke 300 detik Lampirkan BackendConfig dengan timeoutSec yang ditingkatkan di GKE, atau terapkan dengan --timeout=3600 di Cloud Run

Langkah berikutnya