Routing Control Plane Model — Route table thực sự sống ở đâu
Why this matters in production
Hầu hết kỹ sư mang theo một mental model sai từ thế giới on-prem khi bước vào GCP: họ hình dung VPC có một (hoặc vài) "con router" trung tâm, route table là một bảng nằm trong con router đó, và packet phải "đi qua router" để được forward. Mental model này sai về bản chất, và nó dẫn tới những kết luận sai có hậu quả thật:
- Họ lo lắng về "router bottleneck" và thiết kế để "giảm tải cho router" — trong khi không tồn tại router nào để tải.
- Họ không hiểu vì sao một route mới
gcloud compute routes createlại không có hiệu lực tức thì trên mọi VM, mà có một độ trễ ngắn. - Họ không hiểu vì sao route table "giống nhau" trên mọi VM nhưng hành vi routing lại có thể khác nhau giữa các VM (vì applicable instances, tags, next-hop validity).
- Họ debug routing bằng cách "tìm con router để xem route table của nó" — một việc vô nghĩa trên GCP.
Để reason đúng về routing, scale, và failure trên GCP, bạn cần thay mental model "router trung tâm" bằng mental model đúng: VPC route table là một control-plane object phân tán, được biên dịch thành forwarding state và program vào host vSwitch (Andromeda) tại từng VM. Cả file này dành để xây dựng mental model đó cho chính xác.
Internal model — route table là control-plane object, không phải bảng vật lý
Hai mặt phẳng, hai loại "route table"
Bước đầu tiên là tách bạch hai khái niệm thường bị gộp làm một:
CONTROL PLANE DATA PLANE
───────────── ──────────
VPC route collection Per-VM forwarding state
(các Route resource bạn thấy qua API) (bảng forwarding đã biên dịch,
nằm trong host vSwitch Andromeda)
- Là tập các object có metadata: - Là cấu trúc dữ liệu tối ưu cho
destination, priority, next-hop, lookup ở wire speed
applicable tags, network - Khác nhau giữa các VM (vì tags,
- Bạn CRUD chúng qua Compute API applicability, next-hop validity)
- Thay đổi = eventual consistency - Được Andromeda program & update
- Global hoặc regional theo loại route liên tục từ control planeKhi bạn chạy gcloud compute routes list, bạn đang xem control-plane collection — danh sách các Route resource của VPC. Đây không phải bảng forwarding mà một VM cụ thể dùng để quyết định next-hop cho một packet. Bảng forwarding thực tế là kết quả của việc Andromeda lấy control-plane collection, lọc theo những route áp dụng cho VM đó (applicability), loại bỏ route có next-hop không hợp lệ, rồi biên dịch phần còn lại thành cấu trúc lookup hiệu năng cao đặt ngay tại host chứa VM.
Sự phân tách này là nền tảng kiến trúc của Andromeda — SDN stack của Google (Andromeda, NSDI '18). Control plane chịu trách nhiệm tính toán trạng thái mạng mong muốn; một hệ thống phân phối (thường gọi là "VM controller" / "hoverboard" trong kiến trúc Andromeda) chịu trách nhiệm đẩy trạng thái đó tới đúng các host; và datapath tại host thực thi forwarding mà không cần hỏi lại control plane cho từng packet.
Không có "con router", chỉ có host vSwitch
Đây là điểm phản trực giác lớn nhất với người đến từ on-prem. Trong một mạng vật lý, packet rời NIC của server, đi tới một switch, có thể tới một router, router tra route table của nó, rồi forward. Route table là tài sản của thiết bị router, và thiết bị đó là một điểm vật lý mà traffic phải đi qua.
Trên GCP, không có thiết bị router nào trong đường đi. Mỗi host vật lý chạy một phần mềm datapath (Andromeda vSwitch). Khi một VM gửi packet:
- Packet rời guest kernel của VM, vào virtual NIC.
- Andromeda vSwitch tại chính host đó nhận packet, tra forwarding state đã được program sẵn cho VM này.
- vSwitch xác định next-hop (một VM khác, một gateway, một tunnel...), đóng gói (encapsulate) packet, và đẩy thẳng qua Jupiter fabric tới host đích.
Không có hop nào tới một "con router trung tâm". Quyết định routing xảy ra tại host nguồn, dựa trên forwarding state đã được program từ trước. Đây là lý do căn bản vì sao:
- VPC có thể là global mà không có single point of failure. Không tồn tại router trung tâm để fail. Forwarding state được phân tán tới mọi host. Mất một host chỉ ảnh hưởng VM trên host đó.
- Throughput không bị giới hạn bởi một "router". Mỗi host forward độc lập; tổng throughput scale theo số host, không theo công suất một thiết bị.
- Route resolution là deterministic và cục bộ. Cùng một packet từ cùng một VM luôn được resolve giống nhau vì forwarding state của VM đó là cố định tại thời điểm đó — không phụ thuộc tải của một router dùng chung.
Mental model đúng: "Route table của VPC" là một bản thiết kế (blueprint) ở control plane. Andromeda biên dịch bản thiết kế đó thành một bản sao forwarding state cục bộ tại mỗi host, đã được cá nhân hóa cho từng VM. Packet không bao giờ "đi tìm route table"; route table (đã biên dịch) ở ngay cạnh nó.
Vòng đời của một thay đổi route
Hiểu vòng đời này giải thích vì sao thay đổi route không tức thời và vì sao failover có độ trễ:
t0 Bạn gọi API: tạo/sửa/xóa một Route, hoặc Cloud Router học route mới qua BGP
│
▼
t1 Control plane validate & cập nhật VPC route collection
(kiểm tra trùng lặp với subnet route, next-hop hợp lệ, quota...)
│
▼
t2 Control plane tính lại forwarding state mong muốn cho các host bị ảnh hưởng
(chỉ những host chứa VM mà route này áp dụng)
│
▼
t3 State được đẩy (program) xuống Andromeda tại các host đó
│
▼
t4 Datapath tại host bắt đầu dùng forwarding state mới
→ packet tiếp theo được forward theo route mớiKhoảng t0 → t4 thường là dưới một giây cho thay đổi tĩnh, và vài giây cho route động lan truyền (BGP learn → program → propagate). Điểm mấu chốt về mental model: thay đổi route là eventually consistent. Trong cửa sổ t0 → t4, các host khác nhau có thể tạm thời thấy state khác nhau. Đây không phải bug — đây là bản chất của một control plane phân tán program một data plane phân tán. Mọi thiết kế dựa trên routing để failover (BGP, ECMP withdraw) phải tính tới cửa sổ này; đừng giả định "BGP session down ⇒ packet đổi đường ngay lập tức".
State nằm ở đâu, ai sở hữu nó
Để gỡ bỏ hoàn toàn mental model "router trung tâm", hãy định vị rõ từng mẩu state:
| State | Sống ở đâu | Ai program | Tính nhất quán |
|---|---|---|---|
| Route resources (metadata) | Control plane của VPC (toàn cục) | API call / Cloud Router | Strongly consistent ở control plane |
| Forwarding state (đã biên dịch) | Andromeda vSwitch tại mỗi host | Hệ thống phân phối của Andromeda | Eventually consistent với control plane |
| BGP learned routes | Cloud Router (regional) trước khi program vào VPC | BGP session | Phụ thuộc BGP timer + propagation |
| Connection tracking (cho stateful firewall) | Andromeda tại host của VM | Datapath (theo flow) | Cục bộ theo từng VM |
Bảng này là tấm bản đồ để debug: khi routing "sai", câu hỏi đầu tiên không phải "router nào sai" mà là "tầng state nào chưa hội tụ" — control-plane collection đã đúng chưa (xem qua API), và forwarding state tại host đích đã được program chưa (suy ra từ độ trễ propagation và trạng thái BGP).
Scope của route: global vs regional — và vì sao nó quyết định kiến trúc
VPC là global, nhưng không phải mọi loại route đều có scope global. Đây là một trong những điểm tinh tế nhất và là nguồn gốc của hành vi "route biến mất giữa các region" mà Chương 3 chỉ đề cập thoáng qua. Ở đây ta mổ xẻ nó từ góc control plane.
Subnet routes: global scope
Mỗi subnet, dù là regional resource, sinh ra một subnet route có scope toàn VPC (global). Nghĩa là: một VM ở asia-southeast1 tự động có route tới dải primary của một subnet nằm ở us-central1, không cần cấu hình gì. Theo tài liệu routes, subnet route được tạo tự động cho mọi subnet và có độ ưu tiên cao nhất trong nhóm custom routes về mặt khớp đích (most-specific). Đây là điều khiến VPC "cảm giác như" một mạng phẳng global: mọi subnet thấy mọi subnet ở tầng routing (firewall là chuyện khác).
Control-plane implication: subnet route được program vào forwarding state của mọi host có VM trong VPC. Đó là lý do không có "biên giới region" ở tầng subnet routing.
Static routes: global scope (với một số ngoại lệ về next-hop)
Custom static route mặc định cũng có scope global trong VPC — áp dụng cho mọi instance (hoặc theo tag nếu bạn giới hạn). Một static route 0.0.0.0/0 → default-internet-gateway áp dụng cho VM ở mọi region. Static route với next-hop là một VM hay một internal passthrough Network Load Balancer có ràng buộc về region của next-hop, nhưng route resource vẫn được đánh giá trên toàn VPC.
Dynamic routes (BGP): scope phụ thuộc dynamic routing mode
Đây là nơi scope trở nên thú vị và là nguồn gốc của nhiều sự cố. Route học qua BGP bởi Cloud Router có scope phụ thuộc vào dynamic routing mode của VPC:
- Regional dynamic routing (mặc định): Route mà một Cloud Router ở region X học được chỉ được program vào forwarding state của các VM trong region X. Cloud Router cũng chỉ advertise các subnet route của region của nó ra on-prem. Đây là lý do route học ở
us-central1"biến mất" ởeurope-west1: nó chưa từng được program ngoàius-central1. - Global dynamic routing: Route học bởi bất kỳ Cloud Router nào được program vào mọi region, và mỗi Cloud Router advertise subnet route của tất cả region ra on-prem (với một inter-region cost cộng vào MED). File 05 đào sâu cơ chế này.
Control-plane implication, phát biểu chính xác: dynamic routing mode là một thuộc tính của VPC điều khiển phạm vi program của dynamic route — nó quyết định forwarding state của host ở region nào sẽ nhận dynamic route do Cloud Router ở region khác học được. Nó không thay đổi bản chất "Cloud Router là regional"; nó thay đổi việc route học được có vượt biên giới region khi program xuống datapath hay không.
Peering routes: kế thừa, có điều kiện
Route được trao đổi qua VPC peering (subnet route, và tùy chọn custom route) lại có quy tắc scope riêng và đứng thấp hơn route nội bộ trong thứ tự ưu tiên (xem file 02). Điểm cần nhớ về control plane: peering không "merge" hai route table; nó nhập (import) route từ VPC kia vào control-plane collection của VPC này với nhãn nguồn là peering, để bước resolution sau đó có thể ưu tiên route nội bộ hơn route peering.
Bài học kiến thức: "Scope của route" thực chất là câu hỏi "control plane program route này vào forwarding state của những host nào". Subnet/static route → mọi host trong VPC. Dynamic route → tùy dynamic routing mode. Peering route → các host của VPC nhập route, với độ ưu tiên thấp hơn. Mọi hành vi "route có/không xuất hiện ở một VM" đều quy về câu hỏi program-scope này.
Constraints, trade-offs & failure modes
Eventual consistency là ràng buộc nền tảng, không phải lỗi
Vì forwarding state được program bất đồng bộ, mọi cơ chế dựa trên thay đổi route để chuyển hướng traffic đều có một cửa sổ hội tụ. Hệ quả thực tế:
- Failover qua BGP withdraw không tức thời. Khi một BGP session down, route bị withdraw ở control plane, rồi forwarding state mới được program. Trong cửa sổ này, packet vẫn có thể được gửi theo đường cũ (blackhole) cho tới khi state hội tụ. Đây là lý do BFD (phát hiện lỗi nhanh) và thiết kế dư thừa quan trọng — xem file 04.
- Đừng dùng route flap như một cơ chế điều khiển tần suất cao. Mỗi thay đổi kéo theo một chu kỳ recompute + reprogram. Một control loop bên ngoài liên tục thêm/xóa route sẽ tạo ra trạng thái không ổn định và độ trễ hội tụ tích lũy.
Quota của control-plane collection là giới hạn cứng
Vì route là object ở control plane, chúng chịu quota. Mỗi VPC có giới hạn về số dynamic route, static route, và đặc biệt là số dynamic route prefix duy nhất mà Cloud Router học/program (mặc định ở mức hàng nghìn, có thể nâng qua support). Khi vượt quota:
- Cloud Router ngừng học thêm prefix mới → route từ on-prem không xuất hiện → "kết nối on-prem mất một phần dải".
- Triệu chứng đặc trưng: một số dải on-prem thông, một số không, không theo quy luật firewall.
Đây là failure mode rất hay bị chẩn đoán nhầm thành lỗi BGP hoặc firewall. Cách phòng tránh: route summarization ở phía on-prem (advertise 10.0.0.0/8 thay vì hàng nghìn /24), và alerting trên metric số prefix của Cloud Router. Best practices Cloud Router khuyến nghị thiết lập alerting policy để tránh chạm quota prefix.
Forwarding state cá nhân hóa → cùng route table, khác hành vi
Vì forwarding state được lọc theo applicability (tags, service account của next-hop, next-hop validity), hai VM trong cùng VPC có thể có forwarding state khác nhau dù control-plane collection giống hệt. Ví dụ: một static route giới hạn bằng tags: [proxy] chỉ được program vào host của VM có tag đó. Một kỹ sư so sánh gcloud compute routes list (giống nhau) rồi kết luận "routing phải giống nhau" sẽ bỏ lỡ điều này. Mental model đúng: route table bạn xem qua API là tập nguồn; forwarding state thực thi là tập đã lọc theo từng VM.
Anti-pattern: debug routing bằng cách "tìm con router"
Một anti-pattern phổ biến của kỹ sư mới chuyển từ on-prem: khi routing sai, họ tìm "thiết bị router của VPC" để xem/sửa route table của nó. Trên GCP việc này vô nghĩa và làm họ đi sai hướng hàng giờ.
- Vì sao nó xảy ra: hiểu lầm rằng route table là tài sản của một thiết bị nằm trên datapath (mental model on-prem).
- Hệ quả ở scale: thời gian debug bị lãng phí vào việc tìm thứ không tồn tại; trong sự cố, đội vận hành không biết kiểm tra tầng state nào.
- Cách tư duy đúng: routing trên GCP được debug bằng cách (1) đọc control-plane collection qua API (
gcloud compute routes list,gcloud compute routers get-status), (2) suy luận về program-scope (route này lẽ ra được program vào host của VM nào), và (3) dùng Connectivity Tests của Network Intelligence Center để mô phỏng đường đi packet theo đúng forwarding state đã biên dịch. Không có "con router" nào để đăng nhập.
GCP-native implementation guidance
Một vài lệnh phản ánh đúng mô hình control plane, hữu ích khi xác minh:
# Xem control-plane collection (tập nguồn) — KHÔNG phải forwarding state của một VM
gcloud compute routes list --filter="network=prod-vpc"
# Xem các "applicable routes" mà control plane tính cho một VM cụ thể
# (gần nhất với forwarding state đã biên dịch cho VM đó)
gcloud compute networks subnets list-effective-routes ... \
|| gcloud compute instances ... # tùy ngữ cảnh, dùng Connectivity Tests cho chính xác
# Trạng thái dynamic route đã được program từ Cloud Router (control plane → VPC)
gcloud compute routers get-status router-us-central1 \
--region=us-central1 \
--format="table(result.bestRoutes[].destRange, result.bestRoutes[].nextHopIp)"Cách kiểm chứng chính xác nhất forwarding state thực tế là Connectivity Tests (Network Intelligence Center): nó mô phỏng đường đi của một packet 5-tuple cụ thể qua đúng route resolution + firewall đã biên dịch, thay vì để bạn đoán từ danh sách route thô. Đây là công cụ phản ánh đúng "forwarding state đã cá nhân hóa", trong khi routes list chỉ cho bạn tập nguồn.
Tóm tắt mental model
- Route table của VPC là control-plane object phân tán, không phải bảng trong một thiết bị router. Không có router trung tâm trên datapath.
- Andromeda biên dịch control-plane collection thành forwarding state cục bộ tại mỗi host, cá nhân hóa theo từng VM (applicability, next-hop validity).
- Quyết định routing xảy ra tại host nguồn; đó là lý do VPC global mà không có SPOF và không có "router bottleneck".
- Thay đổi route là eventually consistent — có cửa sổ hội tụ; mọi failover dựa trên route phải tính tới nó.
- Scope của route = program-scope: subnet/static → toàn VPC; dynamic → tùy dynamic routing mode; peering → VPC nhập, ưu tiên thấp hơn.
Với mental model này làm nền, file tiếp theo mổ xẻ chính xác thuật toán mà forwarding state dùng để chọn một route khi nhiều route cùng khớp.
References
- VPC Routes Overview — phân loại route, subnet route scope, next-hop validity
- Andromeda: Google Cloud's Software-Defined Networking (USENIX NSDI '18) — kiến trúc control plane / datapath, cơ chế program forwarding state
- Cloud Router Overview — Cloud Router là control-plane, Andromeda forward packet
- VPC Network Overview — VPC global, subnet regional, dynamic routing mode
- Connectivity Tests — mô phỏng forwarding state thực tế