JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

覆疊與虛擬交換器:為雲端織起網路

葉脊架構又快又「笨」,而且是刻意如此。那麼,成千上萬個客戶,要如何在同一套共用的線路上各自擁有一張屬於自己的私有網路?訣竅是把封包包進封包裡——再讓軟體交換器去動腦。

光靠裸架構解不了的兩個問題

上一篇給了我們一台漂亮的機器:一張葉脊架構,能在任意兩台伺服器之間全速搬運封包,並用 等價多路徑(ECMP)把資料流攤在許多條等長的路徑上。但這張架構是刻意做得簡單的。它知道實體伺服器、它們的位址,以及抵達每一台的最短路徑——除此之外幾乎一無所知。在真實的雲端裡,客戶根本就不是實體伺服器。他們是虛擬機與容器,幾十個擠在每一台實體機器上,一小時內成千上萬次地誕生又消失。

這帶來兩個讓裸資料中心網路靠自己解不了的頭痛問題。第一是隔離:客戶 A 和客戶 B 可能都替自己某台機器挑了位址 10.0.0.5,而他們絕不能看到彼此的流量——即使他們的虛擬機恰好落在同一台實體伺服器上。第二是移動性:當一台虛擬機為了維護而從一個機架遷移到另一個機架時,它的位址必須跟著走——但在底層網路裡,位址是綁定在「位置」上的,所以搬動它通常會弄斷每一條連線。架構之所以快,正是因為它拒絕去追蹤這一切的變動。

覆疊的點子:用軟體畫出來的私有網路

網路覆疊是一張只以「邊緣機器之間的約定」形式存在的網路。架構中段的任何東西都不需要知道它的存在。把它想成郵政系統:高速公路與分揀中心(底層)永遠只讀信封外層的位址。如果你把第二封寫好完整地址的信,封進那個信封裡,郵政系統會樂呵呵地把整件東西送到外層位址所寫的那棟建築——只有在那裡拆信的人,才會讀到裡頭那封信並把它轉交出去。外層信封是底層的工作;裡頭那封信,則是覆疊自己的私事。

這個「信封套信封」的把戲,正是封裝——你很久以前就遇過的同一個點子:一個 TCP 區段被裝進 IP 封包、再裝進乙太網路訊框裡。覆疊只是再加一層:它拿起來自客戶虛擬機的一個完整封包,把它包進一個全新的、定址於兩台實體伺服器之間的外層封包裡。架構依照外層位址轉送這個外層封包,從不檢視裡頭裝著什麼。當它抵達時,接收端的伺服器剝掉那層包裝,把原封不動的原始封包交給正確的虛擬機。客戶的網路完全不曉得自己搭了趟便車,穿過了別人的線路。

這一招同時解掉了兩個頭痛問題。隔離不費吹灰之力:每張覆疊都帶著一個標籤,標明它屬於哪個客戶的網路,所以兩台都用 10.0.0.5 的虛擬機,是坐在不同的覆疊上的,永遠不會被搞混。移動性也是免費送的:當一台虛擬機遷移到新機架時,變的只有外層位址——而那個內層封包,連同虛擬機自己那個沒變過的位址,在覆疊裡的所有人看來都長得一模一樣。連線之所以能撐過這次搬遷,是因為客戶看得見的那部分,根本就沒有動過。

VXLAN:那層包裝實際上是怎麼運作的

建造這類覆疊最常見的方式是 VXLAN——Virtual eXtensible LAN(虛擬可延伸區域網路)。這名字本身就透露了它在做什麼:它讓客戶的虛擬機表現得像是全都插在同一張大交換器上、處在同一個本地網路裡,即使它們其實散落在各個機架、底下只靠路由過的 IP 連起來。VXLAN 拿起客戶整個乙太網路訊框,把它塞進一個會穿越底層網路的 UDP 封包裡。負責這層包裝與拆裝的端點叫做 VTEP(VXLAN 隧道端點),它們幾乎總是以軟體形式住在每一台實體伺服器上。

What goes on the wire when VM-A (on server S1) sends a frame to VM-B (on server S2):

  +----------------------------------------------------------------+
  | Outer Ethernet | Outer IP        | Outer UDP | VXLAN | INNER   |
  | S1-nic -> S2-nic| 192.0.2.1->.2  | dst 4789  | VNI   | FRAME   |
  +----------------------------------------------------------------+
     \____ added by the VTEP on S1 (the wrapper) _________/   ^
                                                              |
  INNER FRAME = the customer's original, untouched Ethernet frame:
     [ VM-A mac -> VM-B mac | 10.0.0.5 -> 10.0.0.6 | TCP ... data ]

  VNI = the 24-bit tenant tag: which customer network this belongs to.
  The leaf-spine fabric only ever reads the OUTER IP (192.0.2.1->.2).
一個經 VXLAN 封裝的封包:客戶整個訊框,是以負載的身分,搭在一個定址於兩台實體伺服器之間的外層 UDP/IP 封包裡。VNI 標籤把各個租戶分隔開來。

那張草圖裡有兩個細節,承載著真正的魔法。第一個是 VNI,VXLAN 網路識別碼:一個被蓋進每個被包裝封包裡的 24 位元標籤,說明它屬於哪個租戶的網路。24 位元能給出約 2^24 個網路——超過一千六百萬個——這就是為什麼 VXLAN 取代了舊式 VLAN 標籤那區區的 4096 個。第二個是那個外層 UDP。選用 UDP 不是為了可靠性——內層的 TCP 早就把那件事處理好了。它其實是個巧計:底層的 ECMP 是靠雜湊埠號來分散資料流的,所以 VTEP 會讓每一條內層流的外層 UDP 來源埠各不相同。如此一來,成千上萬條被隧道化的資料流,就會均勻地散到所有脊上的路徑,而不會把某一條塞爆。

