Docker 容器跨主機多網段通訊解決方案

1、MacVlan
實現Docker的跨主機網絡通訊的方案有不少,如以前博文中寫到的經過部署 Consul服務實現Docker容器跨主機通訊docker

Macvlan工做原理:vim

Macvlan是Linux內核支持的網絡接口。要求的Linux內部版本是v3.9–3.19和4.0+;
經過爲物理網卡建立Macvlan子接口,容許一塊物理網卡擁有多個獨立的MAC地址和IP地址。虛擬出來的子接口將直接暴露在相鄰物理網絡中。從外部看來,就像是把網線隔開多股,分別接受了不一樣的主機上同樣;
物理網卡收到包後,會根據收到包的目的MAC地址判斷這個包須要交給其中虛擬網卡。centos

當容器須要直連入物理網絡時,可使用Macvlan。Macvlan自己不建立網絡,本質上首先使宿主機物理網卡工做在‘混雜模式’,這樣物理網卡的MAC地址將會失效,全部二層網絡中的流量物理網卡都能收到。接下來就是在這張物理網卡上建立虛擬網卡,併爲虛擬網卡指定MAC地址,實現一卡多用,在物理網絡看來,每張虛擬網卡都是一個單獨的接口。服務器

使用Macvlan注意:網絡

  • 容器直接鏈接物理網絡,由物理網絡負責分配IP地址,可能的結果是物理網絡IP地址被耗盡,另外一個後果是網絡性能問題,物理網絡中接入的主機變多,廣播包占比快速升高而引發的網絡性能降低問題;
  • 宿主機上的某張網上須要工做在‘混亂模式’下;
  • 前面說到,工做在混亂模式下的物理網卡,其MAC地址會失效,因此,此模式中運行的容器並不能與外網進行通訊,可是不會影響宿主機與外網通訊;
  • 從長遠來看bridge網絡與overlay網絡是更好的選擇,緣由就是虛擬網絡應該與物理網絡隔離而不是共享。

工做示意圖:
Docker 容器跨主機多網段通訊解決方案
2、配置實例
實例1(實現容器基於macvlan的單網段跨主機通訊)ide

實現效果:oop

兩臺centos 7.3,分別運行着docker服務;
兩臺docker服務器建立相同的一個MacVlan網絡,使docker服務器上的容器能夠實現跨主機通訊。性能

開始配置
一、第一臺docker服務器配置以下測試

[root@docker01 ~]# ip link set ens33 promisc on             # 開啓ens33網卡的混雜模式
[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
#建立macvlan網絡,指定網關、網段等信息,「-o」指定綁定在哪張網卡之上
[root@docker01 ~]# docker run -itd --name test1 --ip 172.22.16.10 --network mac_net1 busybox     # 基於新建立的macvlan網絡運行一個容器,並指定其IP

確認運行的容器的IP地址code

[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

二、第二臺docker服務器配置以下(與第一臺docker服務器基本類似)

[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
#建立一個與第一臺docker服務器的網段、網關相同的macvlan。並綁定到物理網卡上。
#爲了能夠直觀的看出其餘docker服務器上的macvlan和第這臺是在同一個網段的。因此,建議設置的網絡名稱同樣。
[root@docker02 ~]# docker run -itd --name test2 --ip 172.22.16.11 --network mac_net1 busybox
#運行一個容器,並指定是基於macvlan網絡的
#注意,其IP地址不要與其餘docker服務器上的容器IP地址衝突

確認運行的容器的IP地址

[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服務器上的容器test2對第一臺docker服務器上的容器test1進行ping測試
Docker 容器跨主機多網段通訊解決方案
OK,跨主機的容器通訊就經過macvlan實現了。因爲使用混雜模式會形成物理網卡的MAC地址失效,因此容器並不能經過此模式進行與外網的通訊。

實例2(基於macvlan的跨主機網絡多網段的解決方案)

實現的效果以下:

  • 兩臺centos 7.3,分別運行着docker服務;
  • 每臺宿主機建立了兩個MacVlan網段供容器使用(172.10.16.0/24和172.20.16.0/24);
  • 第一臺docker服務器上運行容器test1和test2,第二臺docker服務器運行容器test3和test4。
  • 最終實現跨主機的同網段容器互相通訊。

開始配置:
一、第一臺docker服務器配置以下

[root@docker01 ~]# ip link set ens33 promisc on             # 開啓ens33網卡的混雜模式
#也就是開啓網卡的多個虛擬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模塊,若是有信息返回,則表示該模塊已經加載

modinfo 8021q命令返回的信息以下
Docker 容器跨主機多網段通訊解決方案

[root@docker01 ~]# modprobe 8021q     #若沒有加載8021q模塊,則執行此命令
[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             # 複製一份網卡配置文件,-p保留本來文件的屬性
[root@docker01 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@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並不在同一網段
PREFIX=24
GATEWAY=192.168.20.2
VLAN=yes
[root@docker01 network-scripts]# ifdown ens33;ifup ens33          #重啓網卡,使更改生效
[root@docker01 network-scripts]# ifup ens33.10      # 啓動該網卡
[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
#建立一個macvlan網絡,給其定義一個網段、網關及綁定到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
#建立一個macvlan網絡,給其定義一個網段、網關及綁定到ens33.20
#接下來分別基於剛剛建立的macvlan網絡運行一個容器

二、第二臺docker服務器配置以下(基本與第一臺操做相似,要注意IP不要衝突)

[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
返回信息可參考圖一
[root@docker02 ~]# modprobe 8021q     #若沒有加載8021q模塊,則執行此命令
[root@docker02 ~]# cd /etc/sysconfig/network-scripts/
[root@docker02 network-scripts]# vim ifcfg-ens33 
            ...............#省略部份內容
BOOTPROTO=manual        
[root@docker02 network-scripts]# scp root@192.168.171.151:/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         # 重啓網卡 ,使配置生效
[root@docker02 network-scripts]# ifup ens33.10     # 啓動網卡
[root@docker02 network-scripts]# ifup ens33.20
#接下來建立macvlan網絡,與第一臺docker服務器建立的網絡同樣
[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應該和test1互通(由於其都是基於mac_net10網絡);test4應該和test2互通(同理)。
但test3和test1不能和test4和test2互通(由於其不是基於同一個虛擬局域網)。
容器test3 ping 容器test1測試(注意:如果使用vmware虛擬機進行測試,因爲vmware的特性,需將其網絡適配器改成「橋接模式」,而不是NAT模式等。不然沒法通訊)
Docker 容器跨主機多網段通訊解決方案
容器test4 ping 容器test2測試:
Docker 容器跨主機多網段通訊解決方案
至此,跨主機網絡多網段已經實現,一樣,各個容器沒法與外網進行通訊。如有耐心,仍是建議閱讀docker官方文檔

相關文章
相關標籤/搜索