Kiến Trúc Cloud NAT & Cơ Chế SNAT
Tại Sao Kiến Trúc Quan Trọng Với Production Engineer
Phần lớn sự cố liên quan đến Cloud NAT — từ port exhaustion đến latency bất ngờ đến behavior kỳ lạ khi scale — đều bắt nguồn từ một hiểu lầm cơ bản: người vận hành nghĩ Cloud NAT hoạt động như một proxy appliance hoặc một VM trung gian, trong khi thực tế nó là một distributed, datapath-level mechanism được triển khai trong lớp SDN của Google.
Hiểu lầm này dẫn đến:
- Capacity planning sai (nghĩ có thể "scale up" NAT gateway như scale VM)
- Không hiểu tại sao thay đổi NAT configuration có thể gây gián đoạn ngay lập tức
- Nhầm lẫn giữa "NAT bottleneck" và "port exhaustion" khi debug
File này xây dựng mental model chính xác về Cloud NAT từ tầng kiến trúc.
Internal Model: Cloud NAT Sống Ở Đâu
Vị Trí Trong Stack GCP
Cloud NAT không tồn tại như một resource VMs hay một thiết bị độc lập trong project. Thay vào đó, khi bạn tạo một Cloud NAT gateway, Google Cloud lập trình cấu hình NAT trực tiếp vào Andromeda — phần mềm SDN vận hành VPC network.
┌─────────────────────────────────────────────────────────┐
│ GCP Data Plane │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ VM / Pod │ │ Andromeda │ │ Internet │ │
│ │ │──▶│ (NAT logic │──▶│ │ │
│ │ 10.0.0.5 │ │ embedded) │ │ │ │
│ └─────────────┘ └──────────────┘ └─────────────┘ │
│ ▲ │
│ │ Programming via │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Cloud NAT Control Plane │ │
│ │ (Cloud Router + NAT Gateway configuration) │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘Đây là điểm quan trọng nhất: Cloud NAT là một tính năng của Andromeda, không phải một VM hay proxy. Khi packet rời VM, Andromeda thực hiện SNAT ngay tại điểm xuất phát (ở tầng hypervisor/NIC), trước khi packet rời physical host. Không có hop trung gian, không có VM proxy, không có bottleneck đơn điểm.
Andromeda SDN và Role Của Cloud NAT
Andromeda là phần mềm SDN của Google vận hành toàn bộ GCP networking. Mỗi physical host trong datacenter chạy một Andromeda datapath agent (được gọi là "hummingbird"). Agent này:
- Nhận tất cả packet từ VM trên host đó
- Apply routing, firewall rules, và NAT translation theo configuration được lập trình bởi control plane
- Forward packet ra network fabric (Jupiter spine-leaf)
Khi bạn cấu hình Cloud NAT gateway:
- Control plane (Cloud Router + NAT service) tính toán mapping: subnet nào được NAT, dùng IP nào, phân bổ port thế nào
- Configuration này được pushed xuống Andromeda agent trên từng host có VM thuộc subnet đó
- Từ thời điểm đó, mọi outbound packet từ VM sẽ được SNAT ngay tại host, không cần đi qua bất kỳ trung gian nào
Đây là lý do Cloud NAT không làm giảm network bandwidth: translation xảy ra in-line tại điểm xuất phát, không tạo ra bottleneck trung tâm. Toàn bộ bandwidth của VM vẫn được giữ nguyên sau khi Cloud NAT được bật.
Cloud NAT vs Appliance-Based NAT: Sự Khác Biệt Cơ Bản
| Chiều | Appliance-based NAT | Cloud NAT (Andromeda) |
|---|---|---|
| Điểm xử lý | VM/thiết bị trung gian | Andromeda agent tại nguồn |
| Single point of failure | Có | Không (mỗi host tự xử lý) |
| Bottleneck bandwidth | Có (throughput appliance) | Không (bandwidth VM giữ nguyên) |
| State management | Centralized connection table | Distributed per-host |
| Horizontal scale | Scale appliance hoặc clustering | Tự động theo số host |
Trong môi trường on-prem hoặc AWS NAT Gateway, NAT thường là một điểm tập trung. Traffic từ nhiều VM phải đi qua một thiết bị vật lý hoặc VM proxy. Cloud NAT hoàn toàn khác: mỗi physical host xử lý NAT cho tất cả VM của nó, không có traffic nào phải đi qua "gateway" trung tâm.
Cơ Chế SNAT: Flow Chi Tiết
SNAT Là Gì Trong Context Cloud NAT
Source NAT (SNAT) là quá trình thay thế source IP và source port của packet khi nó rời khỏi mạng nội bộ để ra internet. Cloud NAT thực hiện SNAT cho outbound traffic và DNAT (Destination NAT) ngầm cho return traffic của cùng phiên.
Packet Flow Outbound (VM → Internet)
VM (10.0.0.5:52340) → Internet (8.8.8.8:53)
Bước 1: VM gửi packet
└─ Source: 10.0.0.5:52340
└─ Destination: 8.8.8.8:53
└─ Protocol: UDP
Bước 2: Andromeda agent bắt packet (tại host hypervisor)
└─ Kiểm tra: VM này có NAT policy không? → Có
└─ Tìm mapping trong connection tracking table
└─ Nếu chưa có entry: phân bổ NAT IP + port từ pool
Ví dụ: phân bổ 34.100.200.50:44001
└─ Ghi vào connection tracking table:
(10.0.0.5:52340, 8.8.8.8:53/UDP) → (34.100.200.50:44001, 8.8.8.8:53/UDP)
Bước 3: Rewrite packet header
└─ Source thay đổi: 34.100.200.50:44001
└─ Destination giữ nguyên: 8.8.8.8:53
└─ Checksum được recalculate
Bước 4: Packet đi ra internet với source là NAT IP/portReturn Traffic (Internet → VM)
Internet response: 8.8.8.8:53 → 34.100.200.50:44001
Bước 1: Packet đến GCP edge với destination 34.100.200.50 (external IP của Cloud NAT)
└─ Andromeda định tuyến đến đúng host dựa trên NAT IP ownership
Bước 2: Andromeda agent tại host tra connection tracking table:
└─ (34.100.200.50:44001, 8.8.8.8:53/UDP) → (10.0.0.5:52340, 8.8.8.8:53/UDP)
└─ Tìm thấy entry
Bước 3: DNAT (reverse SNAT): rewrite destination
└─ Destination thay đổi: 10.0.0.5:52340
└─ Source giữ nguyên: 8.8.8.8:53
Bước 4: Packet được deliver đến VMConnection Tracking Table
Connection tracking table là trái tim của NAT operation. Mỗi Andromeda agent duy trì một bảng ánh xạ hai chiều:
[Internal tuple] → [External tuple]
(src_ip, src_port, dst_ip, dst_port, proto) ←→ (nat_ip, nat_port, dst_ip, dst_port, proto)Bảng này cần được duy trì miễn là connection còn active. Khi connection đóng hoặc timeout, entry được xóa và NAT port được trả về pool để tái sử dụng. Đây là điểm then chốt: port exhaustion xảy ra khi connection tracking table đầy trước khi timeout, không phải khi số kết nối đồng thời vượt quá một ngưỡng ngẫu nhiên nào đó.
Tại Sao Cloud NAT Chỉ Hỗ Trợ Outbound
Cloud NAT không cho phép unsolicited inbound connections — kết nối từ internet đến VM mà không có session được initiate từ phía VM trước. Đây là thiết kế có chủ đích:
Connection tracking requirement: DNAT cho return traffic chỉ hoạt động nếu có entry tương ứng trong connection tracking table từ outbound packet trước đó. Nếu không có entry, Andromeda không biết packet inbound này thuộc về VM nào.
Security model: Đây là behavior mong muốn — VM không cần external IP vẫn không thể bị tiếp cận từ internet. Đây là nền tảng của GKE private cluster security model.
ICMP Echo (ping) nuance: Outbound ping hoạt động bình thường (VM initiate, Cloud NAT track, reply được delivered). Inbound ping từ internet sẽ bị drop vì không có tracking entry.
Endpoint-Independent Mapping (EIM)
Cơ Chế
Endpoint-Independent Mapping (EIM) là một tính năng tùy chọn của Public NAT, mô tả trong RFC 5128 Section 2.3. Với EIM, Cloud NAT tạo mapping many-to-one giữa internal source và NAT source:
Không có EIM (mặc định — endpoint-dependent):
VM 10.0.0.5:10001 → Dest A (203.0.113.1:80) → NAT 34.x.x.x:30001
VM 10.0.0.5:10001 → Dest B (203.0.113.2:443) → NAT 34.x.x.x:30002 ← port khác nhau!
Với EIM bật:
VM 10.0.0.5:10001 → Dest A (203.0.113.1:80) → NAT 34.x.x.x:30001
VM 10.0.0.5:10001 → Dest B (203.0.113.2:443) → NAT 34.x.x.x:30001 ← cùng port!Với EIM, cùng một internal source tuple sẽ luôn ánh xạ đến cùng một NAT tuple, bất kể destination là gì. Điều này hữu ích cho các ứng dụng peer-to-peer (WebRTC, STUN/TURN) cần biết external address của mình trước để negotiate.
EIM Conflict Và Trade-Off
EIM đi kèm với một ràng buộc quan trọng: nếu hai VM khác nhau có cùng source port và ánh xạ đến cùng một NAT port, conflict xảy ra.
Scenario gây conflict:
VM A (10.0.0.5:10001) → đã ánh xạ đến NAT 34.x.x.x:30001
VM B (10.0.0.6:10001) → cũng cần ánh xạ, nhưng NAT 34.x.x.x:30001 đã bị VM A chiếm
Kết quả: packet của VM B bị drop với lý do ENDPOINT_INDEPENDENCE_CONFLICTTrong môi trường có nhiều VM đồng thời dùng chung source ports (ví dụ: GKE clusters với nhiều pod share cùng node's IP), tần suất conflict này có thể cao. Vì vậy:
- EIM bật: cần thiết cho P2P apps, nhưng tăng risk ENDPOINT_INDEPENDENCE_CONFLICT drop
- EIM tắt (mặc định): endpoint-dependent mapping, không có conflict, phù hợp cho hầu hết workloads
- EIM không tương thích với Dynamic Port Allocation
Theo Google Cloud documentation: Endpoint-Independent Mapping chỉ khả dụng cho Public NAT với static port allocation. Private NAT luôn dùng endpoint-dependent mapping.
Khi Nào Cần EIM
EIM cần thiết khi application phải hole-punching qua NAT — tức là cần biết external IP:port của mình để gửi cho peer khác, để peer đó có thể initiate connection về phía mình. Ví dụ điển hình: WebRTC signaling, game servers dùng UDP NAT traversal.
Với server-side applications thông thường (HTTP/HTTPS, gRPC, database connections) — các loại workload phổ biến nhất trên GCP — EIM không cần thiết và thực tế gây hại nhiều hơn lợi.
Distributed State: Connection Tracking Tại Scale
Thách Thức Của Distributed NAT
Vì Cloud NAT không có central gateway, connection tracking state phải được quản lý distributed. Mỗi Andromeda agent chỉ biết về các connection của VM trên host của nó. Điều này làm nảy sinh câu hỏi: nếu VM migrate (live migration), connection tracking state đi theo không?
Câu trả lời từ Google: live migration bảo tồn connection tracking state. Khi VM được migrated sang host mới, Andromeda state cũng được transferred. Đây là lý do tại sao maintenance events (live migration) thường không gây connection drop cho ongoing TCP connections qua Cloud NAT.
NAT IP Ownership và Routing
Mỗi external IP được gán cho Cloud NAT gateway cần được advertised để internet biết traffic về IP đó phải đến GCP. Google quảng bá các IP này qua BGP từ các edge PoP. Khi return traffic đến GCP edge:
- Traffic được route đến region chứa Cloud NAT gateway
- Andromeda trong region đó biết IP nào thuộc về gateway nào
- Andromeda forward packet đến đúng host dựa trên connection tracking entry
Điều này giải thích tại sao Cloud NAT là regional resource: connection tracking state và IP ownership đều gắn với một region cụ thể. Một VM ở us-central1-a không thể dùng Cloud NAT gateway ở us-east1.
Tác Động Của Configuration Changes
Vì configuration Cloud NAT được programmed xuống từng Andromeda agent, thay đổi configuration (ví dụ: thêm NAT IP, thay đổi ports-per-VM) có tác dụng gần như ngay lập tức — nhưng không phải instantaneous. Có một propagation delay nhỏ (thường dưới 60 giây) trong khi configuration mới được pushed xuống tất cả hosts trong region.
Quan trọng hơn: không phải mọi config change đều seamless. Cụ thể:
- Thêm NAT IP: an toàn, mở rộng pool không gián đoạn
- Xóa NAT IP: gây gián đoạn cho các connection đang dùng IP đó — connection tracking entry bị mất
- Thay đổi ports-per-VM (static): có thể gây reallocation và drop connections
Constraints & Trade-offs
"Proxyless" Không Có Nghĩa Là "Free"
Mặc dù Cloud NAT không thêm network hop, nó vẫn có overhead nhất định:
- CPU overhead nhỏ trên Andromeda agent để rewrite header và maintain connection tracking
- Memory overhead để lưu connection tracking table — tỷ lệ với số concurrent connections
- NAT IP pool cần được managed: thêm IP có thể mất vài phút để BGP propagate
Regional Constraint
Cloud NAT là regional. Một gateway chỉ phục vụ VMs trong cùng region. Nếu bạn có VMs ở nhiều region, bạn cần Cloud NAT gateway riêng cho mỗi region. Đây không phải hạn chế về performance mà là do connection tracking state không thể chia sẻ cross-region trong thiết kế distributed.
Không Hỗ Trợ Inbound Connections
Cloud NAT chỉ hỗ trợ outbound-initiated connections. Nếu workload cần inbound từ internet, cần external IP hoặc Load Balancer — Cloud NAT không thể là giải pháp.
Giới Hạn Protocol
Cloud NAT hỗ trợ TCP, UDP, và ICMP (cho outbound echo requests). Các protocol khác (như ESP/IPsec, GRE) không được NAT qua Cloud NAT.
Anti-Pattern: Nhầm Lẫn "Scale Up" Cloud NAT
Một anti-pattern phổ biến là khi gặp vấn đề Cloud NAT, team cố gắng "scale up" gateway — nhưng Cloud NAT gateway không có instance size. Bạn không thể tăng throughput bằng cách chọn tier cao hơn vì Cloud NAT không phải VM.
Các đòn bẩy thật sự để scale Cloud NAT:
- Thêm NAT IP address: tăng tổng port pool
- Bật Dynamic Port Allocation: phân bổ linh hoạt hơn
- Tune timeouts: giảm TIME_WAIT, giải phóng port nhanh hơn
- Thiết kế lại application: connection pooling, giảm số concurrent connections