Перейти к основному содержанию
На этой странице описан один из способов запуска Claude apps gateway на Google Cloud. Конфигурация является рабочим примером для инфраструктуры, управляемой клиентом, а не поддерживаемым развертыванием для производства; используйте её, чтобы понять, как компоненты работают вместе, прежде чем адаптировать её к своей среде. Требования, независимые от платформы, см. в руководстве по развертыванию.
Этот пример развертывает Claude apps gateway на Google Cloud с использованием Agent Platform Google Cloud в качестве вышестоящего поставщика моделей, используя либо Cloud Run, либо GKE для вычислений. Google Workspace используется в качестве примера поставщика идентификации (IdP), но работает любой поставщик, совместимый с OpenID Connect (OIDC); изменяется только блок oidc. Подробности для каждого IdP см. в разделе Настройка поставщика идентификации.

Что вы создадите

Диаграмма Claude apps gateway на Google Cloud: клиенты Claude Code подключаются по HTTPS к шлюзу (Cloud Run или GKE), который работает внутри VPC рядом с приватной базой данных Cloud SQL для состояния сеанса. Шлюз выполняет вход пользователей через OIDC для Google Workspace, читает конфигурацию и секреты из Secret Manager, перенаправляет запросы моделей в Agent Platform и извлекает свой образ из Artifact Registry при развертывании.
Эталонная конфигурация подготавливает:
  • Сервис Cloud Run или развертывание GKE, запускающие контейнер шлюза
  • Репозиторий Artifact Registry для образа шлюза
  • Экземпляр Cloud SQL для PostgreSQL, только с приватным IP, для хранилища шлюза
  • Секреты Secret Manager для gateway.yaml, ключа подписи JWT, секрета клиента OIDC и URL Postgres
  • Сервисный аккаунт с roles/aiplatform.user, подключённый непосредственно на Cloud Run или привязанный через Workload Identity на GKE
  • Внутренний Application Load Balancer на Cloud Run или внутренний GKE Ingress класса gce-internal на GKE для HTTPS

Предварительные требования

  • Проект GCP с включённым биллингом и разрешением на создание указанных выше ресурсов
  • CLI gcloud, аутентифицированный с помощью gcloud auth login, и Docker, установленный локально
  • Для трека GKE: kubectl и кластер GKE на VPC, созданный в пошаговом руководстве ниже
  • Доступ к необходимым моделям Claude в Model Garden в регионе, который их публикует
  • Веб-приложение OAuth 2.0 Google Workspace с URI перенаправления https://<gateway-host>/oauth/callback; см. Настройка поставщика идентификации
  • TLS имя хоста для шлюза, обычно внутреннее имя DNS, указывающее на балансировщик нагрузки
Установите проект и регион один раз:
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"

Развертывание шлюза

Приведённые ниже шаги подготавливают полное развертывание с помощью команд 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 зависят от пути развертывания:
  • compute и servicenetworking: требуются для пути приватного IP Cloud SQL
  • run: только Cloud Run
  • container: только GKE
2

Создание сервисного аккаунта и предоставление IAM

Шлюз работает как выделенный сервисный аккаунт с разрешением на вызов Agent Platform. Он достигает Cloud SQL через VPC с пользователем пароля, поэтому роль 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
Затем включите модели Claude для проекта в Model Garden; модели публикуются в определённых регионах, поэтому проверьте каждую карточку модели.
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 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

Подготовка Cloud SQL для PostgreSQL

Создайте экземпляр на VPC через Private Services Access, чтобы он не имел публичного 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: 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 или маршрутизироваться в него.
5

Написание gateway.yaml

Блок upstreams указывает на Agent Platform с auth: {}, поэтому шлюз аутентифицируется через Application Default Credentials из сервисного аккаунта среды выполнения. Полное описание каждого поля см. в справочнике конфигурации.Два поля listen зависят от того, что находится перед шлюзом:
  • public_url: требуется за Cloud Run или GKE Ingress. Шлюз строит redirect_uri IdP и документ обнаружения только из этого значения, никогда из заголовков X-Forwarded-*.
  • trusted_proxies: диапазоны источников переднего конца. Шлюз соблюдает X-Forwarded-For только когда TCP-пир находится в этом списке, затем проходит по цепи мимо доверенных переходов, поэтому ограничения скорости входа на IP и события аудита записывают IP-адреса разработчиков вместо адреса балансировщика нагрузки.
Установите trusted_proxies в соответствии с вашим передним концом. Внешний GKE Ingress класса gce не указан: он подготавливает адрес публичного правила переадресации, который проверка приватной сети /login отклоняет.
Передний конецtrusted_proxies
Cloud Run, достигнутый напрямую, без балансировщика нагрузки[169.254.0.0/16]
Internal Application Load Balancer перед Cloud Run169.254.0.0/16 плюс CIDR вашей подсети только для прокси
GKE внутренний Ingress, класс gce-internalCIDR вашей подсети только для прокси
Пример ниже использует значения внутреннего балансировщика нагрузки перед 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 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: <your-region>                        # must match $REGION
    project_id: <your-project>
    auth: {} # ADC via the runtime service account
Google id_tokens не содержат претензию groups. Для использования политик на основе групп в managed.policies с Google Workspace в качестве IdP настройте 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 client
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

Развертывание

