תיעוד 77
פריסת Claude apps gateway ב-Google Cloud
דוגמה מעשית להרצת Claude apps gateway ב-Google Cloud: Cloud Run או GKE, Cloud SQL עבור PostgreSQL, Secret Manager, ואימות באמצעות service account אל Agent Platform של Google Cloud.
הערה: דף זה מציג דרך אחת להרצת Claude apps gateway ב-Google Cloud. התצורה היא דוגמה עובדת עבור תשתית בניהול הלקוח ולא פריסת ייצור נתמכת. השתמש בה כדי לראות כיצד החלקים מתחברים יחד לפני שתתאים אותה לסביבה שלך. לדרישות שאינן תלויות פלטפורמה, עיין במדריך הפריסה.
דוגמה זו מקימה את Claude apps gateway ב-Google Cloud עם Agent Platform של Google Cloud כ-upstream של המודל, תוך שימוש ב-Cloud Run או ב-GKE לצורכי מחשוב. Google Workspace משמש כספק הזהויות (IdP) לדוגמה, אך כל ספק זהויות התואם ל-OpenID Connect (OIDC) יעבוד, רק בלוק ה-oidc משתנה. ראה הגדרת ספק זהויות לפרטים עבור כל ספק זהויות.
#מה תבנה
הפריסה מורכבת מ:
- שירות Cloud Run או Deployment ב-GKE המריצים את קונטיינר ה-gateway
- מאגר Artifact Registry עבור ה-image של ה-gateway
- מופע Cloud SQL for PostgreSQL, עם IP פרטי בלבד, עבור ה-store של ה-gateway
- סודות ב-Secret Manager עבור
gateway.yaml, מפתח החתימה של ה-JWT, ה-client secret של ה-OIDC, וכתובת ה-URL של Postgres - Service account עם
roles/aiplatform.user, המצורף ישירות ב-Cloud Run או מקושר באמצעות Workload Identity ב-GKE - HTTPS front end שאתה מספק: Application Load Balancer פנימי לפני Cloud Run, שמדריך זה מגדיר את ה-gateway עבורו אך אינו יוצר אותו, או GKE Ingress פנימי מסוג
gce-internalב-GKE
#דרישות מוקדמות
- פרויקט GCP שמופעל בו חיוב, והרשאות ליצירת המשאבים שלמעלה
- ה-CLI של
gcloud, מאומת באמצעותgcloud auth login, ו-Docker מותקן מקומית - עבור מסלול GKE:
kubectl, ואשכול GKE בתוך ה-VPC שנוצר במדריך להלן - גישה אל מודלי Claude שאתה צריך ב-Model Garden, באזור שמפרסם אותם
- לקוח יישום אינטרנט מסוג OAuth 2.0 ב-Google Workspace עם redirect URI בכתובת
https://<gateway-host>/oauth/callback, ראה הגדרת ספק זהויות - שם מארח TLS עבור ה-gateway, בדרך כלל שם DNS פנימי שמצביע על ה-load balancer
הגדר את הפרויקט ואת האזור פעם אחת:
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"#פריסת ה-gateway
השלבים שלהלן מקצים את הפריסה המלאה באמצעות פקודות gcloud.
הפעלת ממשקי 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 שאתה צריך תלויים במסלול הפריסה:
computeו-servicenetworking: נדרשים עבור מסלול Cloud SQL עם IP פרטיrun: עבור Cloud Run בלבדcontainer: עבור GKE בלבד
יצירת ה-service account והענקת IAM
ה-gateway רץ כ-service account ייעודי עם הרשאה לקרוא ל-Agent Platform של Google Cloud. הוא ניגש אל Cloud SQL דרך ה-VPC עם משתמש מבוסס סיסמה, כך שלא נדרש תפקיד 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לאחר מכן הפעל את מודלי Claude עבור הפרויקט ב-Model Garden. מודלים מפורסמים באזורים ספציפיים, לכן בדוק כל כרטיס מודל.
בנייה ודחיפה של ה-image אל Artifact Registry
בנה את ה-image בהתאם לדרישות ה-container image, באמצעות קובץ בינארי glibc עבור
linux-x64, ודחף אותו: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:
4. **הקצאת Cloud SQL for PostgreSQL**
צור את המופע בתוך VPC באמצעות Private Services Access כך שלא תהיה לו כתובת IP ציבורית. זה מספק מענה גם לפרויקטים שבהם נאכף `constraints/sql.restrictPublicIp`:
```bash
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"סביבת ההרצה של Cloud Run או GKE חייבת לפעול בתוך ה-VPC הזה, או להיות מנותבת אליו.
כתיבת gateway.yaml
בלוק ה-
upstreamsמצביע על Agent Platform של Google Cloud עםauth: {}, כך שה-gateway מבצע אימות באמצעות Application Default Credentials מ-service account של סביבת ההרצה. עיין במדריך התצורה עבור כל שדה.שני שדות ב-
listenמתארים מה ניצב לפני ה-gateway:public_url: מקור ה-https://החיצוני, הנדרש עבור כל bind שאינו loopback. ראה הפניה עבורlisten. ה-gateway בונה את ה-redirect_uriשל ה-IdP ואת מסמך הגילוי שלו אך ורק מערך זה, ולעולם לא מכותרותX-Forwarded-*.trusted_proxies: טווחי המקור של ה-front end. ה-gateway מכבד אתX-Forwarded-Forרק כאשר עמית ה-TCP מופיע ברשימה זו, ואז מתקדם לאורך השרשרת מעבר לדילוגים מהימנים, כך שמגבלות קצב כניסה לפי IP ואירועי ביקורת מתעדים את כתובות ה-IP של המפתחים במקום את כתובת ה-load balancer.
הגדר את
trusted_proxiesבהתאם ל-front end שלך. Ingress חיצוני של GKE מסוגgceאינו מופיע ברשימה: הוא מקצה כתובת ציבורית של כלל העברה, שבדיקת הרשת הפרטית של/loginדוחה.Front end trusted_proxiesCloud Run בגישה ישירה, ללא load balancer [169.254.0.0/16]Application Load Balancer פנימי לפני Cloud Run 169.254.0.0/16בתוספת ה-CIDR של ה-proxy-only subnet שלךGKE Ingress פנימי, מסוג gce-internalה-CIDR של ה-proxy-only subnet שלך הדוגמה שלהלן משתמשת בערכים של load balancer פנימי לפני 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}
upstreams:
- provider: vertex
region:
#must match $REGION
project_id: <your-project>
auth: {}
#ADC via the runtime service account
> הערה: טוקני id_token של Google אינם נושאים את ה-claim בשם `groups`. כדי להשתמש במדיניות מבוססת קבוצות ב-[`managed.policies`](/docs/en/claude-apps-gateway-config#managed) עם Google Workspace כספק הזהויות (IdP), הגדר את [`oidc.google_groups`](/docs/en/claude-apps-gateway-config#oidc), שבודק את הקבוצות של כל משתמש באמצעות Admin SDK Directory API בעזרת service account עם הרשאת domain-wide delegation. ללא זאת, בצע התאמה לפי `email_domain` במקום זאת.
6. **אחסון סודות ב-Secret Manager**
צור ארבעה סודות והענק את התפקיד `roles/secretmanager.secretAccessor` ל-service account בשם `claude-gateway`:
| סוד | מקור |
| --- | --- |
| `gateway-jwt-secret` | `openssl rand -base64 32` |
| `gateway-oidc-client-secret` | מסוף Google Cloud ← לקוח OAuth |
| `gateway-postgres-url` | `$GATEWAY_POSTGRES_URL` משלב ה-Cloud SQL |
| `gateway-config` | קובץ ה-`gateway.yaml` המלא מהשלב הקודם |
אופן הגעת הסודות לקונטיינר שונה לפי המסלול:
* ב-GKE הם נטענים כקבצים באמצעות מנהל ההתקן Secret Manager CSI, ו-`gateway.yaml` מפנה אל `${file:/secrets/...}`.
* ב-Cloud Run, שאינו תומך בטעינת מספר סודות לתוך אותה תיקייה, `gateway.yaml` נטען כקובץ ושלושת האחרים מוזרקים כמשתני סביבה, כך ש-`gateway.yaml` מפנה במקום זאת אל `${GATEWAY_JWT_SECRET}`, אל `${OIDC_CLIENT_SECRET}`, ואל `${GATEWAY_POSTGRES_URL}`.
7. **פריסה**
**Cloud Run**
הפקודה שלהלן מבצעת פריסה לסביבת ייצור מאחורי load balancer פנימי.
```bash
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 יציאת VPC ישירה (Direct VPC egress), באמצעות --network, --subnet ו---vpc-egress=private-ranges-only, מאפשרת לשירות להגיע ישירות ל-IP הפרטי של Cloud SQL. כל מופע מחזיק עד store.max_connections חיבורי Postgres, חמישה כברירת מחדל, לכן שמור על מכפלת מופעים מרביים ב-store.max_connections מתחת למגבלת החיבורים של שכבת ה-Cloud SQL שלך. נכסי הייחוס מגבילים את המופעים ל-8 עבור שכבת db-g1-small מסיבה זו. תעבורת יציאה ציבורית אל נקודות הקצה של Agent Platform של Google Cloud ואל accounts.google.com יוצאת ישירות לאינטרנט ולא דרך ה-VPC, כך שלא נדרש Cloud NAT.
בדיקת ה-IAM של ה-invoker חייבת להיות פתוחה או מבוטלת. ה-gateway מריץ OIDC משלו והלקוחות שלו אינם נושאים טוקן של GCP, ולכן בדיקת ה-invoker של Cloud Run חייבת לקבל בקשות ללא אימות מוקדם. כניסת ה-OIDC של ה-gateway מאמתת את הבקשה ברגע שהיא מגיעה לקונטיינר, כאשר allowed_email_domains קובע אילו דומיינים רשאים להיכנס.
שני דגלים מאפשרים קבלת בקשות ללא אימות מוקדם:
--no-invoker-iam-check: מבטל את הבדיקה ללא צורך בניהול שיוך שלallUsers, ופועל תחת Domain Restricted Sharing--allow-unauthenticated: מעניק ל-allUsersאת התפקידrun.invoker. השתמש בו אם הארגון שלך אינו מאפשר שימוש ב---no-invoker-iam-check
הגבלת תעבורה נכנסת באמצעות --ingress היא שכבה נפרדת ובלתי תלויה מבדיקת ה-invoker. השאר אותה מוגדרת כדי להגביל את השירות לרשת הארגונית שלך.
כברירת מחדל, כתובת ה-URL של Cloud Run בתבנית *.run.app נפתרת לכתובת ציבורית, שבדיקת הרשת הפרטית של /login דוחה. שתי טופולוגיות מספקות למפתחים שם מארח שנפתר באופן פרטי, ו-Cloud Run אינו מקצה אף אחת מהן עבורך:
- Application Load Balancer פנימי, הטופולוגיה שקובץ ה-
gateway.yamlבדף זה מניח: הקצה Application Load Balancer פנימי לפני השירות עם שם DNS פנימי ותעודה, והגדר אתlisten.public_urlלשם מארח זה. הגדרת ה-ingress שלinternalכבר מקבלת תעבורה מ-Application Load Balancers פנימיים. ההגדרהinternal-and-cloud-load-balancingמאפשרת בנוסף גם Application Load Balancers חיצוניים, שכתובותיהם הציבוריות נדחות על ידי בדיקת הרשת הפרטית של/login, ולכן אף טופולוגיה בדף זה אינה זקוקה לה. - Ingress פנימי בלבד ללא load balancer: השאר את פקודת הפריסה כפי שהיא והשאר את
listen.public_urlככתובת ה-URL של*.run.app, שהיא ברירת המחדל בנכסי הייחוס להלן. כדי ש-*.run.appייפתר באופן פרטי, צוות הרשת שלך כבר חייב לתפעל נקודת קצה של Private Service Connect עבור ממשקי API של Google, אזור פרטי ב-Cloud DNS שפותר את*.run.appאליה, וניתוב מקומי (on-premises) לאותה נקודת קצה.
מדריך הרשת הפרטית של Google עבור Cloud Run מכסה את התשתית ששתי האפשרויות זקוקות לה. ודא את הכניסה ברגע שה-gateway משרת בשם מארח פרטי. עד אז, ודא שהקונטיינר אותחל מתוך היומנים (logs) שלו ב-Cloud Run.
עדכן את ה-redirect URI המורשה של לקוח ה-OAuth ל-<public_url>/oauth/callback לפני הכניסה הראשונה. פרוס מחדש לאחר שינוי public_url, מכיוון שה-gateway בונה את המקור הציבורי שלו אך ורק מהגדרה זו ומתעלם מ-X-Forwarded-Host ומ-X-Forwarded-Proto. המערכת מתחשבת ב-X-Forwarded-For עבור כתובות IP של לקוחות רק כאשר listen.trusted_proxies מוגדר.
GKE
האשכול חייב להימצא בתוך ה-$VPC שנוצר בשלב ה-Cloud SQL כדי ש-pods יוכלו להגיע ל-IP הפרטי של מסד הנתונים. קישור VPC peering לבדו אינו עובד, מכיוון ש-IP פרטי של Cloud SQL הוא בעצמו רשת עם peering, ו-peering אינו טרנזיטיבי. כדי ליצור אשכול חדש בתוך אותו VPC, העבר את --network="$VPC" --subnetwork=cc-gateway-subnet אל gcloud container clusters create.
הפעל את Workload Identity באשכול ובמאגרי הצמתים (node pools) שלו, ולאחר מכן קשר את ה-service account של Google אל ה-service account של Kubernetes כדי ש-pods יירשו את פרטי האימות שלו:
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" פרוס את ה-gateway בתור Deployment רגיל בתוספת Service ו-Ingress פנימי, מסוג gce-internal, כמתואר בפריסה ב-Kubernetes, עם:
serviceAccountName: gateway- מנהל ההתקן Secret Manager CSI טוען סודות ב-
/secrets - בדיקת המוכנות (readiness probe) מכוונת אל
GET /readyz
צרף BackendConfig עם ערך timeoutSec מוגדל אל ה-Service של ה-gateway: שירות ה-backend של ה-load balancer שמאחורי GKE Ingress מוגדר כברירת מחדל עם פסק זמן של 30 שניות, מה שקוטע תגובות streaming ממושכות.
אל תחיל NetworkPolicy לתעבורה יוצאת שחוסם את 169.254.169.254 באשכול עם Workload Identity. ה-pod חייב להגיע אל שרת המטא-דאטה עבור פרטי אימות. ה-SSRF guard המובנה של ה-gateway הוא קו ההגנה במקרה זה.
ה-gateway רושם אזהרת אתחול שה-endpoint של המטא-דאטה נגיש ומציע להחיל NetworkPolicy לתעבורה יוצאת. תחת Workload Identity אזהרה זו צפויה, מכיוון שה-pod זקוק ל-endpoint.
הפצת כתובת ה-URL של ה-gateway למחשבי המפתחים
ה-gateway פועל כעת, אך מפתחים אינם יכולים להגיע אליו מתוך
/loginעד שכתובת ה-URL של ה-gateway תימצא במחשבים שלהם. פרוס לכל מכשיר באמצעות MDM את קטע ההגדרות המנוהלות המלא, הכולל אתforceLoginMethod, אתforceLoginGatewayUrl, ואת הבחירה ב-parentSettingsBehavior: "merge". אין אפשרות של gateway בבורר הכניסה שמפתח יכול לבחור ידנית.
#הפניית Terraform
נכסי פריסת הייחוס מבצעים אוטומציה למסלול Cloud Run שבדף זה. נכסי התצורה וה-image חלים על שני המסלולים:
setup.sh: סקריפט התקנה אידמפוטנטי עבורgcloudשעובר בכל מסלול Cloud Run, מהפעלת ממשקי API ועד לפריסה הראשונהterraform/: אותה פריסה כתשתית כקוד, עבור פריסה חדשה לחלוטין (greenfield): הרצת apply ממוקדת ליצירת מאגר ה-Artifact Registry, לאחר מכן בנייה ודחיפה של ה-image, ולאחר מכן apply מלאgateway.yaml.exampleו-Dockerfileעבור image סביבת הרצה מסוג distroless
הנכסים מגדירים את ה-ingress של Cloud Run כברירת מחדל ל-internal, בהתאם לפקודת הפריסה שבדף זה. הגדרה זו פועלת עם או בלי Application Load Balancer פנימי לפני השירות, וגם הנכסים אינם יוצרים את ה-load balancer. כמו כן, הנכסים מגדירים כברירת מחדל את שכבת ה-invoker להענקת run.invoker ל-allUsers במקום --no-invoker-iam-check, ההיפך ממה שהודגם בדף זה. שתי האפשרויות עובדות, והבחירה תלויה באילוצי המדיניות של הארגון שלך.
הנכסים מסופקים כדוגמאות עובדות ולא כתוצר ייצור נתמך. בדוק והתאם אותם לסביבה שלך.
#פתרון בעיות
עבור שגיאות באתחול ה-gateway ובכניסה, ראה את טבלת פתרון הבעיות הכללית שאינה תלויה בפלטפורמה. הרשומות שלהלן ייעודיות ל-Google Cloud.
| תסמין | סיבה | פתרון |
|---|---|---|
Cloud Run מחזיר 403 Forbidden לפני שהבקשה מגיעה לקונטיינר | בדיקת ה-IAM של ה-invoker עדיין מופעלת | פרוס עם --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. אם מנגנון Domain Restricted Sharing דרך constraints/iam.allowedPolicyMemberDomains חוסם גם את זה, השתמש במסלול GKE, שחושף את ה-gateway בשכבת הרשת ללא שיוך של allUsers. |
Container manifest type … must support amd64/linux בעת הפריסה | ה-image נבנה על גבי מארח שאינו amd64, או ש-buildx יצר OCI image index | בנה עם --platform=linux/amd64 --provenance=false |
| אתחול ה-gateway יוצא עם שגיאת פסק זמן בחיבור ל-Postgres ב-Cloud Run | השירות אינו מחובר ל-VPC, או של-Cloud SQL אין IP פרטי ב-VPC זה, ה-store מפסיק להמתין לאחר 5 שניות | פרוס עם --network ו---subnet עבור Direct VPC egress, וצור את מופע ה-Cloud SQL עם --no-assign-ip ו---network המצביעים על אותו VPC |
בקשות Agent Platform של Google Cloud מחזירות 403 PERMISSION_DENIED | סביבת ההרצה אינה משתמשת ב-service account בשם claude-gateway, או שהמודל אינו מופעל ב-Model Garden עבור הפרויקט | הגדר את --service-account ב-Cloud Run או קשר את Workload Identity ב-GKE, והפעל כל מודל Claude ב-Model Garden עבור אזור היעד |
| תגובות streaming נקטעות לאחר משך זמן קבוע | פסק זמן של בקשת ה-front-end: שירות ה-backend של ה-load balancer מאחורי GKE Ingress מוגדר כברירת מחדל ל-30 שניות ו-Cloud Run ל-300 שניות | צרף BackendConfig עם timeoutSec מוגדל ב-GKE, או פרוס עם --timeout=3600 ב-Cloud Run |
#הצעדים הבאים
- הפניית תצורה: כל אפשרות ב-
gateway.yaml, כוללmanaged.policiesו-telemetry - פריסה ותפעול: הגדרת ספק זהויות (IdP), בדיקות תקינות (health checks), סבב מפתחות סוד של JWT, שדרוגים ומודל האבטחה
- סקירת Claude apps gateway: התחלה מהירה וחיבור מפתחים