GCP Networking 基礎與 API Gateway 設計
這篇涵蓋兩個主題: 在 GCP 上手動建立 VPC、Subnet、Firewall Rules、Service Account, 以及 API Gateway 的設計概念與面試常見問題。
GCP Networking
VPC: Global vs Regional
GCP VPC 是 global 的, Azure VNet 是 regional 的。
|
|
GCP 的優勢是同一個 VPC 內, 不同 region 的 VM 可以走內網直通, 不需要 Peering。
Subnet 與 CIDR
Subnet 是 regional 的。建 Subnet 要指定 region 和 IP 範圍 (CIDR)。
|
|
/24 後面 8 bits 可變 = 2^8 = 256 個 IP (可用 254 個)。
| CIDR | Usable IPs | Use case |
|---|---|---|
| /8 | 16,777,214 | Large private network |
| /16 | 65,534 | Medium VPC |
| /24 | 254 | Typical subnet |
| /28 | 14 | Small subnet (GCP minimum) |
| /32 | 1 | Single IP (firewall rule) |
/0 = 所有 IP。0.0.0.0/0 就是「任意來源」。
|
|
Firewall Rules
GCP Firewall Rules 掛在 VPC 層, 不是 Subnet 層 (Azure NSG 可以掛在 Subnet 或 NIC)。
Priority 數字越小, 優先度越高。預設 1000, 最高 0, 最低 65535。GCP 有一條隱藏的 implied deny-all (priority 65535), 所有沒有 match 到任何 rule 的流量都會被擋。
|
|
|
|
Production 做法是 --source-ranges=YOUR_IP/32, 只允許自己的 IP。
Service Account vs Managed Identity
Service Account 是給程式或服務用的身分, 不是給人用的。
| GCP Service Account | Azure Managed Identity | |
|---|---|---|
| 建立方式 | 手動建立, 手動指派 | System-assigned 隨資源自動建立 |
| Credentials | 可下載 JSON key (但不建議) | 完全沒有 key, Azure 管 token lifecycle |
| 生命週期 | 獨立存在, 手動管理 | System-assigned 隨資源一起刪除 |
Azure 設計上就把 key 的路堵死了, 是更安全的預設值。GCP 的 SA key 下載太方便, 是常見的安全漏洞來源。
解法是 Workload Identity Federation (WIF): 讓 GitHub Actions 或 GKE Pod 用 OIDC token 換 GCP 權限, 整個流程不需要 SA key。
|
|
SA + WIF = 跟 Managed Identity 同等安全, 但需要主動設定。
|
|
API Gateway
定義
API Gateway 是所有請求的統一入口, 負責處理橫切關注點 (cross-cutting concerns), 讓後端服務只需要專注在業務邏輯。
| 在 Gateway 處理 | 後端服務就不用管 |
|---|---|
| TLS termination | 不用處理 HTTPS |
| Auth (JWT / API key) | 不用每個服務各自驗 token |
| Rate limiting | 不用自己擋暴力請求 |
| Caching | 不用每個服務自己做 cache |
| Routing | 統一管理 path → service 對應 |
SSL Termination
TLS handshake 有 CPU 開銷。讓 Gateway 處理 SSL, 後端和 Gateway 之間走 HTTP 內網通訊。
|
|
好處:
- 憑證只在 Gateway 管一份, 到期只更新一個地方
- 後端服務省去加解密的 CPU 消耗
Gateway 和後端在同一個 VPC 內, 內部 HTTP 通常可以接受。需要更嚴格的場景 (金融、醫療) 可以加 mTLS, 後端之間也加密。
Caching
讀多寫少、回應不常變動的 API 適合在 Gateway 層 cache。
|
|
個人化的回應 (GET /cart, GET /orders) 不適合 cache, 因為每個用戶的資料不同。
BFF Pattern
不同客戶端對 API 的需求差異越大, 用同一個 Gateway 服務所有客戶端就會出現各種妥協。BFF (Backend for Frontend) 的解法: 為不同類型的客戶端各自維護一個 Gateway。
|
|
Web BFF 可以做大量資料聚合, Mobile BFF 只回傳精簡欄位, Public BFF 做嚴格版本控制。後端微服務保持不變。
適合: 有多個差異明顯的客戶端, 且每個客戶端團隊有能力維護自己的 BFF。小型團隊或客戶端差異不大時, 一個統一 Gateway 就夠了。
GraphQL 是另一個解法: 客戶端自己決定要哪些欄位, 同一個 endpoint 服務所有客戶端。代價是 schema 設計複雜度和 N+1 query 問題。
架構與高可用
|
|
Gateway 是無狀態的, 路由規則存在設定檔或 DB, 任何 instance 都能處理任何請求, 水平擴展自然。
Rate limiting 是有狀態的: 計數器存在 Redis, 所有 instance 共享同一份數據。
|
|
沒有共享 Redis 的話, 用戶可以同時打三個 instance 各打 100 次, 繞過 100 次/分鐘的限制。
常見面試問題
Q: Is the Gateway a SPOF?
No. Deploy multiple instances behind a Load Balancer. Gateway is stateless — any instance can handle any request — so horizontal scaling is straightforward.
Q: How do you share rate limit state across instances?
Store rate limit counters in Redis. All Gateway instances read and write to the same Redis, so the limit is enforced globally regardless of which instance handles the request.
Q: What’s the difference between a Gateway and a Load Balancer?
LB distributes traffic at L4/L7. Gateway handles application-level concerns — auth, rate limiting, routing logic. LB sits in front of the Gateway for HA; Gateway sits in front of your services for business logic.
Consistent Hashing
多個 LB instance 如何在不共享狀態的情況下做路由決策?
Round Robin 需要計數器 (「我上次給哪台」), 多個 instance 各自維護計數器, 分流會不均衡。
Consistent Hashing 用確定性算法: 同一個輸入永遠得到同一個輸出, 不依賴任何外部狀態。
|
|
任何 LB instance 收到同一個 IP, 算出來的結果都一樣。不需要溝通, 不需要共享狀態。
| Algorithm | Needs shared state | Reason |
|---|---|---|
| Round Robin | Yes | requires counter |
| Least Connections | Yes | requires connection count per backend |
| Random | No | stateless by nature |
| Consistent Hashing | No | deterministic function, same input = same output |