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