详解Docker 容器跨主机多网段通信解决方案
一、MacVlan
实现Docker的跨主机网络通信的方案有很多,如之前博文中写到的通过部署Consul服务实现Docker容器跨主机通信
Macvlan工作原理:
Macvlan是Linux内核支持的网络接口。要求的Linux内部版本是v3.9–3.19和4.0+;
通过为物理网卡创建Macvlan子接口,允许一块物理网卡拥有多个独立的MAC地址和IP地址。虚拟出来的子接口将直接暴露在相邻物理网络中。从外部看来,就像是把网线隔开多股,分别接受了不同的主机上一样;
物理网卡收到包后,会根据收到包的目的MAC地址判断这个包需要交给其中虚拟网卡。
当容器需要直连入物理网络时,可以使用Macvlan。Macvlan本身不创建网络,本质上首先使宿主机物理网卡工作在‘混杂模式',这样物理网卡的MAC地址将会失效,所有二层网络中的流量物理网卡都能收到。接下来就是在这张物理网卡上创建虚拟网卡,并为虚拟网卡指定MAC地址,实现一卡多用,在物理网络看来,每张虚拟网卡都是一个单独的接口。
使用Macvlan注意:
- 容器直接连接物理网络,由物理网络负责分配IP地址,可能的结果是物理网络IP地址被耗尽,另一个后果是网络性能问题,物理网络中接入的主机变多,广播包占比快速升高而引起的网络性能下降问题;
- 宿主机上的某张网上需要工作在‘混乱模式'下;
- 前面说到,工作在混乱模式下的物理网卡,其MAC地址会失效,所以,此模式中运行的容器并不能与外网进行通信,但是不会影响宿主机与外网通信;
- 从长远来看bridge网络与overlay网络是更好的选择,原因就是虚拟网络应该与物理网络隔离而不是共享。
工作示意图:
二、配置实例
实例1(实现容器基于macvlan的单网段跨主机通信)
实现效果:
两台centos7.3,分别运行着docker服务;
两台docker服务器创建相同的一个MacVlan网络,使docker服务器上的容器可以实现跨主机通信。
开始配置
1、第一台docker服务器配置如下
[root@docker01~]#iplinksetens33promiscon#开启ens33网卡的混杂模式 [root@docker01~]#iplinkshowens33#确定查看的信息包含以下标红的字样 2:ens33:mtu1500qdiscpfifo_faststateUPmodeDEFAULTgroupdefaultqlen1000 link/ether00:0c:29:9f:33:9fbrdff:ff:ff:ff:ff:ff [root@docker01~]#dockernetworkcreate-dmacvlan--subnet172.22.16.0/24--gateway172.22.16.1-opa rent=ens33mac_net1 #创建macvlan网络,指定网关、网段等信息,“-o”指定绑定在哪张网卡之上 [root@docker01~]#dockerrun-itd--nametest1--ip172.22.16.10--networkmac_net1busybox#基于新创建的macvlan网络运行一个容器,并指定其IP
确认运行的容器的IP地址
[root@docker01~]#dockerexectest1ipa#查看IP,确定以下标红与配置的一样 1:lo:mtu65536qdiscnoqueueqlen1000 link/loopback00:00:00:00:00:00brd00:00:00:00:00:00 inet127.0.0.1/8scopehostlo valid_lftforeverpreferred_lftforever 6:eth0@if2: mtu1500qdiscnoqueue link/ether02:42:ac:16:10:0abrdff:ff:ff:ff:ff:ff inet'172.22.16.10/24'brd172.22.16.255scopeglobaleth0 valid_lftforeverpreferred_lftforever
2、第二台docker服务器配置如下(与第一台docker服务器基本相似)
[root@docker02~]#iplinksetens33promiscon#开启混杂模式 [root@docker02~]#iplinkshowens33 2:ens33:mtu1500qdiscpfifo_faststateUPmodeDEFAULTgroupdefaultqlen1000 link/ether00:0c:29:b5:bc:edbrdff:ff:ff:ff:ff:ff [root@docker02~]#dockernetworkcreate-dmacvlan--subnet172.22.16.0/24--gateway=172.22.16.1-oparent=ens33mac_net1 #创建一个与第一台docker服务器的网段、网关相同的macvlan。并绑定到物理网卡上。 #为了可以直观的看出其他docker服务器上的macvlan和第这台是在同一个网段的。所以,建议设置的网络名称一样。 [root@docker02~]#dockerrun-itd--nametest2--ip172.22.16.11--networkmac_net1busybox #运行一个容器,并指定是基于macvlan网络的 #注意,其IP地址不要与其他docker服务器上的容器IP地址冲突
确认运行的容器的IP地址
[root@docker02~]#dockerexectest2ipa 1:lo:mtu65536qdiscnoqueueqlen1000 link/loopback00:00:00:00:00:00brd00:00:00:00:00:00 inet127.0.0.1/8scopehostlo valid_lftforeverpreferred_lftforever 6:eth0@if2: mtu1500qdiscnoqueue link/ether02:42:ac:16:10:0bbrdff:ff:ff:ff:ff:ff inet'172.22.16.11/24'brd172.22.16.255scopeglobaleth0 valid_lftforeverpreferred_lftforever
使用第二台docker服务器上的容器test2对第一台docker服务器上的容器test1进行ping测试
OK,跨主机的容器通信就通过macvlan实现了。由于使用混杂模式会造成物理网卡的MAC地址失效,所以容器并不能通过此模式进行与外网的通信。
实例2(基于macvlan的跨主机网络多网段的解决方案)
实现的效果如下:
- 两台centos7.3,分别运行着docker服务;
- 每台宿主机创建了两个MacVlan网段供容器使用(172.10.16.0/24和172.20.16.0/24);
- 第一台docker服务器上运行容器test1和test2,第二台docker服务器运行容器test3和test4。
- 最终实现跨主机的同网段容器互相通信。
开始配置:
1、第一台docker服务器配置如下
[root@docker01~]#iplinksetens33promiscon#开启ens33网卡的混杂模式 #也就是开启网卡的多个虚拟interface(接口) [root@docker01~]#iplinkshowens33#确定查看的信息包含以下标红的字样 2:ens33:mtu1500qdiscpfifo_faststateUPmodeDEFAULTgroupdefaultqlen1000 link/ether00:0c:29:9f:33:9fbrdff:ff:ff:ff:ff:ff [root@docker01~]#modinfo8021q #查看是否加载8021q模块,如果有信息返回,则表示该模块已经加载
modinfo8021q命令返回的信息如下
[root@docker01~]#modprobe8021q#若没有加载8021q模块,则执行此命令 [root@docker01~]#cd/etc/sysconfig/network-scripts/ [root@docker01network-scripts]#vimifcfg-ens33 ................... BOOTPROTO=manual#将此配置项改为“manual”,也是手动的意思 [root@docker01network-scripts]#cp-pifcfg-ens33ifcfg-ens33.10#复制一份网卡配置文件,-p保留原本文件的属性 [root@docker01network-scripts]#vimifcfg-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@docker01network-scripts]#cpifcfg-ens33.10ifcfg-ens33.20 [root@docker01network-scripts]#vimifcfg-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@docker01network-scripts]#ifdownens33;ifupens33#重启网卡,使更改生效 [root@docker01network-scripts]#ifupens33.10#启动该网卡 [root@docker01network-scripts]#ifupens33.20#启动 [root@docker01~]#dockernetworkcreate-dmacvlan--subnet172.10.16.0/24--gateway172.10.16.1-oparent=ens33.10mac_net10 #创建一个macvlan网络,给其定义一个网段、网关及绑定到ens33.10 [root@docker01~]#dockernetworkcreate-dmacvlan--subnet172.20.16.0/24--gateway172.20.16.1-oparent=ens33.20mac_net20 #创建一个macvlan网络,给其定义一个网段、网关及绑定到ens33.20 #接下来分别基于刚刚创建的macvlan网络运行一个容器
[root@docker02~]#iplinksetens33promiscon#开启混杂模式 [root@docker02~]#iplinkshowens33 2:ens33:mtu1500qdiscpfifo_faststateUPmodeDEFAULTgroupdefaultqlen1000 link/ether00:0c:29:b5:bc:edbrdff:ff:ff:ff:ff:ff [root@docker02~]#modinfo8021q 返回信息可参考图一
[root@docker02~]#modprobe8021q#若没有加载8021q模块,则执行此命令 [root@docker02~]#cd/etc/sysconfig/network-scripts/ [root@docker02network-scripts]#vimifcfg-ens33 ...............#省略部分内容 BOOTPROTO=manual [root@docker02network-scripts]#scproot@192.168.171.151:/etc/sysconfig/network-scripts/ifcfg-ens33.*.#要注意后面的“.” ifcfg-ens33.10100%12883.4KB/s00:00 ifcfg-ens33.20100%12475.0KB/s00:00 [root@docker02network-scripts]#vimifcfg-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@docker02network-scripts]#vimifcfg-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@docker02network-scripts]#ifdownens33;ifupens33#重启网卡,使配置生效 [root@docker02network-scripts]#ifupens33.10#启动网卡 [root@docker02network-scripts]#ifupens33.20 #接下来创建macvlan网络,与第一台docker服务器创建的网络一样 [root@docker02~]#dockernetworkcreate-dmacvlan--subnet172.10.16.0/24--gateway172.10.16.1-oparent=ens33.10mac_net10 [root@docker02~]#dockernetworkcreate-dmacvlan--subnet172.20.16.0/24--gateway172.20.16.1-oparent=ens33.20mac_net20 [root@docker02~]#dockerrun-itd--nametest3--networkmac_net10--ip172.10.16.11busybox [root@docker02~]#dockerrun-itd--nametest4--networkmac_net20--ip172.20.16.21busybox
配置至此,即可进行ping测试了,如果配置无误,则test3应该和test1互通(因为其都是基于mac_net10网络);test4应该和test2互通(同理)。
但test3和test1不能和test4和test2互通(因为其不是基于同一个虚拟局域网)。
容器test3ping容器test1测试(注意:若是使用vmware虚拟机进行测试,由于vmware的特性,需将其网络适配器改为“桥接模式”,而不是NAT模式等。否则无法通信)
容器test4ping容器test2测试:
至此,跨主机网络多网段已经实现,同样,各个容器无法与外网进行通信。若有耐心,还是建议阅读docker官方文档
到此这篇关于Docker容器跨主机多网段通信解决方案的文章就介绍到这了,更多相关Docker容器跨主机多网段通信内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。