首页
/ 如何用 Terraform 在 GCP Cloud Run 部署 LiteLLM Proxy 并解决 GHCR 镜像拉取问题

如何用 Terraform 在 GCP Cloud Run 部署 LiteLLM Proxy 并解决 GHCR 镜像拉取问题

2026-09-08 18:11:10作者:舒璇辛Bertina

LiteLLM 仓库自带一套 Terraform 模块(terraform/litellm/gcp),可以把组件化的 LiteLLM Proxy 一次性部署到 GCP:Cloud Run v2 上跑 gateway(端口 4000)、backend(4001)、ui(3000)三个服务,外加 Cloud SQL for PostgreSQL(写入实例 + 跨区只读副本)、Memorystore Redis(缓存与限流)、GCS 桶、Secret Manager 条目,以及一个外部全局 HTTP(S) 负载均衡器。数据库迁移通过一个一次性 Cloud Run Job(litellm-migrations)执行 prisma migrate deploy 完成。

这条路径中有一个必须先解决的前置问题:四个镜像(litellm-gatewaylitellm-backendlitellm-uilitellm-migrations)发布在 GHCR 上,而 Cloud Run 只接受 Artifact Registry、[region.]gcr.iodocker.io 的镜像,会在 apply 阶段直接拒绝 ghcr.io URI。下面的步骤就是围绕打通这一点展开的。

准备条件

  • 一个已开启 billing 的 GCP 项目。这套栈会创建付费资源(Cloud SQL、Memorystore、LB anycast IP)。
  • gcloud 已完成认证(gcloud auth login)。
  • 目标项目中启用以下 9 个 API(可直接执行):
gcloud services enable \
  run.googleapis.com \
  sqladmin.googleapis.com \
  redis.googleapis.com \
  secretmanager.googleapis.com \
  vpcaccess.googleapis.com \
  compute.googleapis.com \
  servicenetworking.googleapis.com \
  storage.googleapis.com \
  artifactregistry.googleapis.com

解决 GHCR 镜像拉取:创建 Artifact Registry 直通仓库

在目标项目中创建指向 GHCR 的 remote 仓库(每个项目只需做一次):

gcloud artifacts repositories create litellm \
  --repository-format=docker \
  --location=us-central1 \
  --mode=remote-repository \
  --remote-repo-config-desc="GitHub Container Registry passthrough" \
  --remote-docker-repo=https://ghcr.io

如果仓库已存在,该命令会退出并报错,此时直接继续即可。之后 Cloud Run 拉镜像会走这个 remote 仓库,由 GCP 侧透传到 GHCR。

仓库文档同时说明了两个容易踩的细节:

  • 栈创建的运行时 service account 不需要 roles/artifactregistry.reader 权限——Cloud Run 拉镜像用的是项目级 serverless agent(service-<project-num>@serverless-robot-prod.iam.gserviceaccount.com),不是运行时 SA。
  • 如果环境完全离线,可以不走 remote 仓库,改为把镜像 docker pull / docker tag / docker push 到一个普通 AR 仓库,然后把 image_registry 设为不带 /berriai 后缀的路径(镜像布局里没有 org 段)。

配置 terraform.tfvars 并执行部署

examples/default/ 是一个薄入口:配置 google / google-beta provider 并调用上层模块(入口),一键部署路径如下:

cd terraform/litellm/gcp/examples/default
cp terraform.tfvars.example terraform.tfvars
terraform init
terraform apply

terraform.tfvars 中需要编辑的关键项(完整字段见 terraform.tfvars.example 的注释):

project_id     = "my-gcp-project"   # 替换为你的 GCP 项目 ID
region         = "us-central1"
tenant         = "acme"             # 所有资源名的前缀:${tenant}-litellm-${env}
env            = "stage"

# 必须设置:指向上面创建的 Artifact Registry remote 仓库
image_registry = "us-central1-docker.pkg.dev/my-gcp-project/litellm/berriai"
image_tag      = "v1.86.0-dev"

image_registry 不能保留默认值 ghcr.io/berriai——默认值只是为了让本地 terraform plan 能跑通,真实部署时 Cloud Run 会在 apply 时拒绝它。四个 litellm-<component>:${image_tag} 镜像 URI 就是由 image_registry + image_tag 拼出来的,升级 LiteLLM 时两个变量要一起升。只有需要单独固定某个组件镜像时,才在 examples/default/main.tfmodule "litellm" 块里直接设置 gateway_image / backend_image / ui_image / migrations_image 覆盖(示例层没有把这些暴露成变量)。

密钥类输入建议用环境变量而不是写进 tfvars,因为写进 tfvars 的值会进入 terraform.tfstate

export TF_VAR_litellm_master_key="sk-..."   # 可选;省略时栈自动生成随机 sk-… 值
export TF_VAR_litellm_license="lic-..."     # 可选;省略则 OSS-only 运行
export TF_VAR_ui_password="..."             # 可选;省略时 UI 登录回落到 master key

