網卡也能虛擬化?網卡虛擬化技術 macvlan 詳解

本文首發於個人公衆號 Linux雲計算網絡(id: cloud_dev),專一於乾貨分享,號內有 10T 書籍和視頻資源,後臺回覆「1024」便可領取,歡迎你們關注,二維碼文末能夠掃。docker

01 macvlan 簡介

前面的文章講過了幾種 Linux 虛擬網絡設備:tap/tun、veth-pair、bridge,它們本質上是 Linux 系統 提供的網絡虛擬化解決方案,今天要講的 macvlan 也是其中的一種,準確說這是一種網卡虛擬化的解決方案。由於 macvlan 這種技術能將 一塊物理網卡虛擬成多塊虛擬網卡 ,至關於物理網卡施展了 多重影分身之術 ,由一個變多個。編程

02 macvlan 的工做原理

macvlan 是 Linux kernel 支持的新特性,支持的版本有 v3.9-3.19 和 4.0+,比較穩定的版本推薦 4.0+。它通常是之內核模塊的形式存在,咱們能夠經過如下方法判斷當前系統是否支持:ubuntu

# modprobe macvlan
# lsmod | grep macvlan
macvlan                24576  0

若是第一個命令報錯,或者第二個命令沒有返回,說明當前系統不支持 macvlan,須要升級內核。網絡

macvlan 這種技術聽起來有點像 VLAN,但它們的實現機制是徹底不同的。macvlan 子接口和原來的主接口是徹底獨立的,能夠單獨配置 MAC 地址和 IP 地址,而 VLAN 子接口和主接口共用相同的 MAC 地址。VLAN 用來劃分廣播域,而 macvlan 共享同一個廣播域。工具

經過不一樣的子接口,macvlan 也能作到流量的隔離。macvlan 會根據收到包的目的 MAC 地址判斷這個包須要交給哪一個虛擬網卡,虛擬網卡再把包交給上層的協議棧處理。學習

03 四種模式

根據 macvlan 子接口之間的通訊模式,macvlan 有四種網絡模式:測試

  • private 模式
  • vepa(virtual ethernet port aggregator) 模式
  • bridge 模式
  • passthru 模式

默認使用的是 vepa 模式。雲計算

3.1 private

這種模式下,同一主接口下的子接口之間彼此隔離,不能通訊。即便從外部的物理交換機導流,也會被無情地丟掉。spa

3.2 vepa

這種模式下,子接口之間的通訊流量須要導到外部支持 802.1Qbg/VPEA 功能的交換機上(能夠是物理的或者虛擬的),經由外部交換機轉發,再繞回來。3d

注:802.1Qbg/VPEA 功能簡單說就是交換機要支持 髮夾(hairpin) 功能,也就是數據包從一個接口上收上來以後還能再扔回去。

3.3 bridge

這種模式下,模擬的是 Linux bridge 的功能,但比 bridge 要好的一點是每一個接口的 MAC 地址是已知的,不用學習。因此,這種模式下,子接口之間就是直接能夠通訊的。

3.4 passthru

這種模式,只容許單個子接口鏈接主接口,且必須設置成混雜模式,通常用於子接口橋接和建立 VLAN 子接口的場景。

3.5 mactap

和 macvlan 類似的技術還有一種是 mactap。和 macvlan 不一樣的是,mactap 收到包以後不是交給協議棧,而是交給一個 tapX 文件,而後經過這個文件,完成和用戶態的直接通訊。

04 實踐

在 Linux 系統下,建立 macvlan 的命令形式以下:

ip link add link DEVICE name NAME type { macvlan | macvtap } mode { private | vepa | bridge |
              passthru  [ nopromisc ] }

一般,單獨使用 macvlan 毫無心義,通常都是結合 VM 和容器來構建網絡。下面咱們就簡單使用 namespace 來看看 Linux 是怎麼使用 macvlan 的。

實驗拓撲以下:

在個人系統中,以接口 enp0s8 爲例建立兩個 macvlan 子接口(使用 bridge 模式),配置 IP 並將其掛到兩個 namespace 中,測試連通性。

# 建立兩個 macvlan 子接口
ip link add link enp0s8 dev mac1 type macvlan mode bridge
ip link add link enp0s8 dev mac2 type macvlan mode bridge

# 建立兩個 namespace
ip netns add ns1
ip netns add ns2

# 將兩個子接口分別掛到兩個 namespace 中
ip link set mac1 netns ns1
ip link set mac2 netns ns2

# 配置 IP 並啓用
ip netns exec ns1 ip a a 192.168.56.122/24 dev mac1
ip netns exec ns1 ip l s mac1 up

ip netns exec ns1 ip a a 192.168.56.123/24 dev mac2
ip netns exec ns2 ip l s mac2 up

注:enp0s8 的 IP 是 192.168.56.110/24,配置的子接口 IP 也必須是同一網段的。

完了兩個子接口 ping 一下:

root@ubuntu:~# ip netns exec ns1 ip a show mac1
9: mac1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1
    link/ether 2e:6e:d9:08:c5:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.56.122/24 scope global mac1
       valid_lft forever preferred_lft forever
    inet6 fe80::2c6e:d9ff:fe08:c505/64 scope link 
       valid_lft forever preferred_lft forever
root@ubuntu:~# ip netns exec ns1 ping 192.168.56.123
PING 192.168.56.123 (192.168.56.123) 56(84) bytes of data.
64 bytes from 192.168.56.123: icmp_seq=1 ttl=64 time=0.052 ms
64 bytes from 192.168.56.123: icmp_seq=2 ttl=64 time=0.028 ms
^C
--- 192.168.56.123 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.028/0.040/0.052/0.012 ms

能夠看到,可以 ping 通,若是把上面的 mode 換成其餘模式就行不通了,這個就留給你們去實驗了(默認是 vepa 模式)。

另外,在 docker 中,macvlan 是一種較爲重要的跨主機網絡模型,這塊的內容就留做下篇文章再作講解了。

05 總結

macvlan 是一種網卡虛擬化技術,可以將一張網卡虛擬出多張網卡。

macvlan 的四種通訊模式,經常使用模式是 bridge。

思考一下:

  1. macvlan bridge 和 bridge 的異同點
  2. 還有一種相似的技術,多張虛擬網卡共享相同 MAC 地址,但有獨立的 IP 地址,這是什麼技術?

這兩個問題你們能夠留言互動一下。


個人公衆號 「Linux雲計算網絡」(id: cloud_dev) ,號內有 10T 書籍和視頻資源,後臺回覆 「1024」 便可領取,分享的內容包括但不限於 Linux、網絡、雲計算虛擬化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++編程技術等內容,歡迎你們關注。

相關文章
相關標籤/搜索