它是什么
在这篇 gcp cloud run 教學里,先把 Cloud Run 想成「把程序交给 GCP 代管,换回一个网址」。它是 GCP 的无服务器容器运行平台:给容器镜像或源码,平台就把代码、依赖、运行环境变成可通过 HTTPS 访问的服务。容器镜像不用怕,等于把程序和所需东西装进标准盒子;源码是还没封盒的代码,Cloud Run 可帮你构建。
「无服务器」不是没有机器,而是机器不归你管。你不用创建 VM、登录 SSH、维护 Linux 系统;启动实例、按流量扩缩容、底层补丁都由平台做。你只关心程序端口、环境变量和访问权限。
想有个直观感受,可在 GCP 控制台右上角打开 Cloud Shell,确认是测试项目且已绑定结算账号,再直接复制执行:
gcloud services enable run.googleapis.com
gcloud run deploy hello-cloud-run
--image gcr.io/cloudrun/hello
--region asia-east1
--allow-unauthenticated
为什么这样做?Cloud Shell 自带 Google Cloud CLI 和当前项目,少踩安装、登录坑;第一行开启新项目常默认关闭的 Cloud Run API;第二行用官方示例镜像建服务,不必先写 Dockerfile。image 指定盒子,region 选地区,allow-unauthenticated 表示公网可访问,成功后会拿到 HTTPS 网址。
它适合接口、网站、回调服务和任务型作业。服务模式下请求来了才扩容,空闲可缩到零,省钱但首次访问可能稍慢;批处理、定时脚本可用 Jobs,但 Jobs 不接实时 HTTP 回调。
小白常见坑:
- 没选项目、没绑定结算账号或没启用 API,会报错,不是代码错。
- allow-unauthenticated 等于公开服务,内部接口别乱开,测完删除。
- 以后用源码部署,目录里要有可构建项目或 Dockerfile,空文件夹不行。
- 缩到零省钱,但对极低延迟业务要评估最小实例数。
解决什么问题
很多人在搜 gcp cloud run 教學 时会愣一下:「我连服务器都还没有,这东西能帮我啥?」其实它刚好是来把「服务器」这件事删掉的。先别急着部署,跟着敲几条只看不改的命令,你就明白它到底替你扛了什么。
第一,省去服务器运维。以前上线一个小页面,得自己开 VM、装系统、配网页服务、续证书,半夜还得爬起来打安全补丁,SSH 一断心里就咯噔一下。Cloud Run 把这些全收走了:你只交代码或容器,接请求、起环境、补底层漏洞由平台管,不用常守着一个终端。先复制这条看看账号下现在有什么,纯查看、不会改任何东西:
gcloud run services list --platform=managed
为什么这么做:先确认有没有前人留下的「常开」旧服务,免得后面以为没部署、其实一直在计费。小白容易踩的坑:查出来是空的先别怀疑命令,多半是项目选错了,再跑一次
gcloud config get-value project
看当前绑的是不是你刚建的那个项目;很多人对着测试项目研究半小时,其实根本没切过来。
第二,降低小流量成本。VM 是「只要开机就烧钱」,哪怕一天只来 3 个人。Cloud Run 按请求次数 + 真正干活的那几秒算,没人访问就缩到 0,个人站、内部小工具、收 Webhook 这种有一搭没一搭的流量,比长期开着 VM 省得多。小白容易踩的坑:别为了「首屏快一点」一上来就加 --min-instances=1,这一加等于又养了台常驻机器,低流量反而多花钱;先默认 0,真觉得冷启动慢再调。
第三,减少发布风险。每次部署不是直接覆盖线上,而是自动多出一个修订版本,改坏了把流量切回上一条就行,不用连夜改代码重传;日志、报错、监控也全挤在同一个控制台,不用一台台机器去翻文件。复制这条,能直接看到「服务 → 当前生效版本」的对应关系:
gcloud run services list --format="table(metadata.name,status.url,status.latestReadyRevisionName)"
为什么这么做:让你亲眼看到「部署 = 多留一行记录」,以后回滚心里有底。小白容易踩的坑:如果最后一列是空的,不是命令写错,只是还没部署过,等后面章节传完第一个版本再回来看就有数据了,别急着删项目重来。
所以这一节不用背概念,记住一句话就够:你买的不是一台机器,是「有人来才干活」的能力。运维、闲置费、改坏回不去,这三个最劝退新人的坎,Cloud Run 在开头就替你垫平了。
怎么上手
按「项目结算 → 能监听端口的程序 → 部署 → 验收」走就好;顺序反了,多半不是代码错,而是被结算或权限挡住。
-
项目和工具。控制台新建或选一个项目,在「结算」关联结算账号:有免费额度也要绑卡,不关联会在启用 API 或 deploy 时报 billing 错,顺手设个预算提醒。到
https://cloud.google.com/sdk/docs/install按系统装 gcloud,Windows 装完要重开终端;不想装就用控制台右上角的 Cloud Shell。下面第一条若报command not found,先别继续。gcloud --version gcloud init gcloud config set compute/region asia-east1 gcloud config set run/region asia-east1 gcloud services enable run.googleapis.com cloudbuild.googleapis.com artifactregistry.googleapis.comgcloud init会弹浏览器登录,按提示选项目、设默认区域;认准项目 ID而不是中文项目名,选错会去别的项目里找不到服务。后两行再把区域兜底成asia-east1,和后面 deploy 一致,避免「部署成功却看不到」。 -
准备程序。可以自己打镜像,也可以让 GCP 从源码自动构建;小白选后者,复制下面几行会生成一个最小 Node 服务:
mkdir -p hello-run && cd hello-run tee index.js <<'EOF' const http = require('http'); const port = process.env.PORT || 8080; http.createServer(function (req, res) { res.end('Hello Cloud Run!'); }).listen(port); EOF printf '%sn' '{"scripts":{"start":"node index.js"}}' | tee package.json重点是读
process.env.PORT:平台注入的端口常见为8080,但别写死 8080、3000 或 80,否则本地正常、线上却启动超时或 502。已有镜像也一样要监听PORT,部署时改用--image指定镜像地址即可。 -
部署。
hello-run是服务名,--allow-unauthenticated表示公开访问;漏了会 403,不是程序挂了。首次可能问要不要建存放镜像的仓库,输入 Y 回车;构建等 1~3 分钟,别反复 Ctrl+C。gcloud run deploy hello-run --source . --region asia-east1 --allow-unauthenticated gcloud run services describe hello-run --region asia-east1 --format='value(status.url)'第二行输出的
https://xxx.run.app就是平台给的网址,贴进浏览器看到 Hello 即上线。 -
上线后收尾。先看日志,再配环境变量、绑域名:
gcloud run services logs read hello-run --region asia-east1 --limit=50 gcloud run services update hello-run --region asia-east1 --update-env-vars APP_ENV=prod read -p "请输入要绑定的域名(没有就留空回车):" DOMAIN if [ -n "$DOMAIN" ]; then gcloud run domain-mappings create --service hello-run --domain "$DOMAIN" --region asia-east1; fi--update-env-vars只加改一个;别用--set-env-vars,它会清掉没写上的旧变量,更新还会生成新修订版。域名留空可跳过;填了就按终端列出的 DNS 记录去域名商添加,HTTPS 证书由 Google 自动签发,不用买证书、配 Nginx 或开 80 端口。没域名时*.run.app已是 HTTPS;刚绑域名等十几分钟,证书提示先别慌。URL=$(gcloud run services describe hello-run --region asia-east1 --format='value(status.url)') curl -i "$URL"最后访问一次:见到
HTTP/2 200和Hello Cloud Run!就通关;403 查公开访问,502 回日志查端口。
与替代方案对比
先把结论说清楚:搜 gcp cloud run 教學时,别把 Cloud Run 和 VM、GKE、App Engine、云函数混在一起。判断只看一件事:你要自己管到哪一层。管得越多,控制力越强,系统、网络、安全和扩容也越费心。先别部署,在终端复制下面三行,只确认工具、账号和当前项目,不会建资源,也不会产生费用。
gcloud --version
gcloud auth login
gcloud config list
为什么先看?小白常踩的坑不是选错产品,而是没装 Google Cloud CLI、没登录,或终端停在旧项目,却以为在正式环境。第一条报「找不到命令」就先装 CLI;第三条看到 account 和 project 再继续。
- 对比 VM:VM 像自己租一台电脑,控制力最高,能改系统、装服务、调端口;但操作系统、防火墙、补丁和扩容都要你管。忘开防火墙会访问不了,忘打补丁有风险。Cloud Run 更省心,把程序和依赖打成容器后自动伸缩,适合 API、网站后台、Webhook 这类无状态服务。坑是别把上传文件、数据库、登录状态写在容器本地,实例重启或扩容会丢,应放数据库或对象存储。
- 对比 GKE 容器集群:GKE 适合复杂微服务和集群编排,也就是管理一堆机器、容器、路由和升级规则;能力强,但节点池、YAML、入口配置对新手不友好。Cloud Run 少配置、上线快,不用先搭集群,运维门槛更低。小项目别为了「看起来专业」一上来就上 GKE。
- 对比 App Engine 和云函数:App Engine 更偏托管运行时,云函数更偏事件触发的一小段函数,例如文件上传后跑一次;它们省事,但语言版本、系统库和常驻进程常受限制。Cloud Run 用容器,语言和运行依赖更自由,可自带库、二进制或系统包。坑是自由不等于不用管,镜像大小、环境变量、超时、并发和权限仍要检查。
零基础可以记住一句话:无状态接口或小网站优先 Cloud Run;要完全控制机器选 VM;已有复杂微服务团队选 GKE;只处理简单事件,或愿意接受固定运行时,再看 App Engine 和云函数。
最佳实践
把下面几条当成「gcp cloud run 教學」的收尾清单。先在 Cloud Shell 选好项目、开通结算,再整段复制;改好 SECRET_VALUE、SERVICE、REGION 再跑。
export PROJECT_ID="$(gcloud config get-value project)"
export REGION="asia-east1"
export SERVICE="hello-prod"
export SA_NAME="cloudrun-least-privilege"
export SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
export SECRET_VALUE="change-me-now"
gcloud services enable run.googleapis.com secretmanager.googleapis.com iam.googleapis.com
--project="$PROJECT_ID"
gcloud iam service-accounts create "$SA_NAME"
--display-name="Cloud Run least privilege"
--project="$PROJECT_ID" >/dev/null 2>/dev/null || true
if gcloud secrets describe db-password --project="$PROJECT_ID" >/dev/null 2>/dev/null; then
printf '%s' "$SECRET_VALUE" | gcloud secrets versions add db-password
--data-file=- --project="$PROJECT_ID"
else
printf '%s' "$SECRET_VALUE" | gcloud secrets create db-password
--data-file=- --replication-policy="automatic"
--project="$PROJECT_ID"
fi
gcloud secrets add-iam-policy-binding db-password
--member="serviceAccount:${SA_EMAIL}"
--role="roles/secretmanager.secretAccessor"
--project="$PROJECT_ID"
gcloud run deploy "$SERVICE"
--image="gcr.io/cloudrun/hello"
--service-account="$SA_EMAIL"
--set-secrets="DB_PASSWORD=db-password:latest"
--concurrency=80 --timeout=300
--max-instances=10 --min-instances=0
--allow-unauthenticated
--region="$REGION" --project="$PROJECT_ID"
为什么:新建的服务账号只给「读取这一个密钥」的权限,别图省事给编辑者。密码进 Secret Manager,部署时引用,镜像和版本配置里都没有明文。小白常把密码写进 Dockerfile、镜像层或控制台「环境变量」框:镜像能拉下来,配置能看见,改密码还要重新打包。也别让所有服务共用一个高权限账号;公网能访问不等于账号权限大,这是两件事。
同一条命令也拧好了容量:并发 80 是一个实例同时接 80 个请求,不是每秒 80 次,CPU 重就调小;超时 300 秒防卡住的请求一直占资源;最大 10 实例是账单刹车;最小 0 最省钱但有冷启动,怕抖改成 1,它会一直计费。别把最小值照抄成 10,半夜没流量也花钱。上线前再复制下一段做检查和回滚演练。
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=${SERVICE}"
--limit=20 --freshness=1h --project="$PROJECT_ID"
--format="table(timestamp,severity,textPayload)"
gcloud billing accounts list --format="table(name,displayName)"
export PREV_REV="$(gcloud run revisions list --service="$SERVICE"
--region="$REGION" --project="$PROJECT_ID"
--sort-by="~metadata.creationTimestamp" --limit=2
--format="value(metadata.name)" | tail -n 1)"
gcloud run services update-traffic "$SERVICE"
--to-revisions="${PREV_REV}=100"
--region="$REGION" --project="$PROJECT_ID"
先看日志有没有启动报错,再到 Cloud Monitoring 给 5xx、P95 延迟、实例数建告警;用列出的结算账号去「结算 > 预算和提醒」建 100%、120% 提醒。回滚要真练:若刚才只有一个版本,先再部署一次,再重跑回滚那两段,否则等于切回自己。镜像用多阶段、slim 或 distroless,每月更新基础镜像并重发。坑是全用 latest,出事不知道回哪一版,记下版本号或摘要。下一段先把 DOMAIN 换成你能管 DNS 的域名,example.com 只是占位。
export DOMAIN="www.example.com"
export STAGING_SERVICE="${SERVICE}-staging"
export STAGING_SA_NAME="cloudrun-staging"
export STAGING_SA_EMAIL="${STAGING_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts create "$STAGING_SA_NAME"
--display-name="Cloud Run staging"
--project="$PROJECT_ID" >/dev/null 2>/dev/null || true
gcloud run deploy "$STAGING_SERVICE"
--image="gcr.io/cloudrun/hello"
--service-account="$STAGING_SA_EMAIL"
--concurrency=80 --timeout=60
--max-instances=2 --min-instances=0
--no-allow-unauthenticated
--region="$REGION" --project="$PROJECT_ID"
if gcloud run domain-mappings describe "$DOMAIN" --region="$REGION" --project="$PROJECT_ID" >/dev/null 2>/dev/null; then
echo "域名映射已存在,跳过创建"
else
gcloud run domain-mappings create
--service="$SERVICE" --domain="$DOMAIN"
--region="$REGION" --project="$PROJECT_ID"
fi
gcloud run domain-mappings list --region="$REGION" --project="$PROJECT_ID"
不改域名会验证失败。按控制台给的记录填 DNS,HTTPS 证书由 Cloud Run 自动签发,等生效即可;别自己传证书,也别在容器里监听 443,程序只监听平台给的 PORT,别写死 8080。测试最好另开项目,至少像上面另起服务名、账号和上限;密钥、预算再按环境分开,且测试服务不公开。最常见事故就是压测脚本或 DNS 指到生产;拆开后就碰不到正式数据。
常见问题(FAQ)
Cloud Run 和 VM 有什么区别?
Cloud Run 不用管系统和 SSH,VM 要自己装环境、打补丁和扩容。
不会容器也能用吗?
可以,用源码部署或自动构建;但理解容器镜像会更利于排错。
Cloud Run 会不会很贵?
小流量通常很省,按请求和运行时间计费;建议设预算告警和最大实例数。
需要绑定域名和 HTTPS 吗?
正式站点建议绑定自定义域名,Cloud Run 可提供托管证书和 HTTPS。
不想自己折腾 GCP?我们提供云平台代维护、上云迁移与账单代付服务,一对一技术支持。
