Linux 虛擬網路卡技術:Macvlan

米開朗基楊發表於2019-04-01

原文連結:Linux 虛擬網路卡技術:Macvlan

1. Macvlan 簡介

在 Macvlan 出現之前,我們只能為一塊乙太網卡新增多個 IP 地址,卻不能新增多個 MAC 地址,因為 MAC 地址正是通過其全球唯一性來標識一塊乙太網卡的,即便你使用了建立 ethx:y 這樣的方式,你會發現所有這些“網路卡”的 MAC 地址和 ethx 都是一樣的,本質上,它們還是一塊網路卡,這將限制你做很多二層的操作。有了 Macvlan 技術,你可以這麼做了。

Macvlan 允許你在主機的一個網路介面上配置多個虛擬的網路介面,這些網路 interface 有自己獨立的 MAC 地址,也可以配置上 IP 地址進行通訊。Macvlan 下的虛擬機器或者容器網路和主機在同一個網段中,共享同一個廣播域。Macvlan 和 Bridge 比較相似,但因為它省去了 Bridge 的存在,所以配置和除錯起來比較簡單,而且效率也相對高。除此之外,Macvlan 自身也完美支援 VLAN

同一 VLAN 間資料傳輸是通過二層互訪,即 MAC 地址實現的,不需要使用路由。不同 VLAN 的使用者單播預設不能直接通訊,如果想要通訊,還需要三層裝置做路由,Macvlan 也是如此。用 Macvlan 技術虛擬出來的虛擬網路卡,在邏輯上和物理網路卡是對等的。物理網路卡也就相當於一個交換機,記錄著對應的虛擬網路卡和 MAC 地址,當物理網路卡收到資料包後,會根據目的 MAC 地址判斷這個包屬於哪一個虛擬網路卡。**這也就意味著,只要是從 Macvlan 子介面發來的資料包(或者是發往 Macvlan 子介面的資料包),物理網路卡只接收資料包,不處理資料包,所以這就引出了一個問題:本機 Macvlan 網路卡上面的 IP 無法和物理網路卡上面的 IP 通訊!**關於這個問題的解決方案我們下一節再討論。

我們先來看一下 Macvlan 技術的流程示意圖:

Linux 虛擬網路卡技術:Macvlan

簡單來說,Macvlan 虛擬網路卡裝置是寄生在物理網路卡裝置上的。發包時呼叫自己的發包函式,查詢到寄生的物理裝置,然後通過物理裝置發包。收包時,通過註冊寄生的物理裝置的 rx_handler 回撥函式,處理資料包。

2. Macvlan vs Bridge

說到 Macvlan,就不得不提 Bridge,因為你可以把 Macvlan 看成一個簡單的 Bridge。但他們之間還是有很大的區別的。

Bridge

Bridge 實際上就是一種舊式交換機,他們之間並沒有很大的差別。Bridge 與交換機的區別在與市場,而不在與技術。交換機對網路進行分段的方式與 Bridge 相同,交換機就是一個多埠的網橋。確切地說,高階口密度的 Bridge 就稱為區域網交換機。

Linux 虛擬網路卡技術:Macvlan

Bridge 有以下特點:

  • Bridge 是二層裝置,僅用來處理二層的通訊。
  • Bridge 使用 MAC 地址表來決定怎麼轉發幀(Frame)。
  • Bridge 會從 host 之間的通訊資料包中學習 MAC 地址。
  • 可以是硬體裝置,也可以是純軟體實現(例如:Linux Bridge)。

以下是一個在 Linux 主機上,多個 VM 使用 bridge 相互通訊的狀況:

Linux 虛擬網路卡技術:Macvlan

Linux 主機中可以通過命令列工具 brctl 來檢視 Bridge 的配置,該工具可以通過安裝軟體包 bridge-utils 來獲得。

$ brctl show

bridge name  bridge id          STP enabled  interfaces
br0          8000.080006ad34d1  no           eth0
                                             veth0
br1          8000.080021d2a187  no           veth1
                                             veth2
複製程式碼

Bridge 有可能會遇到二層環路,如有需要,你可以開啟 STP 來防止出現環路。

Macvlan

Macvlan 有以下特點:

  • 可讓使用者在同一張實體網路卡上設定多個 MAC 地址。
  • 承上,帶有上述設定的 MAC 地址的網路卡稱為子介面(sub interface);而實體網路卡則稱為父介面(parent interface)。
  • parent interface 可以是一個物理介面(eth0),可以是一個 802.1q 的子介面(eth0.10),也可以是 bonding 介面。
  • 可在 parent/sub interface 上設定的不只是 MAC 地址,IP 地址同樣也可以被設定。
  • sub interface 無法直接與 parent interface 通訊 (帶有 sub interface 的 VM 或容器無法與 host 直接通訊)。
  • 承上,若 VM 或容器需要與 host 通訊,那就必須額外建立一個 sub interface 給 host 用。
  • sub interface 通常以 mac0@eth0 的形式來命名以方便區別。

用張圖來解釋一下設定 Macvlan 後的樣子:

Linux 虛擬網路卡技術:Macvlan

3. Macvlan 的工作模式

Macvlan 共支援四種模式,分別是:

VEPA(Virtual Ethernet Port Aggregator)

Linux 虛擬網路卡技術:Macvlan