Команда ниже развертывает для производства за внутренним балансировщиком нагрузки.
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
Прямой исход VPC через --network, --subnet и --vpc-egress=private-ranges-only позволяет сервису достичь приватного IP Cloud SQL напрямую. Публичный исход к конечным точкам Agent Platform и accounts.google.com идёт непосредственно в интернет, а не через VPC, поэтому Cloud NAT не требуется.Проверка IAM вызывающего должна быть открыта или отключена. Шлюз запускает свой собственный OIDC, и его клиенты не несут токен GCP, поэтому проверка вызывающего Cloud Run должна допускать неаутентифицированные запросы. Аутентификация запроса OIDC шлюза происходит после того, как он достигает контейнера, с allowed_email_domains, ограничивающим, какие домены могут входить.Два флага допускают неаутентифицированные запросы:
  • --no-invoker-iam-check: отключает проверку без привязки allUsers для управления и работает в рамках Domain Restricted Sharing
  • --allow-unauthenticated: предоставляет allUsers роль run.invoker; используйте, если ваша организация не позволяет --no-invoker-iam-check
Ограничение входа через --ingress — это отдельный, независимый слой от проверки вызывающего; держите его установленным, чтобы ограничить сервис вашей корпоративной сетью.По умолчанию URL Cloud Run *.run.app разрешается на публичный адрес, который проверка приватной сети /login отклоняет. Две топологии дают разработчикам приватно разрешаемое имя хоста, и Cloud Run не подготавливает ни одну для вас:
  • Internal Application Load Balancer, топология, которую предполагает команда развертывания выше: развертывайте с --ingress=internal-and-cloud-load-balancing, подготовьте внутренний Application Load Balancer перед сервисом с внутренним именем DNS и сертификатом, и установите listen.public_url на это имя хоста.
  • Внутренний вход только без балансировщика нагрузки: развертывайте с --ingress=internal и оставьте listen.public_url как URL *.run.app, значение по умолчанию в эталонных активах ниже. Чтобы *.run.app разрешался приватно, ваша команда сети должна уже работать с конечной точкой Private Service Connect для Google APIs, приватной зоной Cloud DNS, разрешающей *.run.app для неё, и маршрутизацией на месте к этой конечной точке.
Руководство Google по приватной сети для Cloud Run охватывает инфраструктуру, которая требуется обоим вариантам. Проверьте вход после того, как шлюз обслуживает приватное имя хоста; до этого подтвердите загрузку контейнера из его журналов в Cloud Run.Обновите URI перенаправления авторизации клиента OAuth на <public_url>/oauth/callback перед первым входом. Переразверните после изменения public_url, потому что шлюз строит свой публичный источник только из этого параметра и игнорирует X-Forwarded-Host и X-Forwarded-Proto. X-Forwarded-For соблюдается для IP-адресов клиентов только когда установлен listen.trusted_proxies.
8

Отправка URL шлюза на машины разработчиков

Шлюз теперь работает, но разработчики не могут достичь его из /login до тех пор, пока URL шлюза не будет на их машинах. Установите forceLoginMethod и forceLoginGatewayUrl в файле управляемых параметров, который вы развертываете на каждом устройстве через MDM. В средстве выбора входа нет опции шлюза для разработчика, чтобы выбрать вручную.

Справочник Terraform

Эталонные активы развертывания автоматизируют трек Cloud Run на этой странице; активы конфигурации и образа применяются к обоим трекам:
  • setup.sh: идемпотентный подготовщик gcloud, который проходит полный путь Cloud Run, от включения API до первого развертывания
  • terraform/: то же развертывание как инфраструктура как код, для развертывания на зелёном поле: целевое применение для создания репозитория Artifact Registry, затем построение и отправка образа, затем полное применение
  • gateway.yaml.example и Dockerfile для образа среды выполнения distroless
Артефакты по умолчанию используют входящий трафик 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, обратное пошаговому руководству этой страницы; оба работают, и выбор зависит от ограничений политики вашей организации. Активы предоставляются как рабочие примеры, а не как поддерживаемый артефакт для производства; проверьте и адаптируйте их к своей среде.

Troubleshooting

Для ошибок загрузки и входа шлюза см. независимую от платформы таблицу troubleshooting. Записи ниже относятся к 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. Если Domain Restricted Sharing через constraints/iam.allowedPolicyMemberDomains также блокирует это, используйте трек GKE, который предоставляет шлюз на уровне сети без привязки allUsers.
Container manifest type … must support amd64/linux при развертыванииОбраз был построен на хосте, отличном от amd64, или buildx выдал индекс образа OCIПостройте с --platform=linux/amd64 --provenance=false
Загрузка шлюза завершается с ошибкой тайм-аута подключения Postgres на Cloud RunСервис не подключён к VPC или Cloud SQL не имеет приватного IP на этом VPC; хранилище перестаёт ждать после 5 секундРазвертывайте с --network и --subnet для прямого исхода VPC и создавайте экземпляр Cloud SQL с --no-assign-ip и --network, указывающим на тот же VPC
Запросы Agent Platform возвращают 403 PERMISSION_DENIEDСреда выполнения не использует сервисный аккаунт claude-gateway или модель не включена в Model Garden для проектаУстановите --service-account на Cloud Run или привяжите Workload Identity на GKE и включите каждую модель Claude в Model Garden для целевого региона
Потоковые ответы обрезаны после фиксированной продолжительностиТайм-аут запроса переднего конца: сервис бэкенда балансировщика нагрузки за GKE Ingress по умолчанию имеет 30 секунд, а Cloud Run — 300 секундПрисоедините BackendConfig с повышенным timeoutSec на GKE или развертывайте с --timeout=3600 на Cloud Run

Следующие шаги