原文連接:Linux 虛擬網卡技術:Macvlanhtml
在 Macvlan 出現以前,咱們只能爲一塊以太網卡添加多個 IP 地址,卻不能添加多個 MAC 地址,由於 MAC 地址正是經過其全球惟一性來標識一塊以太網卡的,即使你使用了建立 ethx:y
這樣的方式,你會發現全部這些「網卡」的 MAC 地址和 ethx 都是同樣的,本質上,它們仍是一塊網卡,這將限制你作不少二層的操做。有了 Macvlan
技術,你能夠這麼作了。linux
Macvlan 容許你在主機的一個網絡接口上配置多個虛擬的網絡接口,這些網絡 interface
有本身獨立的 MAC 地址,也能夠配置上 IP 地址進行通訊。Macvlan 下的虛擬機或者容器網絡和主機在同一個網段中,共享同一個廣播域。Macvlan 和 Bridge
比較類似,但由於它省去了 Bridge 的存在,因此配置和調試起來比較簡單,並且效率也相對高。除此以外,Macvlan 自身也完美支持 VLAN
。web
同一 VLAN 間數據傳輸是經過二層互訪,即 MAC 地址實現的,不須要使用路由。不一樣 VLAN 的用戶單播默認不能直接通訊,若是想要通訊,還須要三層設備作路由,Macvlan 也是如此。用 Macvlan 技術虛擬出來的虛擬網卡,在邏輯上和物理網卡是對等的。物理網卡也就至關於一個交換機,記錄着對應的虛擬網卡和 MAC 地址,當物理網卡收到數據包後,會根據目的 MAC 地址判斷這個包屬於哪個虛擬網卡。**這也就意味着,只要是從 Macvlan 子接口發來的數據包(或者是發往 Macvlan 子接口的數據包),物理網卡只接收數據包,不處理數據包,因此這就引出了一個問題:本機 Macvlan 網卡上面的 IP 沒法和物理網卡上面的 IP 通訊!**關於這個問題的解決方案咱們下一節再討論。bash
咱們先來看一下 Macvlan 技術的流程示意圖:markdown
簡單來講,Macvlan 虛擬網卡設備是寄生在物理網卡設備上的。發包時調用本身的發包函數,查找到寄生的物理設備,而後經過物理設備發包。收包時,經過註冊寄生的物理設備的 rx_handler
回調函數,處理數據包。網絡
說到 Macvlan,就不得不提 Bridge
,由於你能夠把 Macvlan 當作一個簡單的 Bridge。但他們之間仍是有很大的區別的。less
Bridge 實際上就是一種舊式交換機,他們之間並無很大的差異。Bridge 與交換機的區別在與市場,而不在與技術。交換機對網絡進行分段的方式與 Bridge 相同,交換機就是一個多端口的網橋。確切地說,高端口密度的 Bridge 就稱爲局域網交換機。ide
Bridge 有如下特色:函數
Frame
)。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 有可能會遇到二層環路,若有須要,你能夠開啓 STP 來防止出現環路。
Macvlan 有如下特色:
sub interface
);而實體網卡則稱爲父接口(parent interface
)。parent interface
能夠是一個物理接口(eth0),能夠是一個 802.1q 的子接口(eth0.10),也能夠是 bonding
接口。sub interface
沒法直接與 parent interface
通信 (帶有 sub interface 的 VM 或容器沒法與 host 直接通信)。sub interface
給 host 用。mac0@eth0
的形式來命名以方便區別。用張圖來解釋一下設定 Macvlan 後的樣子:
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)發回給相應的接口。
若是想在物理交換機層面對虛擬機或容器之間的訪問流量進行優化設定,VEPA 模式將是一種比較好的選擇。
VEPA
和Passthru
模式下,兩個 Macvlan 接口之間的通訊會通過主接口兩次:第一次是發出的時候,第二次是返回的時候。這樣會影響物理接口的寬帶,也限制了不一樣 Macvlan 接口之間通訊的速度。若是多個 Macvlan 接口之間通訊比較頻繁,對於性能的影響會比較明顯。
此種模式相似 Linux 的 Bridge,擁有相同父接口的兩塊 Macvlan 虛擬網卡是能夠直接通信的,不須要把流量經過父網卡發送到外部網絡,廣播幀將會被泛洪到鏈接在"網橋"上的全部其餘子接口和物理接口。這比較適用於讓共享同一個父接口的 Macvlan 網卡進行直接通信的場景。
這裏所謂的 Bridge 指的是在這些網卡之間,數據流能夠實現直接轉發,不須要外部的協助,這有點相似於 Linux host 內建了一個 Bridge,即用 brctl 命令所作的那一切。但和 Linux bridge 毫不是一回事,它不須要學習 MAC 地址,也不須要 STP
,所以效能比起使用 Linux bridge 好上不少。
Bridge 模式有個缺點:若是父接口 down 掉,全部的 Macvlan 子接口也會所有 down 掉,同時子接口之間也將沒法進行通信。
此種模式至關於 VEPA
模式的加強模式,其徹底阻止共享同一父接口的 Macvlan 虛擬網卡之間的通信,即便配置了 Hairpin
讓從父接口發出的流量返回到宿主機,相應的通信流量依然被丟棄。具體實現方式是丟棄廣播/多播數據,這就意味着以太網地址解析 arp
將不可運行,除非手工探測 MAC 地址,不然通訊將沒法在同一宿主機下的多個 Macvlan 網卡間展開。之因此隔離廣播流量,是由於以太網是基於廣播的,隔離了廣播,以太網將失去了依託。
此種模式會直接把父接口和相應的MacVLAN接口捆綁在一塊兒,這種模式每一個父接口只能和一個 Macvlan 虛擬網卡接口進行捆綁,而且 Macvlan 虛擬網卡接口繼承父接口的 MAC 地址。
此種模式的優勢是虛擬機和容器能夠更改 MAC 地址和其它一些接口參。
最後咱們再來討論一下 Macvlan 和 Bridge 的各自使用場景。
使用 Macvlan:
使用 Bridge:
Macvlan 是將 VM 或容器經過二層鏈接到物理網絡的近乎理想的方案,但它也有一些侷限性:
Ipvlan
,感興趣能夠本身查閱相關資料。本文主要介紹了 Macvlan 的實現原理,比較了它和 Linux Bridge 模式之間的差別及其使用場景,還詳細剖析了 Macvlan 四種模式的工做原理和相關注意項。下一節咱們將經過實際演練來模擬 Macvlan 的四種工做模式。