從 AWS 到 GCP:DevOps 工程師的跨雲心智模型與架構對照
當熟悉 AWS 的 DevOps 工程師第一次接觸 Google Cloud Platform(GCP)時,最常遇到的挑戰往往不是名詞對應,而是底層架構假設的衝突。
兩者雖然都提供虛擬機器、受管容器、物件儲存與身分驗證,但在資源邊界、權限繼承方式與網路拓撲等核心設計上,存在本質上的心智模型差異。若直接將 AWS 的操作直覺套用至 GCP,不僅容易在 Terraform 部署時引發非預期的權限覆蓋,還可能在網路規劃與 Kubernetes 整合上造成誤判。
核心架構對照總覽
在深入機制前,下表整理了 DevOps 日常維運中最具「心智衝突」的架構面向:
| 領域 | AWS 概念 | GCP 概念 | 差異程度 | 關鍵思維轉折 |
|---|---|---|---|---|
| 資源隔離 | AWS Organizations / Account | Organization / Folder / Project | 高 | Project 是信任邊界與計費單位,非獨立帳號 |
| 身分授權 | IAM User / Role / Policy | IAM Principal / Role / Allow Policy | 高 | 權限掛在資源階層並向下繼承;Role 僅是權限集合 |
| 虛擬網路 | VPC(區域限定) | VPC(全域,Subnet 為區域) | 高 | 單一 VPC 跨越全球,跨區互通不需 Peering |
| 防火牆 | Security Group + NACL | VPC Firewall Rules / Policies | 中 | 單層有狀態防火牆,支援 Allow/Deny 與 Priority |
| 私有連線 | VPC Endpoint / PrivateLink | Private Google Access / Private Service Connect / Private Services Access | 中 | 依目標拆分為三套機制,存取 Google API 免費 |
| 對外連線 | NAT Gateway(傳統為每 AZ 一台) | Cloud NAT | 中 | 軟體定義分散式架構,依附於 Cloud Router |
| 負載平衡 | ALB / NLB(區域資源) | Cloud Load Balancing | 中 | 全球 Anycast 單一 IP 入口,多資源組合架構 |
| 容器編排 | Amazon EKS | Google Kubernetes Engine (GKE) | 中 | 內建自動滾動升級、VPC-native 與 Autopilot |
| 無伺服器容器 | ECS on Fargate / App Runner | Cloud Run | 中 | 單一平台整合 HTTP 服務、排程工作與背景工作池 |
| 稽核日誌 | AWS CloudTrail | Cloud Audit Logs | 中 | Admin 日誌強制開啟免費,Data 日誌預設關閉 |
1. 資源階層與 IAM:向下繼承的聯集模型
Project 不是 AWS Account
在 AWS 中,最根本的隔離邊界是 AWS Account。Organizations 透過 Organizational Units (OU) 分組,並以 Service Control Policies (SCP) 由上至下限制最大權限,但各 Account 的 IAM 系統各自獨立。
GCP 則採用嚴密的樹狀階層結構:Resource Hierarchy 規範了 Organization → Folder → Project → 底層資源 的從屬關係。
AWS Model:
[Organization] --> [OU] --> [AWS Account]
+-- Role / User / Resources
GCP Model:
[Organization]
+-- [Folder]
+-- [Project] (Resource Container & Billing Unit)
+-- Compute Engine / GKE / Cloud Storage
在 GCP 中,Project 是計費、配額、API 啟用與預設網路的承載容器。核心差異在於權限的流動方向:
- 掛載位置:AWS 的 IAM Policy 主要掛在身分(User、Role)上;GCP 的 Allow Policy 則掛在資源階層上,定義「哪個 Principal 在此節點具備哪個 Role」。
- 向下繼承:父層(如 Folder)賦予的權限,會自動繼承至底下所有的 Project 與資源。
- 聯集規則:依據 GCP 的權限繼承模型,資源的最終有效權限是該資源本身的 Policy 與其所有父層 Policy 的聯集。這意味著子層無法收回父層已發放的權限;若要排除,必須使用 IAM Deny Policy 或在 Organization 層級設定 Organization Policy。
Service Account 對比 IAM Role
AWS 的 IAM Role 像是一頂「帽子」,EC2 透過 Instance Profile 戴上,Lambda 透過 Execution Role 戴上,開發者透過 AssumeRole 戴上。
GCP 則將身分與權限完全解耦為兩個獨立物件:
- Role:純粹的權限清單(如
roles/storage.objectViewer),本身不是身分,無法被「擔任」。 - Service Account (SA):具備電子郵件格式的機器身分(如
deployer@PROJECT_ID.iam.gserviceaccount.com)。
兩者在架構上的本質差異如下表所示:
| 比較面向 | AWS IAM Role | GCP Service Account |
|---|---|---|
| 本質定義 | 虛擬身分(可被實體擔任) | 機器身分(具備專屬 Email) |
| 權限設定 | 直接附加 IAM Policy | 在資源階層上授予 Role(權限集合) |
| 運算綁定 | Instance Profile / Execution Role | 附掛至 VM、GKE 節點或 Cloud Run |
| 自身屬性 | 純身分物件 | 身分兼資源(需授權才能使用) |
WARNING
兩層授權盲點:在 GCP 中,Service Account 本身也是一項資源。要讓某個運算單元(或使用者)以該 SA 執行,操作者必須在該 SA 上擁有 roles/iam.serviceAccountUser 權限。擁有部署權限不等於擁有使用特定 SA 的權限。
實務維運時,有兩項最佳實踐建議遵循:
- 停用預設 SA 的過大權限:Compute Engine 自動建立的 Default SA 通常具備寬鬆的
Editor權限。建議透過 Organization Policy 關閉自動授權,改用自訂的最小權限 SA。 - 摒棄長期 Key 檔:避免下載 Service Account JSON Key,改用附掛身分、IAM Impersonation(角色模擬,類似 AWS 的
AssumeRole)或 Workload Identity Federation(跨雲對接 AWS 時直接以 IAM Role 換發短期 Token)。
Terraform 裡的 IAM 陷阱與本機認證
在 AWS Terraform 中,aws_iam_role_policy_attachment 只管理特定 Policy 與 Role 的關聯,不會影響其他既有設定。但 GCP Provider 提供了三種不同粒度的 IAM 資源(詳見 google_project_iam),其行為與影響範圍大不相同:
# 1. google_project_iam_binding (權威覆蓋單一 Role)
# 獨占特定 Role 的成員清單。若有人在 Console 手動加入其他成員,下次 Apply 會被強制剔除!
resource "google_project_iam_binding" "editor_binding" {
project = var.project_id
role = "roles/editor"
members = ["serviceAccount:${google_service_account.admin.email}"]
}
# 2. google_project_iam_member (最安全:增量加入)
# 僅新增一筆授權,不影響該 Role 下的其他成員或 Console 設定。
resource "google_project_iam_member" "deployer_ar_writer" {
project = var.project_id
role = "roles/artifactregistry.writer"
member = "serviceAccount:${google_service_account.deployer.email}"
}
在既有專案中編寫 IaC 時,建議一律優先使用 google_project_iam_member,避免因使用 iam_binding 或全域覆蓋的 iam_policy 造成非預期的權限抹除。
TIP
本機認證盲點:gcloud 與 ADC 分離:撰寫並於本機測試上述 Terraform 時,AWS CLI 與 SDK 共用 ~/.aws/credentials;GCP 則將兩者分開。gcloud auth login 僅登入 CLI 本身,執行 Terraform 或以 SDK 開發程式時,必須另外執行 gcloud auth application-default login 產生本機 ADC 憑證檔,否則會出現指令正常但程式拋出認證失敗的現象。
2. 網路架構:全域 VPC、Shared VPC 與軟體定義邊界
全域 VPC 與區域 Subnet
AWS 的 VPC 屬於單一 Region,而 Subnet 屬於該 Region 內的單一 Availability Zone (AZ)。若要讓兩個跨 Region 的 VPC 互通,必須建立 VPC Peering 或透過 Transit Gateway 路由。
GCP 的 VPC 是全域資源(Global Resource),而 Subnet 則是區域資源(Regional Resource):
AWS Architecture (Regional VPC):
[Region: us-east-1] [Region: ap-northeast-1]
+-----------------------+ +-----------------------+
| VPC: 10.0.0.0/16 | | VPC: 10.1.0.0/16 |
| +-- Subnet AZ-a |<->| +-- Subnet AZ-a |
| +-- Subnet AZ-b | | +-- Subnet AZ-b |
+-----------------------+ +-----------------------+
(跨 Region 需 Peering 或 Transit Gateway)
GCP Architecture (Global VPC):
+---------------------------------------------------+
| Global VPC Network |
| +-- Region: us-central1 (Subnet: 10.128.0.0/20) |
| +-- Region: asia-east1 (Subnet: 10.140.0.0/20) |
| |
| <--- Direct Internal Routing ---> |
+---------------------------------------------------+
這項架構帶來三大根本轉變:
- 天然內網互通:位於
asia-east1的 VM 與us-central1的 VM,只要在同一個 VPC 內,直接使用內部 IP 即可互通,走 Google 全球骨幹網路,完全無需 Peering。 - Subnet 跨越所有 Zone:Subnet 不綁定特定 Zone。在同一個 Region 內只需規劃一個 Subnet,該區域內的所有 Zone 均可共享此網段。
- 無 Public/Private Subnet 之分:GCP 沒有 Internet Gateway (IGW) 資源。VM 能否連上外部網路,取決於該 VM 是否掛載外部 Public IP,或該區域是否設定了 Cloud NAT。
NOTE
跨專案架構:Shared VPC:類似 AWS RAM 共用 Subnet,GCP 的 Shared VPC 允許將單一 Host Project 的 VPC 網路分享給多個 Service Project 使用。網路團隊在 Host Project 統一管理 Subnet 與防火牆,各應用團隊則在 Service Project 建立 VM 或 GKE 叢集,與 Project 權限隔離架構契合。
防火牆機制與三種「標記」辨析
AWS 採用雙層模型:掛載於 ENI 的 Security Group(有狀態、僅能 Allow)搭配掛載於 Subnet 的 NACL(無狀態、支援 Allow/Deny、具備 Rule Number 順序)。
GCP 將兩者融合成單一系統 VPC Firewall Rules:
- 有狀態偵測:回程流量自動放行。
- 支援 Allow 與 Deny:使用 Priority(
0至65535,數字越小優先權越高)決定規則比對順序。 - 目標選擇器:透過 Network Tags(純字串標籤)或 Target Service Accounts(服務帳號)選定套用實例。
resource "google_compute_firewall" "allow_lb_to_web" {
name = "allow-lb-to-web"
network = google_compute_network.main.id
direction = "INGRESS"
priority = 1000
source_ranges = ["35.191.0.0/16", "130.211.0.0/22"] # Google LB 探測與 GFE 對後端流量網段
target_service_accounts = [google_service_account.web.email]
allow {
protocol = "tcp"
ports = ["8080"]
}
}
AWS 的 Tag 只有一種,GCP 則將「標記」拆分成三種互不相通的獨立機制:
| 標記類型 | 定義層級與特性 | 核心用途與限制 |
|---|---|---|
| Labels | 資源層級(Key-Value) | 僅用於帳單成本拆分與 Console 篩選,無法作為 IAM 或防火牆條件 |
| Tags (RM Tags) | Organization / Project 層級(階層繼承) | 具備強型別與權限控管,可作為 IAM 條件與 Org Policy 條件 |
| Network Tags | VM 屬性(純字串清單) | 僅用於 VPC 防火牆規則與路由之目標篩選,無 IAM 存取控制 |
因此在安全要求嚴格的環境中,防火牆規則應改用 Target Service Accounts 作為目標過濾條件,避免因 VM 上的 Network Tag 被任意修改而繞過防禦。
私有連線與負載平衡架構
AWS 將不對外連線的私有存取統一歸在 VPC Endpoint。GCP 則依目標型態拆分為三套獨立機制:
- Private Google Access:Subnet 層級一鍵開啟,讓僅有內部 IP 的 VM 完全免費存取 Google APIs(如 GCS、BigQuery),無需建立 Endpoint 網路卡。
- Private Service Connect (PSC):等同 AWS PrivateLink,透過自訂內部 IP 端點連向第三方 SaaS 或跨 VPC 發布之私有服務。
- Private Services Access (PSA):以 VPC Peering 形式專門對接 Google 託管服務(如 Cloud SQL、Memorystore)的內部專屬網段;Cloud SQL 的私有 IP 連線現由官方建議採用 PSC,新專案的預設選項也是 PSC;PSA 屬較早期機制。
在對外連線與負載平衡方面:
- Cloud NAT:AWS NAT Gateway 建於特定 AZ,傳統上需在各 AZ 獨立建立以確保高可用性(2025 年 11 月起另有自動跨 AZ 的 Regional NAT Gateway);GCP 的 Cloud NAT 為分散式軟體架構,直接設定於區域內的 Cloud Router,無需維護 Proxy VM。
- Cloud Load Balancing:AWS ALB/NLB 屬於區域資源;GCP 提供 Global External Application Load Balancer,具備單一 Anycast IP。全球流量會從距離使用者最近的 Google Edge 節點進入骨幹網路,並自動將請求分發給多個 Region 的後端服務,內建跨區容錯。
NOTE
3. Kubernetes:GKE 對比 EKS 的雲端整合
對於具備 CKA(Certified Kubernetes Administrator)認證的工程師而言,kubectl、Deployment 與 Service 等 Kubernetes 原生概念完全通用,關鍵差異在於雲端託管層。
Standard 與 Autopilot 模式
EKS 的節點管理通常搭配 Managed Node Group、Karpenter 或 Fargate。GKE 則在叢集建立時提供兩種模式:
| 評估面向 | GKE Standard | GKE Autopilot |
|---|---|---|
| 節點管理 | 使用者自管 Node Pool | Google 全託管 Worker Nodes |
| 控制平面 | 支援 Zonal(單點)與 Regional(高可用性) | 強制 Regional(跨多 Zone 複製備援) |
| 計費基礎 | 節點規格與數量(VM 費用) | Pod 宣告之 Resource Requests |
| 節點存取 | 支援 SSH 與節點級除錯查修 | 禁止 SSH,完全依賴 Cloud Logging |
| 升級機制 | 可自訂或搭配 Release Channel | 強制鎖定 Release Channel 自動升級 |
WARNING
Standard 叢集的單點盲點:AWS EKS 的 Control Plane 永遠由 AWS 跨多可用區託管。但 GKE Standard 允許建立 Zonal 叢集(Control Plane 僅落在單一 Zone,成本較低但存在單點失效風險)。在正式生產環境中,務必建立 Regional 叢集 以確保 Control Plane 高可用性。
在 GKE Autopilot 下,維運思維需要調整:資源請求(Requests)直接等於帳單費用;節點維護工作全部由 Google 代管,日誌與故障排除需完全依賴 Cloud Logging 與 kubectl describe。
VPC-Native 叢集與次要 IP 範圍
在 AWS EKS 中,VPC CNI 讓 Pod 直接佔用 Subnet 網段內的 IP 位址,叢集擴充時容易耗盡 Subnet 的 IP。
GKE 預設採用 VPC-Native 架構(Alias IP):
GCP Subnet CIDR Layout for GKE:
+---------------------------------------------------+
| Primary CIDR: 10.0.0.0/24 (Node VMs) |
| Secondary CIDR 1: 10.4.0.0/14 (Pods) |
| Secondary CIDR 2: 10.8.0.0/20 (Services) |
+---------------------------------------------------+
正因為 Secondary Range 的 Pod IP 在整個 VPC 內具備原生路由能力,Google Cloud Load Balancer 能透過 Network Endpoint Groups (NEG) 繞過 NodePort 與 kube-proxy,將流量直接送達 Pod IP(Container-Native Load Balancing),大幅減少網路躍點(Hop)與延遲。
Workload Identity Federation for GKE
在 AWS EKS 中,Pod 存取 AWS API 早期使用 IRSA(需建立 OIDC Provider 與 Trust Policy),現今亦可使用 EKS Pod Identity。
GKE 對應的解決方案為 Workload Identity Federation for GKE。開啟後,節點上的 Metadata Server 會攔截憑證請求,將 Kubernetes ServiceAccount (KSA) Token 轉換為 GCP 的短期 Access Token。
目前 GCP 主推的作法,是直接授權給 KSA Principal,其格式如下:
principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME
此格式可直接作為任何 GCP 資源 IAM Policy 的 member 綁定,省略額外建立中間 GCP Service Account 的步驟。
IMPORTANT
Project Number vs Project ID:設定 Workload Identity Principal 時,字串路徑中必須填入數字組成的 Project Number(而非英文字串 Project ID)。這是跨雲設定中常見的除錯盲點。
自動滾動升級機制(Release Channels)
在 EKS 中,Kubernetes 升級必須由維運人員主動觸發 Control Plane 與 Node Group 的升級流程。
GKE 則預設導入 Release Channels(Rapid、Regular、Stable,Standard 叢集另可選擇提供長期支援的 Extended):
- Control Plane 與 Node 均會自動滾動升級。
- DevOps 的核心責任轉變為:設定完善的 PodDisruptionBudget (PDB)、在 API 棄用前及早改用新版,以及設定 Maintenance Windows(維護時段)與排除期間,確保自動升級不影響核心業務。
4. 無伺服器運算邊界:Cloud Run 的全情境整合
相較於 AWS 將 Serverless 運算拆分為 Lambda(純函式)、App Runner(簡易容器)與 ECS on Fargate(完整容器任務),GCP 則將這類無伺服器工作負載高度收斂至 Cloud Run 平台。
Cloud Run 的核心價值在於:使用同一份標準 Docker 容器映像檔與統一的 IAM 模型,即可覆蓋多種運算情境:
| 運作模式 | 觸發與生命週期 | 適用情境 |
|---|---|---|
| Services | HTTP / gRPC 請求驅動(支援縮容至零) | Web API、Microservices、Webhooks |
| Jobs | 批次呼叫或 Cloud Scheduler 定期排程 | 資料轉換、DB Migration、報表產製 |
| Worker Pools | 持續自 Pub/Sub 等佇列拉取訊息 | 非同步事件處理、背景佇列消費 |
過往獨立的 Cloud Functions 目前也已全面納入 Cloud Run functions 體系。對於維運團隊而言,當面對無狀態工作時,Cloud Run 能免去 Kubernetes 叢集與節點維護負擔。
5. 維運邊界:稽核日誌、API 生態與計費機制
稽核日誌機制(對比 CloudTrail)
GCP 的 Cloud Audit Logs 在架構上有明確的收費與啟用邊界:
- Admin Activity 與 System Event:強制開啟且免費保留 400 天(寫入
_Requiredlog bucket),無法被手動停用。任何資源的建立、修改與刪除皆會自動記錄。 - Data Access 日誌:記錄資料層的讀寫呼叫(如讀取 Cloud Storage 物件),預設關閉(BigQuery 除外),開啟後將依日誌量計費。
API 生態與承諾使用折扣(CUD)
- API 必須主動啟用,停用則有風險:AWS 帳號預設開啟所有服務;GCP 每個 Project 必須主動啟用 API 才能使用(如
container.googleapis.com)。在 Terraform 中通常透過google_project_service集中管理宣告。特別需注意:若停用某個 API(如停用 Cloud Run API),專案內該服務下的所有既有實例與資源將被直接刪除,屬於破壞性操作。 - 跨服務彈性折扣(CUD):AWS Savings Plans 依運算類型分立。GCP 的 Committed Use Discounts (CUD) 除了針對 Compute Engine 提供專屬資源承諾,亦支援 Spend-based Flexible CUD;後者可同時折抵 Compute Engine、GKE 與 Cloud Run 的花費,為混合架構提供更高的採購彈性。