首次 terraform apply 大约需要 20–25 分钟,其中大部分时间花在 Cloud SQL 创建上。顺序是:依赖资源就绪 → 迁移 Job 自动执行 prisma migrate deploy → 之后 gateway / backend / ui 才开始对外服务。apply 返回时栈已可接流量。

可选的 1-click 路径:GCP Cloud Shell 内置了 DeployStack 安装器,回答项目、区域、tenant、env、image tag、image_registry、TLS 等提示后由它执行 terraform apply,提示定义见 deploystack.json

验证部署结果

terraform output lb_url

lb_url 是 Proxy 的对外地址:dashboard 在 /,API 在 /v1/*。HTTP-only 试用部署下它是 http://<lb-ip> 形式。

UI 登录账号是 admin,密码是 master key。如果部署时自动生成了 master key,用下面命令从 Secret Manager 读出来:

gcloud secrets versions access latest \
  --secret="$(terraform output -raw master_key_secret_id)"

其他常用输出:lb_ip(LB anycast IP)、gateway_service_url / backend_service_url / ui_service_url(绕过 LB 的 Cloud Run 直连地址)、migration_run_command(迁移 Job 的 break-glass 手动重跑命令)。

从 HTTP 切到 TLS

默认情况下 terraform plan 会拒绝只建 HTTP 的 LB——TLS 才是受支持的状态。两种走法:

试用 / 开发(HTTP-only):显式设置 allow_plaintext_lb = true 且保持 lb_domains = []。不加这个 flag 而 lb_domains 为空时,plan 会报指向 precondition 的明确错误。

生产 / 预发(Google 托管证书)

  1. 先用 allow_plaintext_lb = true apply 一次,读出 anycast IP:terraform output -raw lb_ip
  2. 把要使用的 DNS 域名 A 记录指向该 IP;
  3. 设置 lb_domains = ["proxy.example.com"],移除 allow_plaintext_lb,重新 apply。

结果是 443 forwarding rule 挂上覆盖每个域名的托管证书,80 端口改写为 301 到 HTTPS。首次 apply 后托管证书会处于 PROVISIONING 状态约 15–60 分钟(等 DNS 传播),可以用 gcloud compute ssl-certificates describe <tenant>-litellm-<env>-cert 查看状态。

后续:添加模型 provider 的 API key

provider 密钥(OpenAI、Anthropic 等)放 Secret Manager,而不是 tfvars。先建 secret:

echo -n "sk-proj-..." | gcloud secrets create openai-api-key --data-file=-

然后在 terraform.tfvars 中引用它的资源 ID(Cloud Run 运行时 SA 会自动获得该 secret 的 roles/secretmanager.secretAccessor),并在 proxy_config 里通过环境变量名引用它:

gateway_extra_secrets = {
  OPENAI_API_KEY = "projects/my-gcp-project/secrets/openai-api-key"
}

proxy_config = {
  model_list = [
    {
      model_name = "gpt-4o"
      litellm_params = {
        model   = "openai/gpt-4o"
        api_key = "os.environ/OPENAI_API_KEY"
      }
    },
  ]
}

注意 secret 只传裸资源 ID(projects/.../secrets/openai-api-key),不能带 /versions/3 这样的版本后缀——secret_key_ref 绑定和 IAM 授权都会拒绝,版本恒定为 latest。改完重新 terraform applyproxy_config 会被编码成 YAML 上传到专用 GCS 桶并以 gcsfuse 只读挂载到 gateway 和 backend 的 /etc/litellm;配置内容的 hash 作为环境变量随行,保证编辑配置就触发新 revision。

限制与清理

  • 数据保留保护cloudsql_deletion_protection 默认为 true(destroy 时拒绝删库),gcs_force_destroy 默认为 false(拒绝销毁非空桶)。只有临时 / CI 栈才应把它们翻转,且意味着接受数据丢失。
  • 数据库认证方式:栈使用密码认证(随机密码存 Secret Manager,容器 entrypoint 在启动 uvicorn 前拼装 DATABASE_URL,密码不出现在服务 spec 和日志里),而不是 GCP IAM 认证。如需 IAM 认证,文档给出的方向是在 Cloud Run v2 的多容器能力下加 cloud-sql-proxy sidecar 走 Unix socket,并替换密码式 URL。
  • 多租户(tenant, env) 对不同的栈可以在同一项目内并存(例如 acme-litellm-stage-gatewayglobex-litellm-dev-license);但模块未声明 configuration_aliasesfor_each 只能在一个项目内扇出多租户,跨项目/区域需要每项目一个 root。
  • 完整输入变量参考 variables.tf,模块各 .tf 文件分工见 terraform/litellm/gcp/README.md 的 Files 表格;分步教程见 TUTORIAL.md
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
858
1.35 K
docsdocs
暂无描述
Markdown
899
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
923
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.83 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
532
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
524
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
393