虛擬交換器:動腦的工作搬到了哪裡

那麼,是誰在做這層包裝、決定該送往哪台實體伺服器、又執行「誰可以跟誰講話」的規則呢?不是架構——它刻意維持「笨」。這些工作搬進了虛擬交換器:一段跑在每台實體伺服器上的軟體,坐在虛擬機與真實網路卡之間。回想最早那個把交換器比作「會學每個人坐哪」的接待員的比喻。虛擬交換器就是同一位接待員,只不過如今住在主機內部的軟體裡,照料著一整棟住滿虛擬租戶、而且老是換座位的建築。

正因為它是軟體,虛擬交換器可以比任何硬體交換器以往所能的都聰明得多。它學會每台虛擬機住在哪,它負責 VXLAN 的包裝與 VNI 的貼標,它在封包還沒碰到線路之前就執行每台虛擬機的防火牆規則(稱為安全群組),它計量頻寬,還能把流量鏡像出來做監控。這就是軟體定義網路那安靜的基礎:網路的智慧已從固定的盒子裡被抽出來,搬進邊緣的可程式化軟體中,在那裡只要一個 API 呼叫、幾秒鐘就能更新。架構負責轉送;虛擬交換器負責思考。

  1. 伺服器 S1 上的虛擬機 A,發出一個再普通不過的訊框,要送給虛擬機 B(內層位址 10.0.0.6)。它完全不知道自己身在雲端——它以為自己在一張單純的區域網路上。
  2. S1 的虛擬交換器攔下這個訊框,查出在這個租戶的網路裡、虛擬機 B 是由哪台實體伺服器所託管,發現它在伺服器 S2 上、底層位址為 192.0.2.2。
  3. 虛擬交換器把整個訊框包進 VXLAN:蓋上這個租戶的 VNI、挑一個外層 UDP 來源埠(好讓 ECMP 分散負載),並把外層 IP 定址為從 192.0.2.1 送往 192.0.2.2。
  4. 葉脊架構單憑外層 IP 來轉送這個外層封包,把它雜湊到眾多等長路徑的其中一條。它從不往裡頭看。
  5. S2 的虛擬交換器收下它,剝掉 VXLAN 包裝,核對 VNI 以確認租戶身分,然後把原封不動的原始訊框交給虛擬機 B——而它對這一切的發生毫不知情。

雲端負載平衡器:一扇門,許多房間

雲端還需要最後一塊拼圖,而它正是直接蓋在覆疊之上的。一個熱門服務並不是一台伺服器——它是一支由一模一樣的虛擬機組成的隊伍,會隨需求脹大或縮小。但外面的世界需要一個單一、穩定的位址來連入。雲端負載平衡器就是那扇單一的前門:客戶端全都連到同一個虛擬 IP,而負載平衡器則把他們的連線攤分到後方那些健康的虛擬機上——就像一位好的主人,會把陸續到來的客人安排到許多空房裡,而不是把他們全擠進同一間。

你在 CDN 那一級已經見過負載平衡,但雲端版本,重重地倚靠著本篇所講的一切。負載平衡器持續跑著健康檢查,所以它絕不會把流量送往一台已經當機的虛擬機。它可以在第四層做平衡(純粹依速度攤分 TCP 連線),也可以像第七層平衡器那樣,窺看 HTTP 內部、按 URL 路徑來路由——把 /images 送往一個機群、把 /checkout 送往另一個。而正因為後端的虛擬機都住在覆疊上,負載平衡器可以挑一台位於不同機架、甚至剛剛才啟動的新虛擬機,而封裝會悄悄地把連線送達那裡。那扇單一的前門穩穩不動,門後的房間卻能隨意重建。

值得誠實地談談負載平衡器修得了與修不了什麼。它把負載攤分得漂亮,也優雅地繞開死掉的虛擬機,而那個虛擬 IP 讓你能隱形地擴張規模。但它無法擊敗物理:如果每一台後端虛擬機都真的超載了,平衡器也只是把這份苦難均勻地攤開而已。而且它多加了一跳,所以它要付出一點延遲——後面擺再多頻寬或再多虛擬機,也永遠削不掉那個來回時間到光速與這額外一跳所允許的範圍以下。負載平衡器管的是「工作往哪去」;它並不會讓網路變快。

把這幾層重新拼回去

退一步看,整張雲端網路就是一份乾淨的分工。最底層,一張又快又「笨」的葉脊架構,在實體伺服器之間搬運外層封包、並用 ECMP 把它們平衡開來——它就只做這件事。在它之上,每台主機上的軟體虛擬交換器VXLAN建造覆疊,給每個客戶一張完全用軟體畫出來的、私有、可移動、互相隔離的網路。而在最前面,雲端負載平衡器替每個服務交付一個單一穩定的位址,背後則是一支可自由擴張的機群。每一層都把自己的混亂藏起來、不讓上一層看見——這正像你在最開頭那一級學到的通訊協定堆疊。

但底下藏著一股張力,而它正為本級接下來的內容鋪了路。這一切的軟體包裝與拆裝,都發生在主機 CPU 上,而這張網路的期限是以微秒計的,且單一個使用者請求可能一次就扇出到上千台後端虛擬機。當那上千個回覆同時湧回來時,它們會以公眾網際網路從未見過的方式,猛撞接收端與架構。為什麼那場「同步洪水」如此危險——以及那為了馴服它而打造的特殊壅塞控制——正是下一篇要帶我們去的地方。