Cloud Run:部署、配置与回滚
运行 HTTP 容器服务;Console:Cloud Run → Services。
推荐做法#
- 每个服务独立 runtime SA;部署者的 actAs、调用者的 Run Invoker 分开授权。
- 容器监听
0.0.0.0:$PORT;持久数据放数据库或对象存储。 - 按后端连接预算设置 max instances 与 concurrency;低延迟场景再配置 minimum instances。
- 发布使用镜像 digest;候选版本验证后切流,回滚目标取
status.traffic。
常用操作#
替换为实际资源;本段不依赖 lab.env。
PROJECT_ID='REPLACE_PROJECT_ID'
REGION='REPLACE_REGION'
SERVICE='REPLACE_SERVICE'
gcloud run services describe "$SERVICE" \
--project="$PROJECT_ID" --region="$REGION" \
--format='yaml(status.url,status.traffic,metadata.annotations,spec.template)'
gcloud run services get-iam-policy "$SERVICE" \
--project="$PROJECT_ID" --region="$REGION"常用变更:发布已有服务的新版本
沿用上方 PROJECT_ID、REGION、SERVICE。先记录当前 status.traffic;下面只创建无流量候选,沿用服务现有身份与入口配置。
IMAGE='REPLACE_IMAGE_AT_SHA256_DIGEST'
gcloud run deploy "$SERVICE" \
--project="$PROJECT_ID" --region="$REGION" \
--image="$IMAGE" --no-traffic --tag=candidate验证 candidate URL 的认证、响应和日志后,复制准确的 Revision 名再切流:
REVISION='REPLACE_VERIFIED_REVISION'
gcloud run services update-traffic "$SERVICE" \
--project="$PROJECT_ID" --region="$REGION" \
--to-revisions="$REVISION=100"回退时将 --to-revisions 设置为先前记录的完整分流配置;不要用“最新 Ready”猜旧版本。
容易踩的坑#
允许 ALB 入口不会自动通过 IAM authentication。 调用者仍需有效身份,或显式采用 IAP / 匿名访问方案;不要为解决 403 直接关闭所有访问控制。
- 504 后代码可能继续执行;写接口要幂等。应用回滚不恢复数据库。
配置说明与完整示例(按需展开)
Cloud Run 是 Google 托管的应用运行平台,本页部署一个需要身份认证的 HTTP 服务,再练习新版本发布和回滚。命令在配置了 gcloud 的本机终端执行;本轮只做文档静态验证,未执行云端部署。
| 阅读目标 | 页面 |
|---|---|
| Service、Revision、身份、ingress、容量、出站网络与 Binary Authorization | 配置详解 |
| 通过公网 ALB 访问服务 | ALB 实验 |
| 调用失败与日志定位 | 端到端排障 |
创建前先分清对象#
Service是提供稳定 URL 的服务;Revision是镜像或配置变化产生的不可变版本;Instance 是运行某个版本容器的实例,由平台管理数量。这里创建 Service;执行后退出的批处理使用 Job。
控制台入口是 Cloud Run → Services → Deploy container / Create service。CLI 对应 gcloud run deploy。先确定项目、Region、镜像和服务名,再设置资源、入口认证与运行身份。
前置:镜像仓库,有 hello:v1。Cloud Run 运行监听 $PORT 的无状态容器;本地文件系统不能作为业务持久层。
准备身份#
Service Account (SA)是程序使用的 Google 身份。本例 RUN_SA 是容器运行时访问 Google API 的身份,CALLER 是调用 HTTP 服务的测试身份,HUMAN_EMAIL 是部署者。actAs 允许部署者将指定运行账号附加到服务;调用权限另行授予。
source lab.env
gcloud config set project "$PROJECT_ID"
gcloud services enable run.googleapis.com
export RUN_SA="lab-run@${PROJECT_ID}.iam.gserviceaccount.com"
export CALLER="lab-caller@${PROJECT_ID}.iam.gserviceaccount.com"
export HUMAN_EMAIL=$(gcloud config get-value account)
gcloud iam service-accounts create lab-run
gcloud iam service-accounts create lab-caller
# 部署者需有 RUN_SA 的 actAs 权限。
gcloud iam service-accounts add-iam-policy-binding "$RUN_SA" \
--member="user:$HUMAN_EMAIL" \
--role=roles/iam.serviceAccountUser部署服务#
下面创建服务并保留 IAM 调用认证。应用需监听 0.0.0.0:8080,平台提供的 $PORT 与 --port 对应;命令不会自动修改应用监听端口。
gcloud run deploy lab-hello \
--region="$REGION" \
--image="${REGION}-docker.pkg.dev/${PROJECT_ID}/lab-images/hello:v1" \
--service-account="$RUN_SA" \
--no-allow-unauthenticated \
--port=8080 \
--min=0 \
--max=2| 参数 | 本例含义 |
|---|---|
--region / --image |
服务部署位置及要运行的容器镜像 |
--service-account |
runtime Service Account;不是 HTTP 调用者 |
--no-allow-unauthenticated |
本实验不授予匿名调用;检查实际 IAM 策略,尤其复用已有服务时 |
--port=8080 |
容器入口端口,不是公网 URL 的端口 |
--min=0 / --max=2 |
服务级最少/最多实例设置;并发及单实例资源另行配置 |
命令完成后检查 Revision Ready;部署失败先看服务日志与监听端口。下面读取服务 URL 并授权测试调用者:
export RUN_URL=$(gcloud run services describe lab-hello --region="$REGION" --format='value(status.url)')
gcloud run services add-iam-policy-binding lab-hello \
--region="$REGION" \
--member="serviceAccount:$CALLER" \
--role=roles/run.invoker
gcloud iam service-accounts add-iam-policy-binding "$CALLER" \
--member="user:$HUMAN_EMAIL" \
--role=roles/iam.serviceAccountTokenCreatorroles/run.invoker 允许测试用 Service Account 调用服务;roles/iam.serviceAccountTokenCreator 允许当前操作者 impersonate 该账号生成令牌。ID token 是 HTTP 调用身份证明,audience 指定预期接收服务,本例使用 RUN_URL。它与 Google 管理 API 使用的 access token 不同。
TOKEN=$(gcloud auth print-identity-token --impersonate-service-account="$CALLER" --audiences="$RUN_URL")
curl --fail -H "Authorization: Bearer $TOKEN" "$RUN_URL"
unset TOKEN验收:带 token 返回 hello;匿名 curl -i "$RUN_URL" 被拒绝。运行 SA、部署者、调用者是三个不同职责。部署容器
发布与回滚#
先完成 Cloud Build 的 v2 镜像。下面先从 status.traffic 记录当前承接 100% 流量的 Revision;最新 Ready Revision 可能是之前留下的无流量候选。如果当前有分流,记录并恢复完整分流比例,不用本例的单 Revision 回滚。
--no-traffic 部署新 Revision 但不接管正常服务流量;--tag=candidate 为候选版本创建可单独调用的标签地址。tag 不会绕过 IAM 或 ingress。确认候选地址的应用响应和日志后才切流。
gcloud run services describe lab-hello --region="$REGION" --format='yaml(status.traffic)'
# Copy the currently serving 100% revision; latestReadyRevisionName can be an unused candidate.
export OLD_REV='REPLACE_CURRENT_SERVING_REVISION'
gcloud run deploy lab-hello \
--region="$REGION" \
--image="${REGION}-docker.pkg.dev/${PROJECT_ID}/lab-images/hello:v2" \
--no-traffic \
--tag=candidate
gcloud run revisions list --service=lab-hello --region="$REGION"在控制台 Revisions 中复制 candidate 标签 URL,以有权限调用者的 ID token 请求该地址;token 的 audience 仍使用服务 RUN_URL。确认返回 v2 的预期响应,且启动与请求日志正常后,再执行切流:
gcloud run services update-traffic lab-hello --region="$REGION" --to-latest切流后再次访问服务 URL,验证正式入口返回新版本。需要回滚时执行:
gcloud run services update-traffic lab-hello --region="$REGION" --to-revisions="$OLD_REV=100"在 Cloud Run → 服务 → Revisions 查看流量。--to-latest 切到最新版本,--to-revisions 指定目标;应用回滚不恢复数据库或业务数据。
容量、连接池与发布期间的实例规划见 配置详解。
清理#
若继续做 ALB 实验,先保留服务和账号。全部完成后先按 ALB 篇删除相关入口资源,再删除本篇专用服务与账号。撤销之前在运行账号上的业务授权,并确认没有其他工作负载使用这些账号。
gcloud run services delete lab-hello --region="$REGION"
gcloud iam service-accounts delete "$RUN_SA"
gcloud iam service-accounts delete "$CALLER"