一、MacVlan的概念
实现Docker的跨主机网络通信的方案有很多,比如在之前博文中写到的通过部署consul服务实现Docker容器跨主机通信 ,而这篇博文将Macvlan写下来
- Macvlan工作原理:
- Macvlan是Linux内核支持的网络接口。要求的Linux内部版本是v3.9–3.19和4.0+;
- 通过为物理网卡创建Macvlan子接口,允许一块物理网卡拥有多个独立的MAC地址和IP地址。虚拟出来的子接口将直接暴露在相邻物理网络中。从外部看来,就像是把网线隔开多股,分别接受了不同的主机上一样;
- 物理网卡收到包后,会根据收到包的目的MAC地址判断这个包需要交给其中虚拟网卡。
当容器需要直连入物理网络时,可以使用Macvlan。Macvlan本身不创建网络,本质上首先使宿主机物理网卡工作在‘混杂模式’,这样物理网卡的MAC地址将会失效,所有二层网络中的流量物理网卡都能收到。接下来就是在这张物理网卡上创建虚拟网卡,并为虚拟网卡指定MAC地址,实现一卡多用,在物理网络看来,每张虚拟网卡都是一个单独的接口
- 使用Macvlan有几点需要注意:
- 容器直接连接物理网络,由物理网络负责分配IP地址,可能的结果是物理网络IP地址被耗尽,另一个后果是网络性能问题,物理网络中接入的主机变多,广播包占比快速升高而引起的网络性能下降问题;
- 宿主机上的某张网上需要工作在‘混乱模式’下;
- 前面说到,工作在混乱模式下的物理网卡,其MAC地址会失效,所以,此模式中运行的容器并不能与外网进行通信,但是不会影响宿主机与外网通信;
- 从长远来看bridge网络与overlay网络是更好的选择,原因就是虚拟网络应该与物理网络隔离而不是共享。
工作示意图如下:
Docker容器跨主机多网段通信解决方案
二、配置实例
实例1(实现容器基于macvlan的单网段跨主机通信):
- 实现效果:
- 两台centos 7.5,分别运行着docker服务;
- 两台docker服务器创建相同的一个MacVlan网络,使docker服务器上的容器可以实现跨主机通信。
开始配置:
(1)第一台docker服务器配置如下:
#开启ens33网卡的混杂模式。#也就是开启网卡的多个虚拟interface(接口)
[liqingfei@docker01 ~]$ sudo ip link set eth0 promisc on
#确定查看的信息包含以下标红的字样,1500
[liqingfei@docker01 ~]$ sudo ip lin show eth0
2: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether fa:16:3e:69:9c:b0 brd ff:ff:ff:ff:ff:ff
#创建macvlan网络,指定网段、网关等信息,“-o”指定绑定在哪张网卡之上
[liqingfei@docker01 ~]$ sudo docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o parent=eth0 mac_net1
1decf127fd0848da96705e1a72086e4d1808f3fefa45f22bff7e71b6f17949f8
[liqingfei@docker01 ~]$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
ad6c4a9868fa bridge bridge local
fd017b022141 host host local
1decf127fd08 mac_net1 macvlan local
5054f103cc9d my-bridge bridge local
ca3235108b83 none null local
#基于新创建的macvlan网络运行一个容器,并指定其IP。
[liqingfei@docker01 ~]$ sudo docker run -tid --name box1 --ip 172.22.16.10 --network mac_net1 liqingfei01/cnetos7-test01
587d629e87de8e6bae5eaa05e6bfbac78e26db89ff8d6f74a72c5277592492fc
确认运行的容器的IP地址:
(1)第二台docker服务器配置如下(与第一台docker服务器的配置基本相似):
#开启ens33网卡的混杂模式。#也就是开启网卡的多个虚拟interface(接口)
[liqingfei@docker02 ~]$ sudo ip link set eth0 promisc on
#确定查看的信息包含以下标红的字样,1500
[liqingfei@docker02 ~]$ sudo ip link show eth0
2: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether fa:16:3e:87:21:05 brd ff:ff:ff:ff:ff:ff
#创建macvlan网络,指定网段、网关等信息,“-o”指定绑定在哪张网卡之上
#创建一个与第一台docker服务器的网段、网关相同的macvlan。并绑定到物理网卡上。
#为了可以直观的看出其他docker服务器上的macvlan和第这台是在同一个网段的。
#所以,建议设置的网络名称一样。
[liqingfei@docker02 ~]$ sudo docker network create -d macvlan --subnet 172.22.16.0/24 --gateway=172.22.16.1 -o parent=eth0 mac_net1
6f0670f8ba8a3114f3aa3307c3b4879c24b788c455cc4a974c8a94c2312f7703
[liqingfei@docker02 ~]$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
26f0c61328c6 bridge bridge local
202bac44a904 host host local
6f0670f8ba8a mac_net1 macvlan local
a9ad2008a52d none null local