您好,登錄后才能下訂單哦!
在 Macvlan 出現之前,我們只能為一塊以太網卡添加多個 IP 地址,卻不能添加多個 MAC 地址,因為 MAC 地址正是通過其全球唯一性來標識一塊以太網卡的,即便你使用了創建 ethx:y 這樣的方式,你會發現所有這些“網卡”的 MAC 地址和 ethx 都是一樣的,本質上,它們還是一塊網卡,這將限制你做很多二層的操作。有了 Macvlan 技術,你可以這么做了。
Macvlan 允許你在主機的一個網絡接口上配置多個虛擬的網絡接口,這些網絡 interface 有自己獨立的 MAC 地址,也可以配置上 IP 地址進行通信。Macvlan 下的虛擬機或者容器網絡和主機在同一個網段中,共享同一個廣播域。Macvlan 和 Bridge 比較相似,但因為它省去了 Bridge 的存在,所以配置和調試起來比較簡單,而且效率也相對高。除此之外,Macvlan 自身也完美支持 VLAN。
同一 VLAN 間數據傳輸是通過二層互訪,即 MAC 地址實現的,不需要使用路由。不同 VLAN 的用戶單播默認不能直接通信,如果想要通信,還需要三層設備做路由,Macvlan 也是如此。用 Macvlan 技術虛擬出來的虛擬網卡,在邏輯上和物理網卡是對等的。物理網卡也就相當于一個交換機,記錄著對應的虛擬網卡和 MAC 地址,當物理網卡收到數據包后,會根據目的 MAC 地址判斷這個包屬于哪一個虛擬網卡。這也就意味著,只要是從 Macvlan 子接口發來的數據包(或者是發往 Macvlan 子接口的數據包),物理網卡只接收數據包,不處理數據包,所以這就引出了一個問題:本機 Macvlan 網卡上面的 IP 無法和物理網卡上面的 IP 通信!關于這個問題的解決方案我們下一節再討論。
簡單來說,Macvlan 虛擬網卡設備是寄生在物理網卡設備上的。發包時調用自己的發包函數,查找到寄生的物理設備,然后通過物理設備發包。收包時,通過注冊寄生的物理設備的 rx_handler 回調函數,處理數據包。
macvlan 就如它的名字一樣,是一種網卡虛擬化技術,它能夠將一個物理網卡虛擬出多個接口,每個接口都可以配置 MAC 地址,同樣每個接口也可以配自己的 IP,每個接口就像交換機的端口一樣,可以為它劃分 VLAN。
macvlan 的做法其實就是將這些虛擬出來的接口與 Docker 容器直連來達到通信的目的。一個 macvlan 網絡對應一個接口,不同的 macvlan 網絡分配不同的子網,因此,相同的 macvlan 之間可以互相通信,不同的 macvlan 網絡之間在二層上不能通信,需要借助三層的路由器才能完成通信,如下,顯示的就是兩個不同的 macvlan 網絡之間的通信流程。
我們用一個 Linux 主機,通過配置其路由表和 iptables,將其配成一個路由器(當然是虛擬的),就可以完成不同 macvlan 網絡之間的數據交換,當然用物理路由器也是沒毛病的。
1.可讓使用者在同一張實體網卡上設定多個 MAC 地址。
2.承上,帶有上述設定的 MAC 地址的網卡稱為子接口(sub interface);而實體網卡則稱為父接口(parent interface)。
3.parent interface 可以是一個物理接口(eth0),可以是一個 802.1q 的子接口(eth0.10),也可以是 bonding 接口。
4.可在 parent/sub interface 上設定的不只是 MAC 地址,IP 地址同樣也可以被設定。
5.sub interface 無法直接與 parent interface 通訊 (帶有 sub interface 的 VM 或容器無法與 host 直接通訊)。
承上,若 VM 或容器需要與 host 通訊,那就必須額外建立一個 sub 6.interface 給 host 用。
7.sub interface 通常以 mac0@eth0 的形式來命名以方便區別。
用張圖來解釋一下設定 Macvlan 后的樣子:
docker01 | docker02 |
---|---|
192.168.1.11 | 192.168.1.13 |
關閉防火墻和禁用selinux,更改主機名
[root@localhost ~]# hostnamectl set-hostname docker01
[root@localhost ~]# su -
上一次登錄:二 12月 17 08:20:36 CST 2019從 192.168.1.1pts/0 上
[root@docker01 ~]# systemctl stop firealld
Failed to stop firealld.service: Unit firealld.service not loaded.
[root@docker01 ~]# setenforce 0
setenforce: SELinux is disabled
[root@docker01 ~]# systemctl daemon-reload
[root@docker01 ~]# systemctl restart docker
1) 打開網卡的混雜模式
//需要在docker01和docker02_上都進行操作。
[root@docker01 ~]# ip link show ens33
//查看網卡模式
[root@docker01 ~]# ip link set ens33 promisc on
//創建網卡模式為混雜模式
[root@docker01 ~]# ip link show ens33
//查看網卡模式
2)在docker01.上創建macvlan網絡
[root@docker01 ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o parent=ens33 mac_net1
// 創建一個macvlan模式的網絡
-o parent=綁定在哪張網卡之上
[root@docker01 ~]# docker network ls
//查看網卡信息
3)基于創建的macvlan網絡運行一個容器
[root@docker01 ~]# docker run -itd --name bbox1 --ip 172.22.16.10 --network mac_net1 busybox
4)在docker02.上創建macvlan網絡(要和docker01的macvlan一模一樣)
[root@docker02 ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o parent=ens33 mac_net1
[root@docker02 ~]# docker network ls
5)在docker02. 上,基于創建的macvlan網絡運行一個容器,驗證與docker01.上容器的通信。
[root@docker02 ~]# docker run -itd --name bbox2 --network mac_net1 --ip 172.22.16.20 busybox
//基于busybox創建一個容器
[root@docker02 ~]# docker exec -it bbox2 /bin/sh
//進入bbox2容器
/ # ping 172.22.16.10
//ping一下docker01的主機
1) docker01和docker02驗證內核模塊8021q封裝
macvlan需要解決的問題:基于真實的ens33網卡,生產新的虛擬網卡。
[root@docker01 ~]# modinfo 8021q
//驗證內核模塊8021q封裝
[root@docker01 ~]# modprobe 8021q
//如果內核模塊沒有開啟,運行上邊的命令導入一下
2)docker01基于ens33創建虛擬網卡
修改ens33網卡配置文件
[root@docker01 ~]# cd /etc/sysconfig/network-scripts/
[root@docker01 network-scripts]# vim ifcfg-ens33
手動添加虛擬網卡配置文件
[root@docker01 ~]# cd /etc/sysconfig/network-scripts/
[root@docker01 network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10
//-p保留源文件或目錄的屬性
[root@docker01 network-scripts]# vim ifcfg-ens33.10
//修改ens33.10網卡配置文件
BOOTPROTO=none
NAME=ens33.10
DEVICE=ens33.10
ONBOOT=yes
IPADDR=192.168.10.10
PREFIX=24
GATEWAY=192.168.10.2
VLAN=yes
這里注意,IP要和ens33網段做一個區分, 保證網關和網段IP的一致性,設備名稱和配置文件的-致性,并且打開VLAN支持模式。
創建第二個虛擬網卡配置文件
[root@docker01 network-scripts]# cp -p ifcfg-ens33.10 ifcfg-ens33.20
[root@docker01 network-scripts]# vim ifcfg-ens33.20
//修改ens33.20網卡配置文件
BOOTPROTO=none
NAME=ens33.20
DEVICE=ens33.20
ONBOOT=yes
IPADDR=192.168.20.20
PREFIX=24
GATEWAY=192.168.20.2
VLAN=yes
docker01上的操作,啟用創建的虛擬網卡:
[root@docker01 network-scripts]# ifup ifcfg-ens33.10
[root@docker01 network-scripts]# ifup ifcfg-ens33.20
[root@docker01 network-scripts]# ifconfig
//查看IP
3)docker02基于ens33創建虛擬網卡
修改ens33網卡配置文件
[root@docker02 ~]# cd /etc/sysconfig/network-scripts/
[root@docker02 network-scripts]# vim ifcfg-ens33
手動添加虛擬網卡配置文件
[root@docker02 ~]# cd /etc/sysconfig/network-scripts/
[root@docker02 network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10
//-p保留源文件或目錄的屬性
[root@docker02 network-scripts]# vim ifcfg-ens33.10
//修改ens33.10網卡配置文件
BOOTPROTO=none
NAME=ens33.10
DEVICE=ens33.10
ONBOOT=yes
IPADDR=192.168.10.11
PREFIX=24
GATEWAY=192.168.10.2
VLAN=yes
這里注意,IP要和ens33網段做一個區分, 保證網關和網段IP的一致性,設備名稱和配置文件的-致性,并且打開VLAN支持模式。
創建第二個虛擬網卡配置文件
[root@docker02 network-scripts]# cp -p ifcfg-ens33.10 ifcfg-ens33.20
[root@docker02 network-scripts]# vim ifcfg-ens33.20
//修改ens33.20網卡配置文件
BOOTPROTO=none
NAME=ens33.20
DEVICE=ens33.20
ONBOOT=yes
IPADDR=192.168.20.21
PREFIX=24
GATEWAY=192.168.20.2
VLAN=yes
docker02上的操作,啟用創建的虛擬網卡:
[root@docker02 network-scripts]# systemctl restart network
[root@docker02 network-scripts]# ifup ifcfg-ens33.10
[root@docker02 network-scripts]# ifup ifcfg-ens33.20
[root@docker02 network-scripts]# ifconfig
//查看IP
4)docekr01和docker02基于虛擬網卡,創建macvlan網絡
[root@docker02 network-scripts]# docker network create -d macvlan --subnet 172.16.10.0/24 --gateway 172.16.10.1 -o parent=ens33.10 mac_net10
//創建一個新的網卡基于ens33.10
[root@docker02 network-scripts]# docker network create -d macvlan --subnet 172.16.20.0/24 --gateway 172.16.20.1 -o parent=ens33.20 mac_net20
//創建一個新的網卡基于ens33.20
5)Docker01部署一個私有倉庫
Docker01
72 docker pull registry
//下載registry鏡像
73 docker run -itd --name registry -p 5000:5000 --restart=always registry:latest
//基于registry鏡像,啟動一臺容器
76 docker tag busybox:latest 192.168.1.11:5000/busybox:v1
//把容器重命名一個標簽
77 docker ps
78 vim /usr/lib/systemd/system/docker.service #13行修改
ExecStart=/usr/bin/dockerd --insecure-registry 192.168.1.11:5000
80 systemctl daemon-reload
81 systemctl restart docker.service
//重啟docker
100 docker push 192.168.1.11:5000/busybox:v1
//上傳容器到私有倉庫
101 docker images
Docker02
78 vim /usr/lib/systemd/system/docker.service #13行修改
ExecStart=/usr/bin/dockerd --insecure-registry 192.168.1.11:5000
80 systemctl daemon-reload
81 systemctl restart docker.service
//重啟docker
99 docker pull 192.168.1.11/busybox:v1
//下載剛剛上傳的鏡像
6)docker01和docker02基于busybox:v1鏡像和網卡mac_net10,mac_net20,創建容器。
Docker01
[root@docker01 ~]# docker run -itd --name bbox10 --network mac_net10 --ip 172.16.10.10 192.168.1.11:5000/busybox:v1
[root@docker01 ~]# docker run -itd --name bbox20 --network mac_net20 --ip 172.16.20.20 192.168.1.11:5000/busybox:v1
**Docker02**
[root@docker02 ~]# docker run -itd --name bbox10 --network mac_net10 --ip 172.16.10.10 192.168.1.11:5000/busybox:v1
[root@docker02 ~]# docker run -itd --name bbox20 --network mac_net20 --ip 172.16.20.20 192.168.1.11:5000/busybox:v1
***這里只需注意,我們在這里的操作跟在docker01和上面的操作是一模一樣的,操作順序大致為:
驗證8021q內核封裝
基于ens33網卡創建新的虛擬網卡,ens33.10和ens33.20 (注意和docker01. 上的ens33.10和ens33.20必須是在同一-網段,且IP不能沖突)基于此網絡運行容器。(注意和docker01 上的容器,都是基于剛剛創建的macvlan網絡,但IP地址不能沖突)
7)驗證
在docker01.上進入容器bbox10和docker02.上的bbox11進行通信。
在docker01.上進入容器bbox20和docker02.上的bbox21進行通信。
注意: VMware的網絡必須設置為Bridge模式。
現在把docker01和docker02的網絡模式設置為橋接模式
測試一下相同網卡的主機是否能ping通
[root@docker01 ~]# docker exec -it bbox10 /bin/sh
/ # ping 172.16.20.20
[root@docker02 ~]# docker exec -it bbox20 /bin/sh
/ # ping 172.16.20.20
Macvlan 是將 VM 或容器通過二層連接到物理網絡的近乎理想的方案,但它也有一些局限性:
1.Linux 主機連接的交換機可能會限制同一個物理端口上的 MAC 地址數量。雖然你可以讓網絡管理員更改這些策略,但有時這種方法是無法實行的(比如你要去給客戶做一個快速的 PoC 演示)。
2.許多 NIC 也會對該物理網卡上的 MAC地址數量有限制。超過這個限制就會影響到系統的性能。
3.IEEE 802.11 不喜歡同一個客戶端上有多個 MAC 地址,這意味著你的 Macvlan 子接口在無線網卡或 AP 中都無法通信。可以通過復雜的辦法來突破這種限制,但還有一種更簡單的辦法,那就是使用 Ipvlan,感興趣可以自己查閱相關資料。
macvlan是一種網卡虛擬化技術,能夠將一張網卡虛擬出多張網卡。
macvlan的特定通信模式,常用模式是bridge。
在Docker中,macvlan只支持bridge模式。
相同的macvlan可以通信,不同的macvlan二層無法通信,可以通過三層路由完成通信。
思考一下:
macvlan bridge和bridge的異同點
還有一種類似的技術,多張虛擬網卡共享相同MAC地址,但有獨立的IP地址,這是什么技術?
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。