Linux 虛擬網卡技術:Macvlan
1. Macvlan 簡介
在 Macvlan 出現(xiàn)之前,我們只能為一塊以太網卡添加多個 IP 地址,卻不能添加多個 MAC 地址,因為 MAC 地址正是通過其全球唯一性來標識一塊以太網卡的,即便你使用了創(chuàng)建 ethx:y 這樣的方式,你會發(fā)現(xiàn)所有這些“網卡”的 MAC 地址和 ethx 都是一樣的,本質上,它們還是一塊網卡,這將限制你做很多二層的操作。有了 Macvlan 技術,你可以這么做了。
Macvlan 允許你在主機的一個網絡接口上配置多個虛擬的網絡接口,這些網絡 interface 有自己獨立的 MAC 地址,也可以配置上 IP 地址進行通信。Macvlan 下的虛擬機或者容器網絡和主機在同一個網段中,共享同一個廣播域。Macvlan 和 Bridge 比較相似,但因為它省去了 Bridge 的存在,所以配置和調試起來比較簡單,而且效率也相對高。除此之外,Macvlan 自身也能很好的支持 VLAN。
同一 VLAN 間數(shù)據(jù)傳輸是通過二層互訪,即 MAC 地址實現(xiàn)的,不需要使用路由。不同 VLAN 的用戶單播默認不能直接通信,如果想要通信,還需要三層設備做路由,Macvlan 也是如此。用 Macvlan 技術虛擬出來的虛擬網卡,在邏輯上和物理網卡是對等的。物理網卡也就相當于一個交換機,記錄著對應的虛擬網卡和 MAC 地址,當物理網卡收到數(shù)據(jù)包后,會根據(jù)目的 MAC 地址判斷這個包屬于哪一個虛擬網卡。這也就意味著,只要是從 Macvlan 子接口發(fā)來的數(shù)據(jù)包(或者是發(fā)往 Macvlan 子接口的數(shù)據(jù)包),物理網卡只接收數(shù)據(jù)包,不處理數(shù)據(jù)包,所以這就引出了一個問題:本機 Macvlan 網卡上面的 IP 無法和物理網卡上面的 IP 通信!關于這個問題的解決方案我們下一節(jié)再討論。
我們先來看一下 Macvlan 技術的流程示意圖:
簡單來說,Macvlan 虛擬網卡設備是寄生在物理網卡設備上的。發(fā)包時調用自己的發(fā)包函數(shù),查找到寄生的物理設備,然后通過物理設備發(fā)包。收包時,通過注冊寄生的物理設備的 rx_handler 回調函數(shù),處理數(shù)據(jù)包。
2. Macvlan vs Bridge
說到 Macvlan,就不得不提 Bridge,因為你可以把 Macvlan 看成一個簡單的 Bridge。但他們之間還是有很大的區(qū)別的。
Bridge
Bridge 實際上就是一種舊式交換機,他們之間并沒有很大的差別。Bridge 與交換機的區(qū)別在與市場,而不在與技術。交換機對網絡進行分段的方式與 Bridge 相同,交換機就是一個多端口的網橋。確切地說,高端口密度的 Bridge 就稱為局域網交換機。
Bridge 有以下特點:
- Bridge 是二層設備,僅用來處理二層的通訊。
- Bridge 使用 MAC 地址表來決定怎么轉發(fā)幀(Frame)。
- Bridge 會從 host 之間的通訊數(shù)據(jù)包中學習 MAC 地址。
- 可以是硬件設備,也可以是純軟件實現(xiàn)(例如:Linux Bridge)。
以下是一個在 Linux 主機上,多個 VM 使用 bridge 相互通訊的狀況:
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 有可能會遇到二層環(huán)路,如有需要,你可以開啟 STP 來防止出現(xiàn)環(huán)路。
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 的形式來命名以方便區(qū)別。
用張圖來解釋一下設定 Macvlan 后的樣子:
3. Macvlan 的工作模式
Macvlan 共支持四種模式,分別是:
VEPA(Virtual Ethernet Port Aggregator)
在 VEPA 模式下,所有從 Macvlan 接口發(fā)出的流量,不管目的地全部都發(fā)送給父接口,即使流量的目的地是共享同一個父接口的其它 Macvlan 接口。在二層網絡場景下,由于生成樹協(xié)議的原因,兩個 Macvlan 接口之間的通訊會被阻塞,這時需要上層路由器上為其添加路由(需要外部交換機配置 Hairpin 支持,即需要兼容 802.1Qbg 的交換機支持,其可以把源和目的地址都是本地 Macvlan 接口地址的流量發(fā)回給相應的接口)。此模式下從父接口收到的廣播包,會泛洪給 VEPA 模式的所有子接口。
現(xiàn)在大多數(shù)交換機都不支持 Hairpin 模式,但 Linux 主機中可以通過一種 Harpin 模式的 Bridge 來讓 VEPA 模式下的不同 Macvlan 接口通信(前文已經提到,Bridge 其實就是一種舊式交換機)。怎么配置呢?非常簡單,通過一條命令就可以解決:
- $ brctl hairpin br0 eth1 on
或者使用 iproute2 來設置:
- $ bridge link set dev eth0 hairpin on
如果你的內核是你手工編譯升級的,那么可能你的用戶態(tài)程序并不支持新內核對應的所有特性,也就是說你的 brctl 可能版本過老不支持 hairpin 命令,那么可以 sysfs 來搞定:
- $ echo 1 >/sys/class/net/br0/brif/eth1/hairpin_mode
在 Linux 主機上配置了 Harpin 模式之后,源和目的地址都是本地 Macvlan 接口地址的流量,都會被 br0(假設你創(chuàng)建的 Bridge 是 br0)發(fā)回給相應的接口。
如果想在物理交換機層面對虛擬機或容器之間的訪問流量進行優(yōu)化設定,VEPA 模式將是一種比較好的選擇。
VEPA 和 Passthru 模式下,兩個 Macvlan 接口之間的通信會經過主接口兩次:第一次是發(fā)出的時候,第二次是返回的時候。這樣會影響物理接口的寬帶,也限制了不同 Macvlan 接口之間通信的速度。如果多個 Macvlan 接口之間通信比較頻繁,對于性能的影響會比較明顯。
Bridge
此種模式類似 Linux 的 Bridge,擁有相同父接口的兩塊 Macvlan 虛擬網卡是可以直接通訊的,不需要把流量通過父網卡發(fā)送到外部網絡,廣播幀將會被泛洪到連接在"網橋"上的所有其他子接口和物理接口。這比較適用于讓共享同一個父接口的 Macvlan 網卡進行直接通訊的場景。
這里所謂的 Bridge 指的是在這些網卡之間,數(shù)據(jù)流可以實現(xiàn)直接轉發(fā),不需要外部的協(xié)助,這有點類似于 Linux host 內建了一個 Bridge,即用 brctl 命令所做的那一切。但和 Linux bridge 絕不是一回事,它不需要學習 MAC 地址,也不需要 STP,因此效能比起使用 Linux bridge 好上很多。
Bridge 模式有個缺點:如果父接口 down 掉,所有的 Macvlan 子接口也會全部 down 掉,同時子接口之間也將無法進行通訊。
Private
此種模式相當于 VEPA 模式的增強模式,其完全阻止共享同一父接口的 Macvlan 虛擬網卡之間的通訊,即使配置了 Hairpin 讓從父接口發(fā)出的流量返回到宿主機,相應的通訊流量依然被丟棄。具體實現(xiàn)方式是丟棄廣播/多播數(shù)據(jù),這就意味著以太網地址解析 arp 將不可運行,除非手工探測 MAC 地址,否則通信將無法在同一宿主機下的多個 Macvlan 網卡間展開。之所以隔離廣播流量,是因為以太網是基于廣播的,隔離了廣播,以太網將失去了依托。
Passthru
此種模式會直接把父接口和相應的MacVLAN接口捆綁在一起,這種模式每個父接口只能和一個 Macvlan 虛擬網卡接口進行捆綁,并且 Macvlan 虛擬網卡接口繼承父接口的 MAC 地址。
此種模式的優(yōu)點是虛擬機和容器可以更改 MAC 地址和其它一些接口參。
4. Macvlan 和 Bridge 的使用場景
最后我們再來討論一下 Macvlan 和 Bridge 的各自使用場景。
使用 Macvlan:
- 僅僅需要為虛擬機或容器提供訪問外部物理網絡的連接。
- Macvlan 占用較少的 CPU,同時提供較高的吞吐量。
- 當使用 Macvlan 時,宿主機無法和 VM 或容器直接進行通訊。
使用 Bridge:
- 當在同一臺宿主機上需要連接多個虛擬機或容器時。
- 對于擁有多個網橋的混合環(huán)境。
- 需要應用高級流量控制,F(xiàn)DB的維護。
5. Macvlan 的局限性
- Macvlan 是將 VM 或容器通過二層連接到物理網絡的近乎理想的方案,但它也有一些局限性:
- Linux 主機連接的交換機可能會限制同一個物理端口上的 MAC 地址數(shù)量。雖然你可以讓網絡管理員更改這些策略,但有時這種方法是無法實行的(比如你要去給客戶做一個快速的 PoC 演示)。
- 許多 NIC 也會對該物理網卡上的 MAC地址數(shù)量有限制。超過這個限制就會影響到系統(tǒng)的性能。
IEEE 802.11 不喜歡同一個客戶端上有多個 MAC 地址,這意味著你的 Macvlan 子接口在無線網卡或 AP 中都無法通信。可以通過復雜的辦法來突破這種限制,但還有一種更簡單的辦法,那就是使用 Ipvlan,感興趣可以自己查閱相關資料。
6. 總結
本文主要介紹了 Macvlan 的實現(xiàn)原理,比較了它和 Linux Bridge 模式之間的差異及其使用場景,還詳細剖析了 Macvlan 四種模式的工作原理和相關注意項。下一節(jié)我們將通過實際演練來模擬 Macvlan 的四種工作模式。
7. 參考資料
http://hicu.be/bridge-vs-macvlan
https://blog.csdn.net/ztguang/article/details/51854037
https://lists.linuxfoundation.org/pipermail/bridge/2009-November/006842.html
本文轉載自微信公眾號「 云原生實驗室」,轉載本文請聯(lián)系 云原生實驗室公眾號。