除了ovrlay,docker還開發了另一個支持跨主機容器的driver:macvlan
macvlan本身是linu kernel模塊,其功能是允許在同一物理網卡上配置多了MAC地址,即:多個interface,每個interface可以配置自己的ip。macvlan本身是一種網卡虛擬化技術,Docker用macvlan實現容器網絡就不奇怪了
macvlan最大的優點是性能極好,相比其他方案,macvlan不需要創建Linux bridge,而是直接通過以太interface連接到物理網絡。
准備實驗環境:
我們會使用docker1和docker2上單獨的網卡ens192和ens160創建macvlan。為保證多個MAC地址網絡包都可以從ens190或者ens160通過,我們需要打開網卡的混雜模式
因為docker1號docker2是虛擬機,所以在網卡配置選項中設置混雜模式(注:我使用的是esxi的虛擬機,沒有做這一步也可以)
當前試驗環境如下:盜圖
創建macvlan網絡
docker network create -d macvlan --subnet 192.168.2.1/24 --gateway 192.168.2.1 -o parent=ens160 macnet1
注:macvlan網絡是local網絡,為了保證跨主機能夠通信,用戶需要自己管理IP subnet
與其他網絡不同,docker 不會為macvlan網絡創建網關,這里的網關應該是真實存在的,否則路由無法通
-o parent指定使用的網絡interface
在docker2中也要執行相同的命令:docker network create -d macvlan --subnet 192.168.2.1/24 --gateway 192.168.2.1 -o parent=ens160 macnet1
在docker1中運行容器
docker network create -d macvlan --subnet 192.168.2.1/24 --gateway 192.168.2.1 -o parent=ens160 macnet1
在docker2中執行同樣的操作:
驗證docker1上的mac1與docker2上的mac2的連通性
兩個不同主機之間的容器可以相互ping通,但是不能解析容器的主機名,可見docker沒有為macvlan提供dns服務,這點與overlay是不同的
注:macvlan是物理中實實在在存在的網絡,macvlan實際就是我們常用的網卡的子接口,類似於:eth0:1
macvlan網絡結構分析:
macvlan不依賴linux bridge,brctl show可以確認macvlan沒有創建新的bridge
查看一下容器mac1的網絡設備:
除了lo,容器只有一個eth0,請注意:eth0后面還有@if2,表明該網卡有一個對應的interface,全局編號為2,。根據macvlan的原理,我們猜測這個interface就是ens192,
確認如下:
可見,容器的eth0就是ens192通過macvlan虛擬出來的interface。容器的interface直接與主機的網卡連接,這種方案是的容器無需通過NAT和端口映射就能與外網直接通信(只要有網關)在網絡上與其他獨立的主機沒有區別
當前網絡如圖所示:
用sub-interface實現多macvlan網絡
macvlan會獨占主機的網卡,也就是說一個網卡只能創建一個macvlan網絡,否則會報錯:
但是主機host的網卡是有限的,如何支持更多的macvlan呢?
好在macvlan不僅可以連接到interface(如ens192)還可以連接到sub-interface(如:ens192.xxx)
VLAN是現代網絡常用的網絡虛擬化技術,它可以將物理的二層網絡划分成多達4094個邏輯網絡,這些網絡在二層上是隔離的,每個邏輯網絡(即VLAN)由VLAN ID區分,VLAN ID的取值唯1-4094
linux的網卡也能支持VLAN,同一個interface可以收發多個VLAN數據包,不過前提是要創建VLAN的sub-interface
比如:希望ens192同時支持VLAN10和VLAN20,則需要創建sub-interface ens192.10和ens192.20
在交換機上,如果某個port只能收發單個VLAN數據,該port為Access模式,如果支持多VLAN,則為trunk模式,因為我們在虛擬機上,所以無需配置
下面演示如何在ens192.10和ens192.20上創建macvlan網絡
1.首先在docker1和docker2上創建vlan
2.創建網絡
3.運行容器,分別使用macnet1和macnet2網絡
4.驗證網絡的連通性
在mac1去ping mac2無法ping通,畢竟他們不在同一個網段 ,下面我們在docker1上做同樣的操作
1.配置vlan
2.創建macvlan網絡
3.運行容器,分別使用macnet3和macney4
4.驗證容器的連通性
macnet3ping不通macnet4
我們再來試試docker1上的macnet3能不能ping通docker2上的macnet1,因為他們是在同一個網段
按正常來說他們是能夠正常進行通信的,但是由於我的是在esxi的虛擬機上面做的實驗,需要在esxi中設置ens192為trunk口,允許所有vlan通過后試驗才會生效
即:同一個macvlan下的網絡能ping通,不同的macvlan網絡之間不能通信。但是更准確的說法是:不同的macvlan網絡不能在二層上通信。在三層可以通過網關進行通信
現在的拓撲如下:盜圖
下面測試通過啟用網關的形式,使不同網段的macvlan打通
1.先將192。168.7.222配置成一個虛擬記得路由,設置網關並轉發VLAN10和VLAN20的流量。當然使用物理路由也可以達到這種效果
確保192.168.7.222的IP Forwarding已經啟用
sysctl net.ipv4.ip_forward查看是否開啟轉發,1表示開啟,0表示沒有開啟
sysctl -w net.ipv4.ip_forward=1設置開啟
2.在/etc/sysconfig/network-scripts/下設置192.168.7.222的sub-interface
3.將網關的IP配置到sub-interface:
ifconfig ens192.10 192.168.10.1 netmask 255.255.255.0 up
ifconfig ens192.10 192.168.20.1 netmask 255.255.255.0 up
4.設置防火牆規則;
iptables -t nat -A POSTROUTING -o eth2.10 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2.20 -j MASQUERADE
iptables -A FORWARD -i eth2.10 -o eth2.20 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth2.20 -o eth2.10 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth2.10 -o eth2.20 -j ACCEPT
iptables -A FORWARD -i eth2.20 -o eth2.10 -j ACCEPT
5.當前的網絡拓撲:盜圖
現在不同的macvlan之間也可以進行通信
下面的圖是容器之間的通信過程:盜圖
1.因為容器在不同的網段,所以使用路由進行轉發
macvlan網絡的連通性和隔離性完全依賴VLAN,IP subnet和路由,docker 本身不做任何限制,用戶可以像管理傳統VLAN網絡那樣管理macvlan