VEPA 模式下,所有從 Macvlan 介面發出的流量,不管目的地全部都傳送給父介面,即使流量的目的地是共享同一個父介面的其它 Macvlan 介面。在二層網路場景下,由於生成樹協議的原因,兩個 Macvlan 介面之間的通訊會被阻塞,這時需要上層路由器上為其新增路由(需要外部交換機配置 Hairpin 支援,即需要相容 802.1Qbg 的交換機支援,其可以把源和目的地址都是本地 Macvlan 介面地址的流量發回給相應的介面)。此模式下從父介面收到的廣播包,會泛洪給 VEPA 模式的所有子介面。

現在大多數交換機都不支援 Hairpin 模式,但 Linux 主機中可以通過一種 Harpin 模式的 Bridge 來讓 VEPA 模式下的不同 Macvlan 介面通訊(前文已經提到,Bridge 其實就是一種舊式交換機)。怎麼配置呢?非常簡單,通過一條命令就可以解決:

$ brctl hairpin br0 eth1 on
複製程式碼

或者使用 iproute2 來設定:

$ bridge link set dev eth0 hairpin on
複製程式碼

如果你的核心是你手工編譯升級的,那麼可能你的使用者態程式並不支援新核心對應的所有特性,也就是說你的 brctl 可能版本過老不支援 hairpin 命令,那麼可以 sysfs 來搞定:

$ echo 1 >/sys/class/net/br0/brif/eth1/hairpin_mode
複製程式碼

在 Linux 主機上配置了 Harpin 模式之後,源和目的地址都是本地 Macvlan 介面地址的流量,都會被 br0(假設你建立的 Bridge 是 br0)發回給相應的介面。

Linux 虛擬網路卡技術:Macvlan

如果想在物理交換機層面對虛擬機器或容器之間的訪問流量進行優化設定,VEPA 模式將是一種比較好的選擇。

VEPAPassthru 模式下,兩個 Macvlan 介面之間的通訊會經過主介面兩次:第一次是發出的時候,第二次是返回的時候。這樣會影響物理介面的寬頻,也限制了不同 Macvlan 介面之間通訊的速度。如果多個 Macvlan 介面之間通訊比較頻繁,對於效能的影響會比較明顯。

Bridge

Linux 虛擬網路卡技術:Macvlan

此種模式類似 Linux 的 Bridge,擁有相同父介面的兩塊 Macvlan 虛擬網路卡是可以直接通訊的,不需要把流量通過父網路卡傳送到外部網路,廣播幀將會被泛洪到連線在"網橋"上的所有其他子介面和物理介面。這比較適用於讓共享同一個父介面的 Macvlan 網路卡進行直接通訊的場景。

這裡所謂的 Bridge 指的是在這些網路卡之間,資料流可以實現直接轉發,不需要外部的協助,這有點類似於 Linux host 內建了一個 Bridge,即用 brctl 命令所做的那一切。但和 Linux bridge 絕不是一回事,它不需要學習 MAC 地址,也不需要 STP,因此效能比起使用 Linux bridge 好上很多。

Bridge 模式有個缺點:如果父介面 down 掉,所有的 Macvlan 子介面也會全部 down 掉,同時子介面之間也將無法進行通訊。

Private

Linux 虛擬網路卡技術:Macvlan

此種模式相當於 VEPA 模式的增強模式,其完全阻止共享同一父介面的 Macvlan 虛擬網路卡之間的通訊,即使配置了 Hairpin 讓從父介面發出的流量返回到宿主機,相應的通訊流量依然被丟棄。具體實現方式是丟棄廣播/多播資料,這就意味著乙太網地址解析 arp 將不可執行,除非手工探測 MAC 地址,否則通訊將無法在同一宿主機下的多個 Macvlan 網路卡間展開。之所以隔離廣播流量,是因為乙太網是基於廣播的,隔離了廣播,乙太網將失去了依託。

Passthru

Linux 虛擬網路卡技術:Macvlan

此種模式會直接把父介面和相應的MacVLAN介面捆綁在一起,這種模式每個父介面只能和一個 Macvlan 虛擬網路卡介面進行捆綁,並且 Macvlan 虛擬網路卡介面繼承父介面的 MAC 地址。

此種模式的優點是虛擬機器和容器可以更改 MAC 地址和其它一些介面參。

4. Macvlan 和 Bridge 的使用場景

最後我們再來討論一下 Macvlan 和 Bridge 的各自使用場景。

使用 Macvlan:

使用 Bridge:

  • 當在同一臺宿主機上需要連線多個虛擬機器或容器時。
  • 對於擁有多個網橋的混合環境。
  • 需要應用高階流量控制,FDB的維護。

5. Macvlan 的侷限性

Macvlan 是將 VM 或容器通過二層連線到物理網路的近乎理想的方案,但它也有一些侷限性:

  • Linux 主機連線的交換機可能會限制同一個物理埠上的 MAC 地址數量。雖然你可以讓網路管理員更改這些策略,但有時這種方法是無法實行的(比如你要去給客戶做一個快速的 PoC 演示)。
  • 許多 NIC 也會對該物理網路卡上的 MAC地址數量有限制。超過這個限制就會影響到系統的效能。
  • IEEE 802.11 不喜歡同一個客戶端上有多個 MAC 地址,這意味著你的 Macvlan 子介面在無線網路卡或 AP 中都無法通訊。可以通過複雜的辦法來突破這種限制,但還有一種更簡單的辦法,那就是使用 Ipvlan,感興趣可以自己查閱相關資料。

6. 總結

本文主要介紹了 Macvlan 的實現原理,比較了它和 Linux Bridge 模式之間的差異及其使用場景,還詳細剖析了 Macvlan 四種模式的工作原理和相關注意項。下一節我們將通過實際演練來模擬 Macvlan 的四種工作模式。

7. 參考資料

相關文章