1. 介紹
macvlan 本身是 linxu kernel 模塊蔬浙,其功能是允許在同一個物理網(wǎng)卡上配置多個 MAC 地址猪落,即多個 interface,每個 interface 可以配置自己的 IP敛滋。**macvlan 本質(zhì)上是一種網(wǎng)卡虛擬化技術(shù)(最大優(yōu)點(diǎn)是性能極好)**
可以在linux命令行執(zhí)行`lsmod | grep macvlan` 查看當(dāng)前內(nèi)核是否加載了該driver许布;如果沒有查看到,可以通過`modprobe macvlan`來載入绎晃,然后重新查看蜜唾。內(nèi)核代碼路徑/drivers/net/macvlan.c
Macvlan 允許你在主機(jī)的一個網(wǎng)絡(luò)接口上配置多個虛擬的網(wǎng)絡(luò)接口杂曲,這些網(wǎng)絡(luò) `interface` 有自己獨(dú)立的 MAC 地址,也可以配置上 IP 地址進(jìn)行通信袁余。Macvlan 下的虛擬機(jī)或者容器網(wǎng)絡(luò)和主機(jī)在同一個網(wǎng)段中擎勘,共享同一個廣播域。Macvlan 和 `Bridge` 比較相似颖榜,但因?yàn)樗∪チ?Bridge 的存在棚饵,所以配置和調(diào)試起來比較簡單,而且效率也相對高掩完。除此之外噪漾,Macvlan 自身也完美支持 `VLAN`。
2. 工作模式(Bridge VS MACVlan)
2.1 Bridge Mode
Bridge 是二層設(shè)備且蓬,僅用來處理二層的通訊欣硼。
Bridge 使用 MAC 地址表來決定怎么轉(zhuǎn)發(fā)幀(
Frame
)。Bridge 會從 host 之間的通訊數(shù)據(jù)包中學(xué)習(xí) MAC 地址恶阴。
可以是硬件設(shè)備诈胜,也可以是純軟件實(shí)現(xiàn)(例如:
Linux Bridge
)。
提示:
Bridge 有可能會遇到二層環(huán)路冯事,如有需要焦匈,可以開啟 STP 來防止出現(xiàn)環(huán)路。
2.2 MACVlan Mode
可讓使用者在同一張實(shí)體網(wǎng)卡上設(shè)定多個 MAC 地址昵仅。
上述設(shè)定的 MAC 地址的網(wǎng)卡稱為子接口(
sub interface
)缓熟;而實(shí)體網(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ū)別晚伙。
2.3 MACVlan模式
Bridge:屬于同一個parent接口的macvlan接口之間掛到同一個bridge上吮龄,可以二層互通(macvlan接口都無法與parent 接口互通)。
VPEA(Virtual Ethernet Port Aggregator):所有接口的流量都需要到外部switch才能夠到達(dá)其他接口咆疗。
Private:接口只接受發(fā)送給自己MAC地址的報文漓帚。
Passthru: 父接口和相應(yīng)的MacVLAN接口捆綁在一起,這種模式每個父接口只能和一個 Macvlan 虛擬網(wǎng)卡接口進(jìn)行捆綁午磁,并且 Macvlan 虛擬網(wǎng)卡接口繼承父接口的 MAC 地址尝抖。
前三種模式示意圖:
實(shí)驗(yàn)
Bridge Mode:創(chuàng)建了兩個macvlan接口毡们,分別放到兩個netns中;然后驗(yàn)證這兩個macvlan口之間客戶互通昧辽。
設(shè)置網(wǎng)卡混雜模式(PROMISC網(wǎng)卡混雜標(biāo)志):
[root@localhost ~]#ifconfig ens224 promisc
[root@localhost ~]# ifconfig ens224
ens224: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST> mtu 1500
………………
創(chuàng)建兩個macvlan接口衙熔,其parent接口都是ens224
[root@localhost ~]# ip link add link ens224 name macv1 type macvlan mode bridge
[root@localhost ~]# ip link add link ens224 name macv2 type macvlan mode bridge
查看接口狀態(tài):
創(chuàng)建namespace
[root@localhost ~]# ip netns add net1
[root@localhost ~]# ip netns add net2
將macvlan接口插入到namespace
[root@localhost ~]# ip link set macv1 netns net1
[root@localhost ~]# ip link set macv2 netns net2
設(shè)置網(wǎng)卡IP,設(shè)置網(wǎng)卡UP狀態(tài)
ip netns exec net1 ip addr add 52.1.1.151/24 dev macv1
ip netns exec net2 ip addr add 52.1.1.152/24 dev macv2
設(shè)置網(wǎng)卡IP,設(shè)置網(wǎng)卡UP狀態(tài)
[root@localhost ~]#ip netns exec net1 ip addr add 52.1.1.151/24 dev macv1
[root@localhost ~]#ip netns exec net2 ip addr add 52.1.1.152/24 dev macv2
[root@localhost ~]#ip netns exec net1 ip link set macv1 up
[root@localhost ~]#ip netns exec net2 ip link set macv2 up
查看網(wǎng)卡狀態(tài)
[root@localhost ~]# ip netns exec net1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: macv1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether 4e:a1:51:a9:3f:ef brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 52.1.1.151/24 scope global eth0
valid_lft forever preferred_lft forever
[root@localhost ~]# ip netns exec net2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
5: macv2@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether fe:b5:85:c1:77:c1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 52.1.1.152/24 scope global macv2
valid_lft forever preferred_lft forever
ping測試結(jié)果:
net1和net2無法ping通宿主機(jī),ping自己也不通.2個容器互相ping沒有問題
更改容器內(nèi)網(wǎng)卡名字
ip netns exec net1 ip link set mac1 name eth0
2.4 ipvlan
IPVlan 和 macvlan 類似,都是從一個主機(jī)接口虛擬出多個虛擬網(wǎng)絡(luò)接口搅荞。一個重要的區(qū)別就是所有的虛擬接口都有相同的 macv 地址红氯,而擁有不同的 ip 地址。因?yàn)樗械奶摂M接口要共享 mac 地址咕痛,所有有些需要注意的地方:
- DHCP 協(xié)議分配 ip 的時候一般會用 mac 地址作為機(jī)器的標(biāo)識痢甘。這個情況下,客戶端動態(tài)獲取 ip 的時候需要配置唯一的 ClientID 字段茉贡,并且 DHCP server 也要正確配置使用該字段作為機(jī)器標(biāo)識塞栅,而不是使用 mac 地址
Ipvlan 是 linux kernel 比較新的特性,linux kernel 3.19 開始支持 ipvlan块仆,但是比較穩(wěn)定推薦的版本是 >=4.2(因?yàn)?docker 對之前版本的支持有 bug),具體代碼見內(nèi)核目錄:
/drivers/net/ipvlan/
2.5 ipvlan模式
L2:
ipvlan L2 模式和 macvlan bridge 模式工作原理很相似构蹬,父接口作為交換機(jī)來轉(zhuǎn)發(fā)子接口的數(shù)據(jù)。同一個網(wǎng)絡(luò)的子接口可以通過父接口來轉(zhuǎn)發(fā)數(shù)據(jù)悔据,而如果想發(fā)送到其他網(wǎng)絡(luò)庄敛,報文則會通過父接口的路由轉(zhuǎn)發(fā)出去。
L3:
ipvlan 有點(diǎn)像路由器的功能科汗,它在各個虛擬網(wǎng)絡(luò)和主機(jī)網(wǎng)絡(luò)之間進(jìn)行不同網(wǎng)絡(luò)報文的路由轉(zhuǎn)發(fā)工作藻烤。只要父接口相同,即使虛擬機(jī)/容器不在同一個網(wǎng)絡(luò)头滔,也可以互相 ping 通對方怖亭,因?yàn)?ipvlan 會在中間做報文的轉(zhuǎn)發(fā)工作。
模式架構(gòu)圖:
實(shí)驗(yàn)
創(chuàng)建IPVlan L3模式
[root@localhost ~]#ip link add link ens224 ipvlan1 type ipvlan mode l3
[root@localhost ~]#ip link add link ens224 ipvlan2 type ipvlan mode l3
注意看ipvlan1 和ipvlan2 的MAC地址跟ens224的一樣
[root@localhost ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 00:0c:29:05:18:ac brd ff:ff:ff:ff:ff:ff
3: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 00:0c:29:05:18:b6 brd ff:ff:ff:ff:ff:ff
4: ipvlan1@enp0s3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 00:0c:29:05:18:b6 brd ff:ff:ff:ff:ff:ff
5: ipvlan2@enp0s3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 00:0c:29:05:18:b6 brd ff:ff:ff:ff:ff:ff
創(chuàng)建ns綁定接口
[root@localhost ~]#ip net add net-1
[root@localhost ~]#ip net add net-2
[root@localhost ~]#ip link set ipvlan1 netns net-1
[root@localhost ~]#ip link set ipvlan2 netns net-2
配置IP
[root@localhost ~]#ip net exec net-1 ip addr add 10.0.2.18/24 dev ipvlan1
[root@localhost ~]#ip net exec net-2 ip addr add 10.0.3.19/24 dev ipvlan2
[root@localhost ~]#ip net exec net-1 ip link set ipvlan1 up
[root@localhost ~]#ip net exec net-2 ip link set ipvlan2 up
增加路由
[root@localhost ~]#ip net exec net-1 route add default dev ipvlan1
[root@localhost ~]#ip net exec net-2 route add default dev ipvlan2
ping測試
2個ns可以正忱ぜ欤互相ping通,無法ping通宿主機(jī)IP
抓取ARP報文兴猩,結(jié)果無法在L3模式中抓到ARP,說明二層廣播和組播都不處理早歇,工作在L3.(這就是和L2模式的區(qū)別)
[root@localhost ~]#ip net exec net-1 tcpdump -ni ipvlan1 -p arp
創(chuàng)建L2模式倾芝,其余操作跟L3一樣
ip link add link enp0s3 ipvlan1 type ipvlan mode l2
ip link add link enp0s3 ipvlan2 type ipvlan mode l2
區(qū)別在于L2可以在2個ns中抓取到ARP報文
總結(jié):
ipvlan L3模式中外部網(wǎng)絡(luò)默認(rèn)情況下是不知道 ipvlan 虛擬出來的網(wǎng)絡(luò)的,如果不在外部路由器上配置好對應(yīng)的路由規(guī)則箭跳,ipvlan 的網(wǎng)絡(luò)是不能被外部直接訪問的晨另。