GCP-109:Cloud Run 入門——零運維容器部署完全指南
前言
你有一個 Docker 容器,想把它部署到雲端——最快的方式是什麼?答案是 Cloud Run。
Cloud Run 是 GCP 的無伺服器容器平台。你只要丟一個容器映像給它,伸縮、負載均衡、TLS 憑證、網域名稱它全部幫你搞定,完全零運維。流量來了自動擴展,沒流量時縮到零,這段時間不收你錢。
這篇是 GCP 入門系列第 9 課,從概念一路講到實際操作,帶你把 Cloud Run 的核心用法搞懂。
什麼是 Cloud Run?
Cloud Run 讓你直接部署容器,不用管伺服器。它是建在 Knative 標準上,分成兩種形態:
| 形態 | 用途 | 觸發方式 |
|---|---|---|
| Cloud Run Services | 持續接收 HTTP/gRPC 請求 | HTTP 請求 |
| Cloud Run Jobs | 執行到完成的批次任務 | 手動/排程觸發 |
Gen1 vs Gen2 執行環境
Cloud Run 有兩種執行環境,新服務建議用 Gen2。如果你沒指定,Cloud Run 會看你用到的功能自動幫你選(多數向後相容的情境會走 Gen1,需要完整 Linux 相容性等功能時則用 Gen2):
| 特性 | Gen1 | Gen2 |
|---|---|---|
| 基礎技術 | gVisor 沙盒 | MicroVM(完整 Linux) |
| 系統呼叫 | 受限(不支援全部 syscall) | 完整支援 |
| 冷啟動速度 | 較快(Bursty 流量佳) | 較慢 |
| CPU 效能 | 標準 | 更高(適合計算密集) |
| 記憶體下限 | 128 MiB | 512 MiB |
| 網路吞吐量 | 標準 | 更高 |
| NFS 支援 | ❌ | ✅ |
選擇指引:
- Gen2(預設):大多數場景都適合,尤其是需要完整 Linux 相容性、高效能、或要掛 NFS 的應用
- Gen1:適合那種要求冷啟動超低延遲的 bursty 工作負載(例如事件觸發、跑一下就結束的短暫函式)
資源限制
| 項目 | 限制 |
|---|---|
| 最大 vCPU | 8 個(每實例) |
| 最大記憶體 | 32 GiB(每實例) |
| 最大請求逾時 | 60 分鐘 |
| 最大啟動逾時 | 4 分鐘 |
| 每實例最大並發請求 | 1,000(預設 80) |
| 最大環境變數 | 1,000 個 |
| 最大請求/回應大小 | 32 MiB |
CPU 分配模式
這是 Cloud Run 計費上最關鍵的概念之一,搞懂它才不會帳單爆掉:
模式一:CPU only during request(預設)
CPU 只在請求處理期間分配,空閒時釋放:
請求進來 → CPU 分配 → 處理完成 → CPU 釋放 → 收費結束
適合:
- Bursty / 間歇性流量
- 純 HTTP API
- 無背景任務需求
模式二:CPU always allocated(持續分配)
即使沒有請求,CPU 也持續分配給執行中的實例:
實例啟動 → CPU 持續分配(可做背景工作)→ 實例停止 → 收費結束
適合:
- 需要在回應後繼續執行背景任務(如:寫入 queue、非同步工作)
- 穩定流量應用(持續收費但有 Committed Use Discount)
- Streaming 長連線
設定方式:
gcloud run deploy my-service \
--image asia-east1-docker.pkg.dev/my-project/my-repo/my-app \
--cpu-throttling=false # 持續分配 CPU
最小/最大實例數
縮容至零(預設行為)
預設 min-instances=0,沒流量時實例會全部縮掉。等第一個請求進來才重新啟動,這就是冷啟動(cold start),大概要等 1-2 秒。
設定最小實例(消除冷啟動)
gcloud run deploy my-service \
--image asia-east1-docker.pkg.dev/my-project/my-repo/my-app \
--min-instances=1 \
--max-instances=10
--min-instances=1:至少保留 1 個暖機實例--max-instances=10:最多 10 個實例(預設 100)
費用說明:
- 最小實例在沒有請求時,以「idle instance」費率計費(比活躍費率低)
- 如果用「CPU 持續分配」模式,即使 idle 也按全費率計費
部署方式
方式一:從容器映像部署(最常見)
gcloud run deploy my-service \
--image us-docker.pkg.dev/my-project/my-repo/my-app:v1 \
--region asia-east1 \
--allow-unauthenticated
方式二:從原始碼部署(自動 build)
# 在有 Dockerfile 的目錄執行
gcloud run deploy my-service \
--source . \
--region asia-east1
Cloud Run 會自動用 Cloud Build 幫你建映像再部署,拿來快速測試很方便。
完整部署範例
gcloud run deploy my-api \
--image us-docker.pkg.dev/my-project/backend/api:latest \
--region asia-east1 \
--platform managed \
--allow-unauthenticated \
--concurrency=80 \
--min-instances=1 \
--max-instances=20 \
--memory=512Mi \
--cpu=1 \
--timeout=60s \
--set-env-vars="NODE_ENV=production,LOG_LEVEL=info"
流量管理與版本控制
每次部署 Cloud Run 都會產生一個新的 Revision(版本),而且你可以在不同版本之間分流量:
查看 Revision
gcloud run revisions list --service my-service --region asia-east1
流量分流(金絲雀發布)
# 90% 流量到舊版,10% 到新版
gcloud run services update-traffic my-service \
--region asia-east1 \
--to-revisions my-service-00004-abc=90,my-service-00005-xyz=10
切換全部流量到最新版
gcloud run services update-traffic my-service \
--region asia-east1 \
--to-latest
Revision 標籤(測試用)
# 為特定 revision 加標籤,建立獨立 URL 測試
gcloud run services update-traffic my-service \
--set-tags canary=my-service-00005-xyz \
--region asia-east1
# 測試 URL:https://canary---my-service-xxxxx.run.app
認證與存取控制
公開服務(允許未認證)
# 部署時指定
gcloud run deploy my-service --allow-unauthenticated
# 或部署後修改
gcloud run services add-iam-policy-binding my-service \
--region asia-east1 \
--member="allUsers" \
--role="roles/run.invoker"
私有服務(需要 IAM 認證)
預設行為,只有具備 roles/run.invoker 的 Principal 能呼叫:
# 允許特定 Service Account 呼叫
gcloud run services add-iam-policy-binding my-service \
--region asia-east1 \
--member="serviceAccount:my-sa@my-project.iam.gserviceaccount.com" \
--role="roles/run.invoker"
服務之間互相呼叫時,呼叫方需要在 HTTP Header 帶入 ID Token:
Authorization: Bearer <ID_TOKEN>
VPC 連線(連接內部資源)
當 Cloud Run 要連 Cloud SQL、Memorystore(Redis)這類 VPC 內部資源時,有兩種做法:
Direct VPC Egress(推薦,GA)
直接從 VPC 子網路拿 IP,中間不用架代理:
gcloud run deploy my-service \
--image my-image \
--network my-vpc \
--subnet my-subnet \
--vpc-egress=private-ranges-only # 只有私有 IP 走 VPC
| 特性 | Direct VPC Egress | VPC Access Connector(舊) |
|---|---|---|
| 架構 | 直接從 VPC 子網路取 IP | 透過代理 VM 中繼 |
| 吞吐量 | ~1 Gbps/實例 | ~500 Mbps/實例 |
| 費用 | 只收網路費 | 還需付代理 VM 費用 |
| 推薦程度 | ✅ 2024 起推薦 | ⚠️ 舊方案,仍支援 |
VPC 輸出流量模式
--vpc-egress=private-ranges-only # 只有 RFC1918 走 VPC(推薦)
--vpc-egress=all-traffic # 所有流量走 VPC(含外部流量)
Secret Manager 整合
方式一:掛載為環境變數
gcloud run deploy my-service \
--image my-image \
--update-secrets=DB_PASSWORD=db-password:latest
容器內:
import os
db_password = os.environ["DB_PASSWORD"] # 自動解析 secret 值
方式二:掛載為檔案(支援動態更新)
gcloud run deploy my-service \
--image my-image \
--update-secrets=/secrets/config=app-config:latest
容器內:
with open("/secrets/config") as f:
config = f.read()
IAM 需求:Cloud Run Service Account 需要 roles/secretmanager.secretAccessor
Cloud Run Jobs(批次任務)
如果你要跑的是那種「有開始有結束」的任務(像資料轉換、產報表、定期清理),就用 Cloud Run Jobs:
# 建立 Job
gcloud run jobs create my-job \
--image asia-east1-docker.pkg.dev/my-project/my-repo/batch-processor \
--region asia-east1 \
--tasks=10 \ # 平行任務數
--max-retries=3 \ # 失敗重試次數
--task-timeout=600 # 每個任務最長 10 分鐘
# 手動執行
gcloud run jobs execute my-job --region asia-east1
# 查看執行狀態
gcloud run jobs executions list --job my-job --region asia-east1
Cloud Run Jobs 與 Cloud Run Services 比較:
| 特性 | Services | Jobs |
|---|---|---|
| 觸發方式 | HTTP 請求 | 手動 / 排程 / Cloud Scheduler |
| 執行模型 | 持續運行 | 執行到完成 |
| 計費 | 依請求/實例時間 | 只收執行時間 |
| 最長執行時間 | 60 分鐘(每請求) | 168 小時(7 天) |
| 適合場景 | API、Web App | 批次處理、ETL、定期任務 |
定價與免費層
免費層(每月)
| 項目 | 免費額度 |
|---|---|
| 請求數 | 200 萬次 |
| 記憶體使用 | 360,000 GB-秒 |
| CPU 使用 | 180,000 vCPU-秒 |
| 對外流量(北美) | 1 GB |
超過免費層的費用(Tier 1 區域)
| 項目 | 費用 |
|---|---|
| CPU | $0.000024 / vCPU-秒 |
| 記憶體 | $0.0000025 / GB-秒 |
| 請求 | $0.40 / 100 萬次 |
💡 低流量的個人專案通常可以完全維持在免費層內
Cloud Run vs App Engine vs Cloud Functions
| 特性 | Cloud Run | App Engine | Cloud Functions |
|---|---|---|---|
| 部署單位 | 容器 | 應用程式 | 函式 |
| 語言支援 | 任何(容器) | 指定 runtime | 指定 runtime |
| 最大執行時間 | 60 分鐘 | 可配置 | 60 分鐘(Gen2) |
| 冷啟動 | 秒級 | 較慢 | 毫秒~秒級 |
| VPC 連線 | Direct VPC Egress | 原生 VPC | 需要 VPC Connector |
| 最適合 | 容器化 API / 服務 | 傳統 Web 應用 | 事件觸發函式 |
ACE 考試重點整理
必背知識點
- Cloud Run 預設縮容至零,min-instances=0,第一個請求會有冷啟動
- Gen2 是新服務的推薦執行環境,有完整 Linux 相容性(未指定時 Cloud Run 會依功能自動選擇)
- CPU always allocated 允許背景任務,但費用較高
- 預設並發請求數 80,最大 1,000
- Direct VPC Egress(GA) 是目前推薦的 VPC 連線方式,取代 VPC Connector
- roles/run.invoker 是呼叫 Cloud Run 服務所需的角色
- Cloud Run Jobs 最長可執行 7 天,Services 最長 60 分鐘/請求
常見陷阱題
Q:Cloud Run 可以設定 CPU 永遠不縮容嗎?
A:不能。只能設定 min-instances 避免縮容至零,但不是永遠保持 CPU 全速。CPU 分配模式決定空閒時 CPU 是否被釋放。
Q:如何避免 Cloud Run 冷啟動?
A:設定 --min-instances=1 或以上,保持至少一個暖機實例。
Q:Cloud Run 服務可以互相呼叫嗎?
A:可以,但呼叫方需要在 Header 帶 ID Token,且目標服務的 IAM 需授予呼叫方 roles/run.invoker。
Q:Cloud Run 有免費方案嗎? A:有。每月 200 萬次請求、180,000 vCPU-秒、360,000 GB-秒免費。
實戰範例:部署 Node.js API
# Dockerfile
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]
# 建立 Artifact Registry repo
gcloud artifacts repositories create backend \
--repository-format=docker \
--location=asia-east1
# 建立映像
gcloud builds submit \
--tag asia-east1-docker.pkg.dev/my-project/backend/api:v1
# 部署 Cloud Run 服務
gcloud run deploy api \
--image asia-east1-docker.pkg.dev/my-project/backend/api:v1 \
--region asia-east1 \
--allow-unauthenticated \
--min-instances=1 \
--max-instances=20 \
--concurrency=100 \
--memory=512Mi \
--cpu=1 \
--set-env-vars="NODE_ENV=production" \
--update-secrets="DB_PASSWORD=db-password:latest"
# 取得服務 URL
gcloud run services describe api \
--region asia-east1 \
--format="value(status.url)"
總結
在 GCP 上部署容器化應用,Cloud Run 大概是最省事的選擇了。幾個重點幫你收尾:
- 零運維:自動伸縮、TLS、負載均衡全包
- Gen2 為推薦:完整 Linux 相容,效能更好
- CPU 分配模式:request-based(省錢)vs always-allocated(可背景處理)
- 冷啟動:設定 min-instances 消除冷啟動
- VPC 連線:Direct VPC Egress 是新標準
- 免費層:每月 200 萬請求免費
下一課 ACE-210:GCP 負載均衡深度解析,會帶你看 Application Load Balancer、Cloud CDN 跟 Cloud Armor 怎麼搭起完整架構。
運算服務選型系列
| 課程 | 服務 | 適合場景 |
|---|---|---|
| 本課 GCP-109 | Cloud Run | 容器化 API/微服務,scale-to-zero |
| GCP-111 | Cloud Functions | 事件驅動單一函式(GCS/Pub/Sub 觸發) |
| ACE-212 | App Engine | 快速部署 Web App、免費層最多 |
| ACE-206 | GKE | 完整 K8s 控制、大規模微服務 |
| ACE-203 | 綜合比較 | 全部 Serverless 選型決策樹 |