一、macvlan
實現(xiàn)docker的跨主機網(wǎng)絡(luò)通信的方案有很多,如之前博文中寫到的通過部署 consul服務(wù)實現(xiàn)docker容器跨主機通信
macvlan工作原理:
macvlan是linux內(nèi)核支持的網(wǎng)絡(luò)接口。要求的linux內(nèi)部版本是v3.9–3.19和4.0+;
通過為物理網(wǎng)卡創(chuàng)建macvlan子接口,允許一塊物理網(wǎng)卡擁有多個獨立的mac地址和ip地址。虛擬出來的子接口將直接暴露在相鄰物理網(wǎng)絡(luò)中。從外部看來,就像是把網(wǎng)線隔開多股,分別接受了不同的主機上一樣;
物理網(wǎng)卡收到包后,會根據(jù)收到包的目的mac地址判斷這個包需要交給其中虛擬網(wǎng)卡。
當(dāng)容器需要直連入物理網(wǎng)絡(luò)時,可以使用macvlan。macvlan本身不創(chuàng)建網(wǎng)絡(luò),本質(zhì)上首先使宿主機物理網(wǎng)卡工作在‘混雜模式',這樣物理網(wǎng)卡的mac地址將會失效,所有二層網(wǎng)絡(luò)中的流量物理網(wǎng)卡都能收到。接下來就是在這張物理網(wǎng)卡上創(chuàng)建虛擬網(wǎng)卡,并為虛擬網(wǎng)卡指定mac地址,實現(xiàn)一卡多用,在物理網(wǎng)絡(luò)看來,每張?zhí)摂M網(wǎng)卡都是一個單獨的接口。
使用macvlan注意:
- 容器直接連接物理網(wǎng)絡(luò),由物理網(wǎng)絡(luò)負責(zé)分配ip地址,可能的結(jié)果是物理網(wǎng)絡(luò)ip地址被耗盡,另一個后果是網(wǎng)絡(luò)性能問題,物理網(wǎng)絡(luò)中接入的主機變多,廣播包占比快速升高而引起的網(wǎng)絡(luò)性能下降問題;
- 宿主機上的某張網(wǎng)上需要工作在‘混亂模式'下;
- 前面說到,工作在混亂模式下的物理網(wǎng)卡,其mac地址會失效,所以,此模式中運行的容器并不能與外網(wǎng)進行通信,但是不會影響宿主機與外網(wǎng)通信;
- 從長遠來看bridge網(wǎng)絡(luò)與overlay網(wǎng)絡(luò)是更好的選擇,原因就是虛擬網(wǎng)絡(luò)應(yīng)該與物理網(wǎng)絡(luò)隔離而不是共享。
工作示意圖:
二、配置實例
實例1(實現(xiàn)容器基于macvlan的單網(wǎng)段跨主機通信)
實現(xiàn)效果:
兩臺centos 7.3,分別運行著docker服務(wù);
兩臺docker服務(wù)器創(chuàng)建相同的一個macvlan網(wǎng)絡(luò),使docker服務(wù)器上的容器可以實現(xiàn)跨主機通信。
開始配置
1、第一臺docker服務(wù)器配置如下
1
2
3
4
5
6
7
8
|
[root@docker01 ~] # ip link set ens33 promisc on # 開啟ens33網(wǎng)卡的混雜模式 [root@docker01 ~] # ip link show ens33 # 確定查看的信息包含以下標紅的字樣 2: ens33: <broadcast,multicast, 'promisc' ,up,lower_up> mtu 1500 qdisc pfifo_fast state up mode default group default qlen 1000 link /ether 00:0c:29:9f:33:9f brd ff:ff:ff:ff:ff:ff [root@docker01 ~] # docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o pa rent=ens33 mac_net1 #創(chuàng)建macvlan網(wǎng)絡(luò),指定網(wǎng)關(guān)、網(wǎng)段等信息,“-o”指定綁定在哪張網(wǎng)卡之上 [root@docker01 ~] # docker run -itd --name test1 --ip 172.22.16.10 --network mac_net1 busybox # 基于新創(chuàng)建的macvlan網(wǎng)絡(luò)運行一個容器,并指定其ip |
確認運行的容器的ip地址
1
2
3
4
5
6
7
8
9
|
[root@docker01 ~] # docker exec test1 ip a # 查看ip,確定以下標紅與配置的一樣 1: lo: <loopback,up,lower_up> mtu 65536 qdisc noqueue qlen 1000 link /loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1 /8 scope host lo valid_lft forever preferred_lft forever 6: eth0@if2: <broadcast,multicast,up,lower_up,m-down> mtu 1500 qdisc noqueue link /ether 02:42:ac:16:10:0a brd ff:ff:ff:ff:ff:ff inet '172.22.16.10/24' brd 172.22.16.255 scope global eth0 valid_lft forever preferred_lft forever |
2、第二臺docker服務(wù)器配置如下(與第一臺docker服務(wù)器基本相似)
1
2
3
4
5
6
7
8
9
10
|
[root@docker02 ~] # ip link set ens33 promisc on # 開啟混雜模式 [root@docker02 ~] # ip link show ens33 2: ens33: <broadcast,multicast, 'promisc' ,up,lower_up> mtu 1500 qdisc pfifo_fast state up mode default group default qlen 1000 link /ether 00:0c:29:b5: bc :ed brd ff:ff:ff:ff:ff:ff [root@docker02 ~] # docker network create -d macvlan --subnet 172.22.16.0/24 --gateway=172.22.16.1 -o parent=ens33 mac_net1 #創(chuàng)建一個與第一臺docker服務(wù)器的網(wǎng)段、網(wǎng)關(guān)相同的macvlan。并綁定到物理網(wǎng)卡上。 #為了可以直觀的看出其他docker服務(wù)器上的macvlan和第這臺是在同一個網(wǎng)段的。所以,建議設(shè)置的網(wǎng)絡(luò)名稱一樣。 [root@docker02 ~] # docker run -itd --name test2 --ip 172.22.16.11 --network mac_net1 busybox #運行一個容器,并指定是基于macvlan網(wǎng)絡(luò)的 #注意,其ip地址不要與其他docker服務(wù)器上的容器ip地址沖突 |
確認運行的容器的ip地址
1
2
3
4
5
6
7
8
9
|
[root@docker02 ~] # docker exec test2 ip a 1: lo: <loopback,up,lower_up> mtu 65536 qdisc noqueue qlen 1000 link /loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1 /8 scope host lo valid_lft forever preferred_lft forever 6: eth0@if2: <broadcast,multicast,up,lower_up,m-down> mtu 1500 qdisc noqueue link /ether 02:42:ac:16:10:0b brd ff:ff:ff:ff:ff:ff inet '172.22.16.11/24' brd 172.22.16.255 scope global eth0 valid_lft forever preferred_lft forever |
使用第二臺docker服務(wù)器上的容器test2對第一臺docker服務(wù)器上的容器test1進行ping測試
ok,跨主機的容器通信就通過macvlan實現(xiàn)了。由于使用混雜模式會造成物理網(wǎng)卡的mac地址失效,所以容器并不能通過此模式進行與外網(wǎng)的通信。
實例2(基于macvlan的跨主機網(wǎng)絡(luò)多網(wǎng)段的解決方案)
實現(xiàn)的效果如下:
- 兩臺centos 7.3,分別運行著docker服務(wù);
- 每臺宿主機創(chuàng)建了兩個macvlan網(wǎng)段供容器使用(172.10.16.0/24和172.20.16.0/24);
- 第一臺docker服務(wù)器上運行容器test1和test2,第二臺docker服務(wù)器運行容器test3和test4。
- 最終實現(xiàn)跨主機的同網(wǎng)段容器互相通信。
開始配置:
1、第一臺docker服務(wù)器配置如下
1
2
3
4
5
6
7
|
[root@docker01 ~] # ip link set ens33 promisc on # 開啟ens33網(wǎng)卡的混雜模式 #也就是開啟網(wǎng)卡的多個虛擬interface(接口) [root@docker01 ~] # ip link show ens33 # 確定查看的信息包含以下標紅的字樣 2: ens33: <broadcast,multicast, 'promisc' ,up,lower_up> mtu 1500 qdisc pfifo_fast state up mode default group default qlen 1000 link /ether 00:0c:29:9f:33:9f brd ff:ff:ff:ff:ff:ff [root@docker01 ~] # modinfo 8021q #查看是否加載8021q模塊,如果有信息返回,則表示該模塊已經(jīng)加載 |
modinfo 8021q命令返回的信息如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
[root@docker01 ~] # modprobe 8021q #若沒有加載8021q模塊,則執(zhí)行此命令 [root@docker01 ~] # cd /etc/sysconfig/network-scripts/ [root@docker01 network-scripts] # vim ifcfg-ens33 ................... bootproto=manual # 將此配置項改為“manual”,也是手動的意思 [root@docker01 network-scripts] # cp -p ifcfg-ens33 ifcfg-ens33.10 # 復(fù)制一份網(wǎng)卡配置文件,-p保留原本文件的屬性 [root@docker01 network-scripts] # vim ifcfg-ens33.10 bootproto=none name=ens33.10 #注意更改名稱 device=ens33.10 #注意更改名稱 onboot= yes ipaddr=192.168.10.11 # 給虛擬網(wǎng)卡設(shè)置一個ip prefix=24 gateway=192.168.10.2 vlan= yes [root@docker01 network-scripts] # cp ifcfg-ens33.10 ifcfg-ens33.20 [root@docker01 network-scripts] # vim ifcfg-ens33.20 bootproto=none name=ens33.20 device=ens33.20 onboot= yes ipaddr=192.168.20.10 # 注意,此處的ip與ens33.10并不在同一網(wǎng)段 prefix=24 gateway=192.168.20.2 vlan= yes [root@docker01 network-scripts] # ifdown ens33;ifup ens33 #重啟網(wǎng)卡,使更改生效 [root@docker01 network-scripts] # ifup ens33.10 # 啟動該網(wǎng)卡 [root@docker01 network-scripts] # ifup ens33.20 # 啟動 [root@docker01 ~] # docker network create -d macvlan --subnet 172.10.16.0/24 --gateway 172.10.16.1 -o parent=ens33.10 mac_net10 #創(chuàng)建一個macvlan網(wǎng)絡(luò),給其定義一個網(wǎng)段、網(wǎng)關(guān)及綁定到ens33.10 [root@docker01 ~] # docker network create -d macvlan --subnet 172.20.16.0/24 --gateway 172.20.16.1 -o parent=ens33.20 mac_net20 #創(chuàng)建一個macvlan網(wǎng)絡(luò),給其定義一個網(wǎng)段、網(wǎng)關(guān)及綁定到ens33.20 #接下來分別基于剛剛創(chuàng)建的macvlan網(wǎng)絡(luò)運行一個容器 |
2、第二臺docker服務(wù)器配置如下(基本與第一臺操作類似,要注意ip不要沖突)
1
2
3
4
5
6
|
[root@docker02 ~] # ip link set ens33 promisc on # 開啟混雜模式 [root@docker02 ~] # ip link show ens33 2: ens33: <broadcast,multicast, 'promisc' ,up,lower_up> mtu 1500 qdisc pfifo_fast state up mode default group default qlen 1000 link /ether 00:0c:29:b5: bc :ed brd ff:ff:ff:ff:ff:ff [root@docker02 ~] # modinfo 8021q 返回信息可參考圖一 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
[root@docker02 ~] # modprobe 8021q #若沒有加載8021q模塊,則執(zhí)行此命令 [root@docker02 ~] # cd /etc/sysconfig/network-scripts/ [root@docker02 network-scripts] # vim ifcfg-ens33 ............... #省略部分內(nèi)容 bootproto=manual [root@docker02 network-scripts] # scp [email protected]:/etc/sysconfig/network-scripts/ifcfg-ens33.* . # 要注意后面的“.” ifcfg-ens33.10 100% 128 83.4kb /s 00:00 ifcfg-ens33.20 100% 124 75.0kb /s 00:00 [root@docker02 network-scripts] # vim ifcfg-ens33.10 bootproto=none name=ens33.10 device=ens33.10 onboot= yes ipaddr=192.168.10.11 # 更改ip,以防和第一臺沖突 prefix=24 gateway=192.168.10.2 vlan= yes [root@docker02 network-scripts] # vim ifcfg-ens33.20 bootproto=none name=ens33.20 device=ens33.20 onboot= yes ipaddr=192.168.20.11 prefix=24 gateway=192.168.20.2 vlan= yes [root@docker02 network-scripts] # ifdown ens33;ifup ens33 # 重啟網(wǎng)卡 ,使配置生效 [root@docker02 network-scripts] # ifup ens33.10 # 啟動網(wǎng)卡 [root@docker02 network-scripts] # ifup ens33.20 #接下來創(chuàng)建macvlan網(wǎng)絡(luò),與第一臺docker服務(wù)器創(chuàng)建的網(wǎng)絡(luò)一樣 [root@docker02 ~] # docker network create -d macvlan --subnet 172.10.16.0/24 --gateway 172.10.16.1 -o parent=ens33.10 mac_net10 [root@docker02 ~] # docker network create -d macvlan --subnet 172.20.16.0/24 --gateway 172.20.16.1 -o parent=ens33.20 mac_net20 [root@docker02 ~] # docker run -itd --name test3 --network mac_net10 --ip 172.10.16.11 busybox [root@docker02 ~] # docker run -itd --name test4 --network mac_net20 --ip 172.20.16.21 busybox |
配置至此,即可進行ping測試了,如果配置無誤,則test3應(yīng)該和test1互通(因為其都是基于mac_net10網(wǎng)絡(luò));test4應(yīng)該和test2互通(同理)。
但test3和test1不能和test4和test2互通(因為其不是基于同一個虛擬局域網(wǎng))。
容器test3 ping 容器test1測試(注意:若是使用vmware虛擬機進行測試,由于vmware的特性,需將其網(wǎng)絡(luò)適配器改為“橋接模式”,而不是nat模式等。否則無法通信)
容器test4 ping 容器test2測試:
至此,跨主機網(wǎng)絡(luò)多網(wǎng)段已經(jīng)實現(xiàn),同樣,各個容器無法與外網(wǎng)進行通信。若有耐心,還是建議閱讀 docker官方文檔
到此這篇關(guān)于docker 容器跨主機多網(wǎng)段通信解決方案的文章就介紹到這了,更多相關(guān)docker 容器跨主機多網(wǎng)段通信內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://blog.51cto.com/14227204/2516964