在物理交換機中,Mac-Address-Table 被用于 Ethernet 數據包的轉發。然而,在邏輯交換機中,當兩個虛擬機相互通信時,底層 vSphere Host 必須知道目標 VM 位于哪個 Host 上,然后通過 VXLAN 封裝發送原始 Ethernet Frame。問題來了:Host 如何知道目標 VM 位于哪臺 Host 上?
考慮一個有三個 vSphere 主機 A/B/C 的環境,VTEP 為 10.20.10.10/24、10.20.20.11/24、10.20.30.12/24。我們創建了一個邏輯交換機 VXLAN 5001,并在這個邏輯交換機上連接了兩個虛擬機 VM1 / VM2。邏輯網段是 192.168.10.0/24,兩個虛擬機的 IP 是 101/102,分別位于主機 A 和主機 B 上。
當 VM1 想與 VM2 進行流量傳輸時,Host A 如何知道 VM2 在哪個 Host 上?
首先我們需要知道的是,NSX 控制器為每個邏輯交換機維護三個表。VTEP 表/MAC 表/ARP 表,解釋如下。
VTEP Table
當我們創建一個邏輯交換機時,我們將 VM "插入 "到該邏輯交換機上。簡而言之,每個 vSphere Host 必須知道它有哪些 VM,以及 VM 位于哪個邏輯交換機上。當每個虛擬機所在的邏輯交換機發生變化時,vSphere Host 將立即通知 NSX Controller 哪個邏輯交換機連接到這個 Host。
也就是說,Host A 和 Host B 將分別向控制器報告它們有 VXLAN 5001 作為邏輯交換機。然而,Host C 不會發送這個消息,因為它沒有任何位于 VXLAN 5001 的虛擬機。
Host C 在 VXLAN 5001 上沒有任何 VM,所以在 Controller 的 VTEP 表中不會有 VTEP 10.20.30.12 信息。但要考慮兩個條件:
如果在 Host C 上創建了一個新的 VM3 并添加了 VXLAN 5001,Host C 將告訴 Controller 他也有 VXLAN 5001,并且 Controller 上的 VNI 5001 VTEP 表將添加一個新的 10.20.30.12。
如果 VM 2 從 Host B 被 vMotion 到 Host C,Host C 將向 Controller 報告它有 VXLAN 5001,而 Host B 將向控制器報告它沒有 VXLAN 5001,因為這個 Controller 上沒有更多的虛擬機。
當 VTEP Table 被創建和更新時,Controller 會立即通知每個相關的 vSphere Hosts,因此不僅 Controller 本身,而且每個 vSphere Host 都有一份最新的 VTEP Table,以了解其上有哪些邏輯交換機,以及除了自己以外還有哪些主機也有這個邏輯交換機。主機 A/B 將知道 VXLAN 5001 上的主機包括主機A(10.20.10.10)和主機B(10.20.20.11)。
MAC Table
同樣地,每個 vSphere Host 也必須知道它上面的 VM 的 MAC Address 是什么。因此,Host 也會通知 NSX Controller 哪些虛擬機(MAC Address)在它自己的哪個邏輯交換機中。Host A 會告訴 NSX Controller,它在 VXLAN 5001 中有一個 VM 硬件位置 MAC 1,而 Host B 也會告訴 Controller,它有一個 MAC 2。因此,NSX Controller 匯總了這些信息,可以為邏輯交換機 5001 創建 MAC 表。
當然,如果有虛擬機變化或 vMotion 等操作,受影響的主機也會通知 NSX 控制器進行相關更新。這個表只在 NSX 控制器中維護,不會被發送到主機上。
ARP Table
即使沒有安裝 VMTools,vSphere Host 可能仍然有辦法知道每個虛擬機的 IP 地址,包括
如果這個 VM 發送了 DHCP Request,就會從 reply packet 中知道 IP 地址。
只要這個 VM 發送 ARP Request,請求的源 IP 將告訴這個 VM 的地址。
接下來,主機也會向 NSX 控制器發送一個消息,告知自己虛擬機的 MAC 地址和 IP 地址映射。因此,類似地,NSX 控制器會了解每個邏輯交換機上有哪些 IP 地址,以及相應的 MAC 地址。
從上面的討論中,我們會發現 NSX 控制器實際上集中了每個邏輯交換機的拓撲信息,包括每個交換機建立在哪些主機上,這個交換機上有哪些虛擬機(MAC地址),以及它們對應的 IP 地址。主機 A 如何知道 VM2 在哪個主機上?
首先:VM1 不知道 VM2 的 MAC 地址,所以發出了一個 ARP 請求
此時,vSphere 主機收到這個 ARP 請求,并且不知道主機上緩存中的 VM2 的 MAC 地址,那么主機 A 將向 NSX 控制器發送一個 ARP 請求。然后,主機 A 向 VM1 發送一個 ARP 回復。
(另一種可能是,控制器上的 ARP 表還沒有學到 VM2 的 IP 信息。這時,主機將直接使用本地 VTEP 表向 VNI 5001 VTEP 表中的所有服務器發送該 ARP 請求)
接下來,VM1 向 VM2 發送一個 Ethernet 數據包
當主機 A 收到這個數據包時,它將要求控制器查詢 VXLAN 5001 的 MAC 表,得到 MAC2 對應的 VTEP 是 10.20.20.11。啊哈,目的地主機已經發現了。這一次,Host A 將在原以太網幀的前面加上 VXLAN 表頭。
從底層硬件網絡到主機 B 的正常 Hop-By-Hop 數據包傳輸后,VXLAN 被解包,VXLAN 為 5001,原始以太網幀通過正常的傳輸機制被發送到 5001 邏輯交換機中的 VM2(通過目的 MAC 地址)。
那么從 VM1 到 VM2 的以太網數據包呢?
因為在 ARP 請求和第一次數據包傳輸時,主機 A 已經有了相關的知識并放入了 Cache,后續傳輸同一網絡流的數據包時不需要再詢問 NSX 控制器,直接進行 VXLAN 封裝和傳輸。
我希望以上步驟可以幫助你理解 NSX 中同一邏輯交換機中的數據包是如何通過底層硬件網絡傳遞到目的地的。這也解釋了為什么在 NSX 環境中,通常在 ping 時,第一個數據包的 Latency 會比較大。通常情況下,當 VM 在 NSX 環境中第一次相互通信時,Latency 可能會比較大。
原因是 Host 處理第一個數據包有更多的步驟,包括響應 ARP Request,和向 Controller 詢問相關信息。但在第二個數據包之后,Host 的 Cache 已經存儲了相關信息,那么隨后的網絡傳輸就非常快了。