Understanding Data Center Fabrics - Part 9: Other Considerations
Mục lục
- 1. Single-home hay dual-home server vào fabric?
- 2. Dual-home: Layer 2 M-LAG, IP dual-homing với EVPN, hay routed dual-home?
- 3. Vì sao không nên chạy underlay control plane ra tận server?
- 4. Lựa chọn transport cho underlay: IPv4, IPv6, dual-stack, MPLS, SRv6
- 5. Thiết kế layer tổng thể: underlay autonomic + overlay BGP EVPN
- 6. External connections: vì sao spine không phải là core
- 7. Grey failure: khi luật số lớn "lật ngược" con số MTBF đẹp đẽ
1. Single-home hay dual-home server vào fabric?
Bản năng tự nhiên của hầu hết mọi người là dual-home, đặc biệt là dual-home ở layer 2. Tuy nhiên, khi chạy microservices — nghĩa là ứng dụng được thiết kế để chịu được việc mất kết nối/hỏng một server bất kỳ, không server nào là "pet", tất cả đều là "cattle" — thì single-home hoàn toàn chấp nhận được. Đây chính là cách hầu hết các hyperscaler đang vận hành. Cách làm này ít phổ biến hơn trong các dịch vụ dựa trên virtual machine hoặc bare-metal.
Nếu chọn single-home, có vài điều cần lưu ý:
- ISSU (In-Service Software Upgrade) rất khó thực hiện trong tình huống này.
- Ứng dụng phải có khả năng chuyển đổi (switch/move) từ server này sang server khác rất nhanh.
- Graceful restart cũng là một vấn đề cần giải quyết. Trong một số kiến trúc, routing stack nằm trên RIB, và bên dưới RIB là FIB (forwarding table) — FIB có thể ở software, hardware, hoặc cả hai. Một số implementation của chính RIB (ví dụ Zebra) được chỉnh sửa để hỗ trợ graceful restart, cho phép restart routing service mà không làm mất toàn bộ route.
Vì sao ba điều trên lại quan trọng đến vậy nếu chỉ có một đường lên fabric? Vì với dual-home, khi switch A cần nâng cấp phần mềm, switch B vẫn còn đó gánh toàn bộ traffic — ISSU gần như "miễn phí" theo nghĩa server không bao giờ cảm nhận được gián đoạn. Với single-home, không còn switch B để gánh hộ. Muốn nâng cấp switch mà không đánh sập server phía dưới, chỉ còn hai lựa chọn: hoặc chấp nhận downtime ngắn và để ứng dụng tự phục hồi (đây là lý do ứng dụng phải "chuyển đổi rất nhanh" — tính bằng giây, không phải phút), hoặc router/switch đó phải tự sống sót qua một lần restart phần mềm mà không đánh rơi gói tin nào — chính là graceful restart. Cơ chế graceful restart hoạt động dựa trên việc tách rời hai thứ vốn thường đi cùng nhau: control plane (phần chạy giao thức định tuyến, tính toán route) và data plane/FIB (phần forward gói tin thực tế). Khi daemon định tuyến restart, FIB đã được lập trình từ trước vẫn tiếp tục forward gói tin đúng như cũ trong một khoảng thời gian ân hạn (grace period) — router láng giềng được báo trước qua capability negotiation (ví dụ BGP Graceful Restart Capability) rằng "tôi sắp restart, đừng vội rút session xuống", nhờ vậy traffic đi qua vẫn trôi chảy dù phía trong router đang restart lại toàn bộ RIB.
💡 Hình dung như thế này: một cửa hàng tiện lợi mở 24/7 với hai nhân viên thu ngân (dual-home) có thể cho một người nghỉ giải lao bảo trì máy tính tiền bất cứ lúc nào — khách vẫn được phục vụ bởi người còn lại. Cửa hàng chỉ có một nhân viên duy nhất (single-home) thì không còn lựa chọn "nghỉ giải lao" nữa — hoặc phải đóng cửa vài phút (chấp nhận gián đoạn, khách tự quay lại sau), hoặc nhân viên đó phải học được cách vừa sửa máy tính tiền vừa tiếp tục tính tiền cho khách cùng lúc (graceful restart).
# FRRouting (Zebra) — kiểm tra trạng thái graceful restart cho BGP
show bgp neighbor 10.0.0.1 | include Graceful Restart
show ip route summary # xác nhận FIB vẫn giữ route trong lúc daemon restart
# Cisco IOS-XR — bật Non-Stop Forwarding (NSF)/graceful restart cho IS-IS
router isis UNDERLAY
nsf cisco
2. Dual-home: Layer 2 M-LAG, IP dual-homing với EVPN, hay routed dual-home?
Dual-home là giải pháp phổ biến nhất mà hầu hết mọi người sẽ gặp. Cách nghĩ đầu tiên thường là: dual-home tới hai switch vật lý khác nhau, dùng M-LAG (multi-chassis LAG) hoặc giải pháp LAG tương tự để hai switch đó "trông như một" từ góc nhìn của server (nhiều NIC trên server, nối tới hai switch vật lý riêng biệt).
Quan điểm cá nhân trong bài: không ủng hộ M-LAG layer 2 / spanning tree layer 2 trong underlay, vì mục tiêu là xây dựng một hệ thống phân layer rõ ràng trong data center, tạo ra các module lớn hơn, phẳng hơn, kiểm soát độ phức tạp theo cách khác thay vì chỉ dựa vào kiến trúc phân cấp truyền thống.
Các lựa chọn thay thế:
- IP dual-homing ở layer 3: dual-home bằng IP, sau đó dùng một overlay protocol (ví dụ EVPN) để làm cho việc dual-homing ở layer 2 vẫn hoạt động được phía trên.
- Routed dual-home: dual-home hoàn toàn dựa trên routing.
Ba khái niệm này rất dễ lẫn vào nhau nếu chỉ đọc mô tả bằng chữ, vì cả ba đều bắt đầu bằng cùng một hình ảnh — server có hai NIC, nối tới hai switch. Điểm khác biệt nằm ở chỗ nào tạo ra "ảo giác layer 2" (illusion rằng hai switch vật lý là một thiết bị duy nhất): M-LAG tạo ảo giác đó ngay ở underlay bằng một peer-link vật lý giữa hai switch; IP dual-homing + EVPN tạo ảo giác đó ở tầng overlay phía trên, còn underlay bên dưới vẫn thuần túy là routing; routed dual-home thì không tạo ảo giác layer 2 nào cả — server thấy đúng hai đường L3 độc lập và tự chịu trách nhiệm chọn đường. Hình dưới đây đặt ba mô hình cạnh nhau để dễ so sánh.
Cơ chế M-LAG: ảo giác được tạo ngay tại underlay
M-LAG (và các biến thể theo tên vendor như MC-LAG, vPC của Cisco, MLAG của Arista/Cumulus) hoạt động dựa trên một peer-link vật lý riêng giữa hai switch, dùng để đồng bộ MAC table, ARP table, và trạng thái LACP giữa hai bên. Khi server gửi một gói tin lên switch A, nếu bảng MAC của switch A chưa học được địa chỉ đích, nó có thể phải hỏi hoặc đồng bộ qua peer-link để switch B "biết" trạng thái tương tự — hai switch phải liên tục nói chuyện với nhau để duy trì ảo giác "một switch logic duy nhất". Đây chính là lý do M-LAG bị coi là rủi ro ở tầng underlay: peer-link trở thành một single point of coordination — nếu peer-link đứt trong khi cả hai switch vẫn sống (split-brain), cả hai có thể cùng nghĩ mình là active, dẫn tới loop hoặc forward sai, đúng loại lỗi mà thiết kế Clos/fabric vốn muốn tránh bằng cách loại bỏ toàn bộ layer 2 spanning-tree domain.
Cơ chế IP dual-homing + EVPN: ảo giác được đẩy lên overlay
Với IP dual-homing, hai switch A và B không cần biết gì về nhau ở tầng vật lý — không peer-link, không đồng bộ trạng thái trực tiếp. Ảo giác "server chỉ nối vào một thiết bị logic" được tạo ra hoàn toàn ở tầng overlay, thông qua giao thức BGP EVPN (chuẩn hóa trong RFC 7432). Cơ chế cụ thể: một Ethernet Segment (nhóm các link vật lý cùng nối một server/CE vào nhiều switch/PE) được gán một Ethernet Segment Identifier (ESI) chung. Hai switch A và B cùng quảng bá một EVPN Type-4 route (Ethernet Segment Route) mang đúng ESI đó — đây là cách hai switch "bắt tay" nhau qua BGP thay vì qua cáp vật lý, để cùng thống nhất ai là DF (Designated Forwarder) cho từng VLAN. Song song đó, EVPN Type-1 route (Ethernet Auto-Discovery Route) cho phép router khác trong fabric biết rằng cùng một MAC/host có thể đến qua cả hai switch, từ đó thực hiện "aliasing" — load-balance traffic tới cả hai đường mà không cần switch A và B có bất kỳ liên kết vật lý trực tiếp nào. Nói cách khác, BGP đã thay thế hoàn toàn vai trò của peer-link.
Nếu dual-homing muốn dừng lại ở layer 3 thuần túy (không cần "giả lập" một MAC/host layer 2 dùng chung), EVPN còn có route type khác dành riêng cho việc quảng bá prefix IP — Route Type 5, chuẩn hóa trong RFC 9136. Route Type 5 tách hẳn MAC ra khỏi IP prefix, phù hợp khi cần dual-home một subnet (không phải một host layer 2 cụ thể) tới nhiều switch — đây chính là cầu nối khái niệm dẫn tới lựa chọn thứ ba.
Cơ chế routed dual-home: không còn ảo giác nào cả
Routed dual-home bỏ hẳn khái niệm "MAC dùng chung" hay "ESI" — server có hai địa chỉ IP (hoặc dùng loopback + ECMP theo kiểu BGP unnumbered), mỗi NIC là một next-hop layer 3 độc lập, và chính server (qua BGP hoặc một cơ chế định tuyến chạy trên host) tự quyết định chọn đường nào. Đây là mô hình đơn giản nhất về mặt control plane — không ESI, không DF election, không aliasing — nhưng đổi lại yêu cầu ứng dụng/hệ điều hành trên server phải "hiểu" định tuyến layer 3, thay vì chỉ cắm NIC vào và trông chờ layer 2 tự lo phần còn lại.
# Cisco NX-OS — kiểm tra trạng thái M-LAG (vPC) giữa hai switch qua peer-link
show vpc brief
# Output minh họa
Legend:
(*) - local vPC is down, forwarding via vPC peer-link
vPC domain id : 10
Peer status : peer adjacency formed ok
vPC keep-alive status : peer is alive
Configuration consistency status : success
Per-vlan consistency status : success
Type-2 consistency status : success
vPC role : primary
Number of vPCs configured : 2
Peer Gateway : Enabled
Dual-active excluded VLANs : -
Graceful Consistency Check : Enabled
Auto-recovery status : Enabled
(Output minh họa — cấu trúc và tên field đúng theo lệnh thật, số liệu cụ thể chỉ mang tính ví dụ.)
Chú ý hai field quan trọng nhất khi soát lỗi M-LAG: Peer status (nếu không phải "peer adjacency formed ok", hai switch có thể đang không thống nhất về vai trò active/standby) và vPC keep-alive status (đường keepalive riêng, thường đi qua một link/route ngoài peer-link, dùng để phát hiện split-brain khi peer-link chết hẳn — nếu keep-alive cũng chết trong khi peer-link chết, đây chính là kịch bản split-brain nguy hiểm nhất của mọi kiến trúc M-LAG).
Với routed dual-home, câu hỏi đặt ra là: nên chạy overlay, underlay, hay cả controller/orchestrator ra tới các thiết bị đó? Có thể có tới ba control plane khác nhau (orchestrator, overlay, underlay) — vậy khi nói "chạy control plane theo kiểu routed ra server", thực chất đang chạy cái nào?
3. Vì sao không nên chạy underlay control plane ra tận server?
Quan điểm trong bài: không bao giờ nên chạy underlay control plane ra tận các server. Lý do:
- Không có wide fan-out ở đó — server thường chỉ có hai kết nối (dual-home), nên không có nhiều đường để ECMP phát huy tác dụng — chỉ đơn giản là chọn đường này hoặc đường kia, không hơn.
- Route ra server thường chỉ là default route (
::/0hoặc tương đương) — nghĩa là gần như không có đủ thông tin để đưa ra quyết định ECMP có ý nghĩa. - Việc chọn một đường cụ thể (thay vì đường khác) là công việc của traffic steering — và traffic steering không nên nằm trong underlay. Underlay chỉ nên cung cấp thông tin để traffic steering có thể diễn ra; quyết định cách xây dựng label stack hay cách định tuyến traffic nên thuộc về lớp orchestration/overlay, không phải underlay. Đưa việc này vào underlay sẽ làm tăng độ phức tạp không cần thiết cho lớp vốn cần được giữ đơn giản. Ví dụ cụ thể cho dễ hình dung: giả sử một request của ứng dụng cần đi theo đường có độ trễ thấp nhất (thay vì đường có băng thông rảnh nhiều nhất) — quyết định "đi đường nào" đó nên do overlay/orchestrator đưa ra (ví dụ qua một SR policy gắn sẵn label stack tương ứng với đường mong muốn), sau đó underlay chỉ đơn thuần forward gói tin theo đúng label đã được gắn sẵn. Underlay không nên tự "biết" khái niệm request nào cần latency thấp, request nào cần băng thông cao — đó là logic của tầng trên, không phải việc của lớp chuyển tiếp gói thuần túy bên dưới.
- Chạy underlay ra tận server sẽ phá vỡ sự tách biệt sạch giữa underlay và overlay như hai failure domain riêng biệt. Khi xây các domain phẳng, lớn, không aggregate nhiều, việc kiểm soát blast radius/failure domain cần dựa vào chính sự tách biệt rõ ràng giữa underlay và overlay — đây cũng là một dạng abstraction trong mạng.
Vì sao "wide fan-out" (điểm 1) lại quan trọng đến mức quyết định luôn việc có nên chạy underlay ra server hay không? Vì ECMP không chọn đường ngẫu nhiên — nó băm (hash) một số trường cố định trong header gói tin (thường là 5-tuple: source IP, destination IP, source port, destination port, protocol) thành một chỉ số, rồi dùng chỉ số đó để chọn 1 trong N next-hop khả dụng. Thuật toán này chỉ thực sự phát huy tác dụng cân bằng tải khi N đủ lớn và có đủ route cụ thể để chọn giữa nhiều đường — đúng như những gì các tầng leaf-spine-fab phía trên cung cấp (hàng chục đến hàng trăm next-hop). Ở cạnh server, N chỉ còn 2 (đúng bằng số NIC dual-home), và bản thân route học được cũng chỉ là default route — nghĩa là bài toán "chọn đường" đã suy biến từ ECMP có ý nghĩa thống kê xuống chỉ còn phép chọn nhị phân giữa hai lựa chọn, không còn gì để một control plane phức tạp như IS-IS hay RIFT phát huy giá trị.
💡 Hình dung như thế này: ECMP giống một nhân viên điều phối đứng ở ngã tư có 32 làn đường để chia đều dòng xe — càng nhiều làn, việc chia tải càng mượt và càng khó bị một làn nào đó quá tải. Đặt đúng nhân viên điều phối đó ra đứng trước cổng nhà riêng (server) — nơi chỉ có đúng hai lối ra vào — thì cả bộ kỹ năng "chia đều 32 làn" của anh ta trở nên vô dụng, việc anh ta thực sự cần làm lúc này chỉ là "đi cửa trước hay cửa sau", một quyết định đơn giản không đáng để triệu tập nguyên một hệ thống điều phối giao thông phức tạp.
Đáng chú ý: RIFT (chuẩn hóa thành RFC 9692, công bố tháng 4/2025) được thiết kế với đúng triết lý ở điểm 2 — theo mặc định, RIFT chỉ quảng bá một default route duy nhất theo hướng southbound (từ spine xuống leaf), chứ không đẩy toàn bộ bảng định tuyến chi tiết xuống các tầng dưới. Một phần động lực thiết kế RIFT là để có thể mở rộng an toàn xuống tận các thiết bị ở biên (kể cả bare-metal server) mà không đánh đổi lấy chi phí cấu hình hay rủi ro flooding state — nhưng như bốn lý do nêu trên, việc chạy được về mặt kỹ thuật không đồng nghĩa với việc nên làm, trừ các trường hợp ngoại lệ single-application/single-use đã nêu ở mục sau.
4. Lựa chọn transport cho underlay: IPv4, IPv6, dual-stack, MPLS, SRv6
Có nhiều lựa chọn transport cho underlay: IPv4, IPv6, dual-stack, MPLS, SRv6, SR-MPLS. Hầu như không có câu trả lời "đúng tuyệt đối" cho bất kỳ tình huống nào — mỗi lựa chọn có đánh đổi riêng. Vì vậy, cách đọc phần dưới đây không phải là tìm ra "lựa chọn tốt nhất", mà là đối chiếu với tình huống thực tế của bạn: nếu đã chạy overlay và không có ràng buộc đặc biệt gì về địa chỉ, hãy đọc phần IPv4/IPv6/dual-stack để biết vì sao thường không cần dual-stack; nếu core hiện tại đã chạy MPLS sẵn, đọc phần MPLS; nếu đang xây một fabric single-application không cần overlay, đọc phần ngoại lệ ngay dưới đây trước:
- IPv4: đơn giản, không cần chạy dual-stack. Nếu đã có overlay, overlay có thể mang cả v4, v6, và Ethernet/layer 2 (qua VXLAN chạy trên nền v4).
- Ngoại lệ đáng chú ý: có những mạng single-application/single-use (ví dụ xây riêng một data center fabric chỉ để chạy Hadoop) — trong trường hợp này có thể không cần overlay, không cần các yêu cầu segmentation/layer-2-overlay, nên việc chạy underlay protocol ra tận biên mạng lại hợp lý.
- IPv6: có thể chạy single-stack tương tự IPv4, dùng VXLAN để mang v4/Ethernet trên nền v6. Nhờ dùng link-local, có thể xây fabric mà không cần địa chỉ IP theo nghĩa truyền thống ở nhiều nơi — tuy vậy, hầu hết implementation vẫn yêu cầu một địa chỉ IPv4 cho loopback address làm router ID, nên vẫn phải quản lý một phần địa chỉ v4.
- Dual-stack: nếu đã chạy overlay (overlay tự hỗ trợ cả v4, v6, Ethernet qua VXLAN/MPLS), không rõ lý do gì để chạy dual-stack ở underlay — chỉ tạo thêm cấu hình phức tạp không cần thiết. Ngoại lệ: nếu có những bare-metal server chỉ nói v6 và những server khác chỉ nói v4, và cần overlay control plane (BGP EVPN chẳng hạn) chạy ra tận các server đó — trong tình huống đó dual-stack có thể hợp lý, nhưng cần cân nhắc kỹ độ phức tạp phát sinh.
- MPLS: có thể chạy MPLS trong underlay — nếu core đã chạy MPLS sẵn, việc mở rộng vào data center fabric có thể không tăng thêm nhiều độ phức tạp và có thể mang lại một số khả năng thú vị mà cách khác không có được.
- SRv6 / SR-MPLS: cũng là các lựa chọn khả thi, cả hai đều nằm trong kiến trúc Segment Routing chuẩn hóa ở RFC 8402. Từng có một đề xuất bổ sung tên SRm6 (Segment Routing Mapped to IPv6) với mục tiêu rút gọn SID xuống 16–32 bit thay vì 128 bit đầy đủ của SRv6, nhưng bản draft này đã hết hạn từ năm 2021, chưa từng được một working group nào của IETF nhận nuôi, nên tính tới thời điểm hiện tại nên xem đây là một hướng nghiên cứu đã dừng lại chứ không phải một lựa chọn transport đang tích cực phát triển.
💡 Hình dung như thế này: chọn transport cho underlay giống chọn loại bao bì để đóng gói hàng gửi đi — bao bì càng đơn giản (IPv4, chỉ một lớp giấy gói) thì nhẹ, rẻ, dễ xử lý ở mọi trạm trung chuyển, nhưng không ghi được chỉ dẫn "hàng dễ vỡ, đi đường ưu tiên" lên vỏ ngoài. Bao bì phức tạp hơn (SR-MPLS, SRv6) cho phép dán thêm nhãn chỉ dẫn đường đi chi tiết ngay trên vỏ hộp — nhưng vỏ hộp to hơn, tốn thêm không gian, và trạm trung chuyển nào cũng phải biết đọc đúng loại nhãn đó mới xử lý được.
Vì sao header overhead lại là chuyện đáng cân nhắc, không chỉ là con số kỹ thuật suông?
Underlay không đứng một mình — phần lớn thiết kế trong loạt bài này giả định overlay (VXLAN, MPLS L3VPN, hay SRv6 policy) đã đóng gói (encapsulate) traffic gốc của ứng dụng rồi mới đưa xuống underlay để forward tiếp. Mỗi lớp đóng gói cộng dồn thêm byte vào đầu gói tin, và tổng số byte đó phải nằm gọn trong MTU của toàn tuyến đường — nếu vượt quá, gói tin bị phân mảnh (fragmentation) hoặc bị drop nếu cờ "don't fragment" được bật, cả hai đều là nguồn gốc phổ biến của grey failure khó phát hiện (xem thêm mục 7). IPv4 thuần chỉ cộng thêm 20 byte header, gần như không đáng kể; IPv6 gấp đôi lên 40 byte; MPLS chỉ thêm 4 byte cho mỗi label trong stack — đây là lý do nhiều mạng lõi (core) vốn đã chạy MPLS từ lâu trước khi khái niệm data center fabric xuất hiện, vì overhead của nó gần như miễn phí so với những gì nó đổi lại (traffic engineering qua RSVP-TE hoặc Segment Routing).
SR-MPLS và SRv6: cùng một tư tưởng, khác cách trả giá cho khả năng lập trình đường đi
Cả hai đều dựa trên cùng một ý tưởng cốt lõi của Segment Routing: mã hoá toàn bộ đường đi mong muốn thành một danh sách segment gắn ngay trên gói tin (source routing), thay vì để từng router dọc đường tự tra bảng định tuyến rồi quyết định hop kế tiếp. Khác biệt nằm ở cách một "segment" được biểu diễn. SR-MPLS tái sử dụng đúng label MPLS quen thuộc — mỗi segment chỉ tốn 4 byte, ghép chồng thành một stack label, node nào cũng chỉ cần biết swap label theo đúng cách MPLS vẫn làm hàng chục năm nay. SRv6 (kiến trúc mô tả trong RFC 8402, phần header cụ thể là SRH — Segment Routing Header — chuẩn hóa trong RFC 8754) đi theo hướng khác hẳn: mỗi segment chính là một địa chỉ IPv6 đầy đủ 128 bit, và địa chỉ đó không chỉ định danh một node mà còn có thể mã hoá luôn một "hành động" cụ thể node đó phải thực hiện (mô hình network programming). Cái giá phải trả cho khả năng lập trình phong phú đó là header nặng hơn hẳn — một SRH với vài segment có thể chiếm hàng chục đến hơn một trăm byte, so với vài byte của một label stack MPLS tương đương — nên quyết định chọn SR-MPLS hay SRv6 gần như luôn quay lại đúng câu hỏi đã đặt ra ở đầu mục này: hạ tầng hiện tại đã quen MPLS hay đã đầu tư sâu vào IPv6 native, và mức overhead đó có đáng so với những gì đổi lại hay không.
5. Thiết kế layer tổng thể: underlay autonomic + overlay BGP EVPN
Quay lại tư duy phân layer: xét một butterfly fabric 5 tầng (top-of-rack – spine – fab – spine – top-of-rack). IS-IS (hoặc RIFT) chỉ nên chạy ở các tầng này làm underlay — không chạy ra tận server, trừ khi thực sự cần cho các trường hợp đặc biệt như mạng single-application/single-use đã nêu ở trên.
Mục tiêu là làm cho phần underlay này càng "autonomic" càng tốt — không chỉ đơn thuần tự động hóa việc cấu hình, mà lý tưởng là dùng những implementation loại bỏ hẳn nhu cầu cấu hình trên các thiết bị này. Đây chính là tinh thần "cattle, not pets": không đối xử với các thiết bị này như những "vật cưng" đặc biệt cần chăm chút, cấu hình tỉ mỉ riêng từng con.
Phía trên lớp underlay này, có thể chạy một overlay BGP (ví dụ EVPN), kéo dài xuống tận top-of-rack. Vai trò của mỗi lớp trở nên rõ ràng:
- Underlay cung cấp: khả năng thiết lập BGP peering session, các tunnel endpoint để xây dựng tunnel, và (đặc biệt ở fab router) có thể cung cấp cả SR label để kiểm soát đường đi (pathing) qua mạng.
- Overlay đảm nhận toàn bộ phần phức tạp: policy, segmentation, việc đóng gói (tunneling) traffic layer 2, v.v.
Trong một số trường hợp, hoàn toàn có thể mở rộng overlay (chạy BGP) ra tận host — điều này khác với việc chạy underlay ra host, và là một lựa chọn hợp lý, chấp nhận được trong thiết kế layer như đã trình bày.
"Autonomic" nghĩa là gì trong thực tế, không chỉ là một tính từ đẹp?
Một underlay thực sự autonomic không cần kỹ sư gõ IP, area-id, hay metric tay cho từng thiết bị mới cắm vào rack — thiết bị tự khám phá láng giềng qua LLDP/LIE (Link Information Element trong RIFT), tự suy ra vị trí của mình trong topology (ở tầng leaf hay spine, dựa vào số lượng và hướng của các adjacency xung quanh), rồi tự hình thành adjacency và bắt đầu trao đổi route — toàn bộ quá trình này gọi là Zero Touch Provisioning (ZTP). Khi một switch leaf cháy nguồn và được thay bằng một switch mới nguyên (factory-default, chưa từng cấu hình), nó cắm cáp vào đúng vị trí cũ và tự "biết" mình là leaf, tự thiết lập lại toàn bộ adjacency mà không cần ai đăng nhập vào console — đây chính là ý nghĩa thực sự của "cattle, not pets" ở tầng vật lý: con "bò" (switch) chết đi, con "bò" mới thế chỗ, không ai phải "chăm sóc" riêng cho từng con.
Vì sao overlay lại có thể "mở rộng ra tận host" một cách an toàn trong khi underlay thì không nên (đã lý giải ở mục 3)? Vì bản chất phiên BGP overlay giữa switch và host là một eBGP session được thiết lập tường minh theo policy — mỗi bên biết chính xác mình đang nói chuyện với ai, quảng bá đúng những gì được phép quảng bá (route ứng dụng, VNI, RT/RD tương ứng), và toàn bộ phiên đó có thể tắt/bật độc lập mà không ảnh hưởng tới khả năng bản thân fabric bên dưới còn sống hay không — underlay vẫn tiếp tục forward gói tin dựa trên tunnel endpoint đã có sẵn, bất kể phiên BGP overlay ở host đó còn sống hay vừa restart. Ranh giới failure domain giữa hai lớp nhờ vậy vẫn được giữ nguyên, dù cả hai đều "chạy ra tận host" theo một nghĩa nào đó.
# FRRouting — kiểm tra phiên overlay BGP EVPN từ leaf xuống tận host
show bgp l2vpn evpn summary
# Output minh họa
BGP router identifier 10.0.0.11, local AS number 65011 vrf-id 0
BGP table version 4
RIB entries 6, using 1152 bytes of memory
Peers 2, using 43 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.0.0.1 4 65000 842 839 0 0 0 03:14:22 5
192.168.100.2 4 65099 210 208 0 0 0 00:42:07 2
Total number of neighbors 2
(Output minh họa — cấu trúc và tên field đúng theo lệnh thật, số liệu cụ thể chỉ mang tính ví dụ.)
Trong output trên, neighbor 10.0.0.1 là phiên overlay giữa leaf và một switch khác trong fabric (chạy qua loopback, đúng theo thiết kế underlay cung cấp connectivity), còn neighbor 192.168.100.2 với AS riêng biệt (65099) minh họa đúng trường hợp "mở rộng overlay ra tận host" vừa nêu — một phiên eBGP EVPN thiết lập trực tiếp tới host, độc lập hoàn toàn với việc IS-IS/RIFT bên dưới có chạy tới đó hay không.
💡 Hình dung như thế này: underlay giống hệ thống đường ống nước ngầm của cả thành phố — tự động, không ai phải vặn từng van tay, cứ có ống là có nước chảy tới điểm cần tới. Overlay giống hợp đồng cấp nước ký riêng với từng hộ dân — hộ nào có hợp đồng mới được mở van nhận nước, hộ nào ký thêm hợp đồng gì (nước sinh hoạt, nước tưới cây) là chuyện giữa công ty cấp nước và hộ đó, không liên quan gì tới việc đường ống ngầm bên dưới có đang hoạt động tốt hay không.
6. External connections: vì sao spine không phải là core
Cách vẽ phổ biến nhất của spine-leaf — tất cả spine ở trên cùng, tất cả leaf ở dưới cùng — dễ khiến người xem nhầm tưởng lớp spine chính là network core theo nghĩa truyền thống. Đây là một sự nhầm lẫn khái niệm — spine của một fabric hoàn toàn khác với network core.
Từ sự nhầm lẫn này, nhiều người xây dựng theo kiểu "collapsed core"/"collapsed spine" — dồn kết nối ra bên ngoài (external connectivity) và các loại policy khác vào ngay lớp spine. Điều này có vẻ hợp lý vì spine thường là các chassis lớn, nhiều processor, nhiều bộ nhớ.
Quan điểm phản đối trong bài: spine (hay fab) nên chỉ là một "dumb packet forwarding engine" — không nên chứa bất kỳ trí tuệ/xử lý đặc biệt nào. Thay vào đó, nên đưa external connectivity và mọi thứ liên quan tới policy xuống một pod cụ thể (trong butterfly fabric), hoặc xây dựng một border leaf riêng (trong Clos fabric).
Vấn đề cụ thể khi gắn external connectivity trực tiếp vào lớp spine: giả sử có hai kết nối Internet, nối vào đúng hai router spine cụ thể. Nhìn bề ngoài có vẻ cân bằng (mọi nơi đều có đường lên tới hai router đó), nhưng thực chất đã đặt một loại tải hoàn toàn khác lên đúng hai thiết bị này — chúng phải làm filtering và xử lý đủ loại việc khác mà các spine còn lại không phải làm. Hệ quả:
- Hai thiết bị đó không còn là "cattle" nữa — chúng trở thành "pet", phá vỡ toàn bộ khái niệm single-skew, tính module hóa, tính lặp lại đồng nhất của thiết kế fabric.
- Traffic pattern cũng bị phá vỡ: toàn bộ traffic ra bên ngoài giờ phải đi qua đúng hai thiết bị đó — nghĩa là một phần của fabric quay trở lại traffic pattern north-south. Điều này đi ngược lại chính mục đích cốt lõi của một fabric: biến toàn bộ traffic thành east-west, để mọi port và mọi spine/fab đều bình đẳng với nhau.
💡 Hình dung như thế này: giống một chuỗi cửa hàng có hàng trăm chi nhánh giống hệt nhau, bỗng dưng giao thêm việc "tiếp khách VIP" và "kế toán tổng" cho đúng 2 chi nhánh cụ thể. Hai chi nhánh đó không còn giống các chi nhánh khác nữa — và mỗi khi có khách VIP hay cần đối soát sổ sách, tất cả phải đổ dồn về đúng 2 địa điểm đó, dù hàng trăm chi nhánh khác đang hoàn toàn rảnh rỗi.
Vì sao "dumb packet forwarding engine" lại là một mục tiêu đáng theo đuổi, thay vì một sự lãng phí năng lực phần cứng của những chassis lớn? Vì bản chất một spine/fab trong Clos hay butterfly fabric chỉ cần làm đúng một việc — tra bảng forwarding (dựa trên route học được từ underlay, hoặc đơn giản hơn nữa là swap label nếu chạy MPLS/SR) rồi đẩy gói tin ra đúng port kế tiếp. Việc này không đòi hỏi CPU mạnh, không đòi hỏi route-map, prefix-list, hay bất kỳ policy nào — toàn bộ có thể chạy trên ASIC chuyên dụng với độ trễ cực thấp. Ngược lại, filtering cho external connectivity (chặn prefix không hợp lệ, giới hạn route quảng bá ra ngoài, áp BGP community để đánh dấu traffic) là loại xử lý có trạng thái và có ngữ nghĩa — cần biết "đây là traffic đi ra Internet nên phải lọc theo policy X", một khái niệm hoàn toàn xa lạ với một forwarding engine thuần túy. Nhét cả hai việc vào chung một thiết bị không sai về mặt kỹ thuật, nhưng buộc thiết bị đó phải mang hai vai trò khác bản chất — dẫn thẳng tới hệ quả "pet" đã nêu.
# Cisco IOS-XR — áp route-map lọc route quảng bá ra Internet, cấu hình CHỈ trên border leaf
router bgp 65099
neighbor 203.0.113.1
remote-as 64500
address-family ipv4 unicast
route-map OUT-TO-ISP out
route-map IN-FROM-ISP in
# Kiểm tra route thực sự được quảng bá ra ngoài qua border leaf
show bgp ipv4 unicast neighbors 203.0.113.1 advertised-routes
# Output minh họa
Network Next Hop Metric LocPrf Weight Path
*> 198.51.100.0/24 0.0.0.0 0 0 65099 i
*> 198.51.101.0/24 0.0.0.0 0 0 65099 i
Total number of prefixes 2
(Output minh họa — cấu trúc và tên field đúng theo lệnh thật, số liệu cụ thể chỉ mang tính ví dụ.)
Điểm đáng chú ý trong ví dụ trên: cấu hình route-map và toàn bộ session eBGP ra ISP chỉ tồn tại trên đúng một thiết bị (border leaf 65099) — mọi spine/fab còn lại trong fabric không có, và cũng không cần có, một dòng cấu hình nào liên quan tới Internet hay policy lọc route. Nếu ngày mai cần đổi ISP, thêm community, hay siết chặt filtering, thay đổi chỉ chạm vào đúng một điểm — đây chính là lợi ích vận hành cụ thể của việc tách policy ra khỏi spine, không chỉ là một nguyên tắc thiết kế trừu tượng.
7. Grey failure: khi luật số lớn "lật ngược" con số MTBF đẹp đẽ
Khi nghĩ về resilience, thường thì mong muốn có fan-out ECMP càng cao càng tốt (nghĩa là càng nhiều thiết bị càng tốt). Ví dụ: 2.500 thiết bị 2RU loại 64×100G, mỗi thiết bị hỗ trợ 1.024 đường đi. Nếu tính theo công thức MTBF (Mean Time Between Failure) cho toàn bộ tập hợp đường đi giữa hai port ở top-of-rack, con số trông rất đẹp — có thể lên tới khoảng 25 năm; với một số path khác thậm chí khoảng 100 năm.
Vấn đề: luật số lớn (law of large numbers) rốt cuộc sẽ "lật ngược" những con số MTBF đẹp đẽ này. Với 2.500 router, dù MTBF của toàn bộ fabric (tính theo khả năng path bị mất hoàn toàn) có thể ở mức khoảng 25 năm, nhưng nếu tính ngược lại tần suất một router cụ thể bất kỳ trong mạng gặp sự cố, con số đó rơi vào khoảng 87,6 giờ một lần — hoàn toàn khác biệt. Nếu nhìn vào các optical interface, tần suất lỗi còn cao hơn — khoảng 5,5 giờ một lần.
Vì sao hai con số nghe có vẻ mâu thuẫn đó (25 năm và 87,6 giờ) lại cùng đúng một lúc? Đây thực chất là bài toán độ tin cậy của một hệ thống nối tiếp (series reliability system) kinh điển: khi có N thành phần độc lập, và chỉ cần một thành phần bất kỳ hỏng là tính "một sự cố đã xảy ra ở đâu đó trong hệ thống", thì tỷ lệ lỗi (failure rate) của toàn hệ thống cộng dồn gần như tuyến tính theo N — nghĩa là MTBF của "cả hệ thống có ít nhất một chỗ hỏng" giảm theo đúng hệ số 1/N so với MTBF của một thành phần đơn lẻ. Thử làm phép tính ngược lại với đúng con số trong ví dụ: 25 năm ≈ 219.000 giờ; chia cho 2.500 router, ra đúng 87,6 giờ — khớp chính xác. Nói cách khác, "25 năm" là độ bền kỳ vọng của một router nếu đứng một mình, còn "87,6 giờ" là khoảng thời gian kỳ vọng giữa hai lần bất kỳ router nào trong toàn bộ 2.500 con gặp sự cố — và với một fabric quy mô lớn, câu hỏi vận hành thực sự quan tâm luôn là vế thứ hai, vì luôn có một thiết bị nào đó đang hỏng ở đâu đó trong hệ thống tại bất kỳ thời điểm nào.
💡 Hình dung như thế này: một vé số có xác suất trúng cực thấp — mua một vé, khả năng trúng gần như bằng không, giống hệt việc trông đợi đúng một router cụ thể hỏng trong ngày mai. Nhưng một công ty xổ số phát hành hàng triệu vé mỗi kỳ thì gần như chắc chắn có ai đó trúng thưởng mỗi lần quay số — không phải vì may mắn tăng lên, mà đơn giản vì số lượng vé đủ lớn để luật số lớn phát huy tác dụng. Vận hành một fabric 2.500 router cũng vậy: xác suất một con cụ thể hỏng hôm nay gần như bằng không, nhưng xác suất có một con nào đó hỏng hôm nay lại gần như chắc chắn.
Những kiểu lỗi tần suất cao, quy mô nhỏ này thường dẫn tới grey failure — loại lỗi mà telemetry tiêu chuẩn không quan sát được, nhưng vẫn ảnh hưởng trực tiếp tới hiệu năng ứng dụng. Đây là điều rất quan trọng cần lưu ý khi xây các fabric quy mô thực sự lớn.
Ví dụ về grey failure: tỷ lệ drop gói nhỏ (ví dụ khoảng 1%) trên nhiều interface cùng lúc. Loại lỗi này có thể làm chậm tốc độ hội tụ — nhắc lại cơ chế exponential backoff ở phần trước: nếu liên tục có một lượng nhỏ sự kiện lỗi xảy ra ở mức thấp, các timer backoff sẽ liên tục bị đẩy lùi (back off), khiến tốc độ hội tụ chậm đi đúng vào lúc cần nhanh nhất.
# Kiểm tra dấu hiệu grey failure ở mức interface — packet loss thấp,
# không đủ để trigger link-down nhưng đủ để ảnh hưởng ứng dụng
show interfaces GigabitEthernet0/0/0 | include error|drop|CRC
# Output minh họa
GigabitEthernet0/0/0 is up, line protocol is up
5 minute input rate 980000000 bits/sec, 145000 packets/sec
1245 input errors, 12 CRC, 0 frame, 0 overrun
input queue drops 3021
# Juniper JunOS — theo dõi optic quang qua digital diagnostics (DOM)
show interfaces diagnostics optics et-0/0/0
# Output minh họa
Laser bias current : 38.500 mA
Laser output power : -2.10 dBm
Module temperature : 42 degrees C
Laser rx power : -11.80 dBm (warning threshold: -12.00 dBm)
(Output minh họa — cấu trúc và tên field đúng theo lệnh thật, số liệu cụ thể chỉ mang tính ví dụ.)
Điểm cần soi kỹ trong hai output trên không phải là "interface có down hay không" — cả hai interface vẫn báo up, đúng bản chất grey failure là loại lỗi không đủ nghiêm trọng để trigger trạng thái down. Thứ đáng chú ý là input queue drops đang tăng dần dù interface vẫn up (dấu hiệu nghẽn nhẹ, liên tục), và Laser rx power đang áp sát ngưỡng warning (dấu hiệu optic sắp suy hao tới mức lỗi, nhưng chưa tới) — cả hai đều là loại tín hiệu chỉ lộ ra khi có người chủ động truy vấn số liệu chi tiết, chứ không tự động xuất hiện trong log lỗi thông thường hay trong trạng thái up/down đơn giản mà nhiều hệ thống giám sát mặc định chỉ theo dõi.
Vì vậy cần suy nghĩ kỹ về telemetry để phát hiện grey failure — và bản chất của vấn đề nằm ở chính cách telemetry truyền thống được thiết kế: polling định kỳ (ví dụ SNMP poll mỗi 5 phút) chỉ chụp lại một lát cắt trạng thái tại đúng thời điểm poll, dễ bỏ lỡ hoàn toàn một đợt drop gói kéo dài 30 giây rồi tự hết. Cách tiếp cận phù hợp hơn với grey failure là streaming telemetry — thiết bị tự đẩy số liệu liên tục (event-driven hoặc theo chu kỳ rất ngắn) thay vì chờ được hỏi, giúp phát hiện đúng những đợt suy giảm ngắn, nhỏ, lặp lại mà polling truyền thống gần như chắc chắn bỏ lỡ. Tương tự, security cũng là một chủ đề lớn khác cần cân nhắc riêng. Cả hai — telemetry và security — không nên được "gắn thêm" (bolted on) sau khi thiết kế xong, mà cần được xây dựng sẵn (built in) ngay từ đầu, là một phần của thiết kế gốc chứ không phải phần bổ sung sau này.
Nguồn tham khảo
Nguồn gốc: Understanding Data Center Fabrics, Part 9: Other Considerations — kênh Packet Pushers
Ghi chú fact-check (truy cập 2026-07-13): các con số MTBF cụ thể ở mục 7 (25 năm cho toàn fabric, 87,6 giờ cho một router, 5,5 giờ cho optic) là ví dụ minh họa từ kinh nghiệm cá nhân của diễn giả, không phải số liệu benchmark công khai hay cam kết từ vendor — bản chất toán học của lập luận (luật số lớn khiến MTBF cấp hệ thống và MTBF cấp thiết bị đơn lẻ khác nhau rất xa) là đúng và là nguyên lý được công nhận rộng rãi trong reliability engineering, nhưng con số cụ thể nên xem là minh họa, không phải số tra cứu.
Ghi chú fact-check (truy cập 2026-07-14): thuật ngữ grey failure ở mục 7 có nguồn học thuật cụ thể — bài báo "Gray Failure: The Achilles' Heel of Cloud-Scale Systems" của Peng Huang, Chuanxiong Guo, Lidong Zhou, Jacob R. Lorch, Yingnong Dang, Murali Chintalapati và Randolph Yao (Microsoft Research), trình bày tại HotOS 2017 (Whistler, BC, Canada), thường được xem là paper đặt nền móng cho thuật ngữ này trong ngành. Điểm cốt lõi của paper — "differential observability" (hệ thống giám sát không thấy vấn đề dù ứng dụng đang bị ảnh hưởng thật) — khớp với cách bài viết mô tả grey failure ở mục 7. Đọc thêm tại Gray Failure: The Achilles' Heel of Cloud-Scale Systems (PDF, Microsoft Research).
- EVPN multihoming (Ethernet Segment, ESI, Type-1 Ethernet Auto-Discovery Route, Type-4 Ethernet Segment Route) chuẩn hóa trong BGP MPLS-Based Ethernet VPN — 2026-08-17, RFC 7432.
- EVPN Route Type 5 (IP Prefix Advertisement, tách MAC khỏi IP prefix, dùng cho routed dual-home/subnet dual-homing) chuẩn hóa trong RFC riêng, không nằm trong RFC 7432 gốc — 2026-08-17, RFC 9136.
- Kiến trúc Segment Routing (SR-MPLS và SRv6 là hai data-plane instantiation) — 2026-08-17, RFC 8402.
- SRv6 Segment Routing Header (SRH) — 2026-08-17, RFC 8754.
- RIFT (Routing in Fat Trees) đã được công bố chính thức thành Standards Track RFC vào tháng 4/2025, không còn ở dạng draft — 2026-08-17, RFC 9692.
- Draft SRm6 (draft-bonica-spring-sr-mapped-six) đã hết hạn từ 2021 (bản mới nhất -04, tháng 9/2021), là individual draft, chưa từng được một IETF working group nào nhận nuôi, hiện ở trạng thái "no longer active" — 2026-08-17, IETF Datatracker: draft-bonica-spring-sr-mapped-six.