一、概述
Docker 提供三种 网络驱动:bridge, macvlan 和 overlay overlay 和 macvlan 用于创建跨主机的网络
二、自定义桥接(bridge)网络
这个网桥类似于默认网络中的 bridge
创建自定义网络命令:docker network create
$ docker network create --driver bridge --subnet 172.19.0.0/16 --gateway 172.19.0.1 mybridge_net
参数解释: –driver bridge 表示使用桥接模式 –subnet 172.19.0.0/16 表示子网ip 可以分配 172.19.0.2 到 172.19.255.255 –gateway 172.19.0.1 表示网关 mybridge_net 表示网络名
查看
$ docker network ls
$ docker network inspect mybridge_net
使用新创建的网络创建容器
$ docker run --name=busybox_mybridge_net --net=mybridge_net -td busybox
查看
$ docker network ls
$ network inspect mybridge_net
$ ip a
$ docker run --name=busybox_mybridge_net --net=mybridge_net -td busybox
$ ip a
查看容器IP
$ docker exec -it busybox_mybridge_net ifconfig
三、自定义macvlan网络(物理网卡相当于交换机)
macvlan 是在 宿主机 网卡上创建多个子网卡,并分配独立的 IP 地址和 MAC 地址,把子网卡分配给容器实例来实现实例与物理网络的直通,并同时保持容器实例的隔离性。Host 收到数据包后,则根据不同的 MAC 地址把数据包从转发给不同的子接口,在外界来看就相当于多台主机。
macvlan接口会监听并接收链路上到达本mac地址的报文,因此macvlan(除bridge外)仅能向外部网络发送报文,并接受目的为本机mac的报文。
macvlan 网络会独占物理网卡,也就是说一张物理网卡只能创建一个 macvlan 网络
根据 macvlan 子接口之间的通信模式,macvlan 有四种网络模式:
- vepa(virtual ethernet port aggregator) 模式
- passthru 模式
- private 模式
- bridge 模式(默认模式,最常用的方式)
3.1、四种模式简介 3.1.1、vepa模式
在这种模式下,macvlan设备不能直接接收在同一个物理网卡的其他macvlan设备的数据包,但是其他macvlan设备可以将数据包通过物理网卡发送出去,然后通过hairpin设备返回的给其他macvlan设备,用于管理内部vm直接的流量,并且需要特殊设备支持。
创建vepa模式的网络(macvlan_mode=vepa)
$ docker network create -d macvlan --subnet=192.168.182.0/24 --gateway=192.168.182.2 -o parent=ens37 -o macvlan_mode=vepa vepamv
使用上述网络运行2个容器
$ docker run -itd --net=vepamv --ip=192.168.182.222 --name=macvlan-vepa-1 busybox /bin/sh
$ docker run -itd --net=vepamv --ip=192.168.182.223 --name=macvlan-vepa-2 busybox /bin/sh
查看网络信息,可以看到驱动类型为macvlan,macvlan模型为vepa,两个网卡有独立的mac地址,底层物理网卡为ens37
$ docker network inspect vepamv
在macvlan-vepa-1中ping macvlan-vepa-2发现无法ping通,因为本地环境上并没有开启hairpin模式的交换机或路由器,报文发送到链路上之后无法返回来。即无法在internal内部进行报文传输
$ docker exec -it macvlan-vepa-1 ping 192.168.182.223
但在external network的机器(宿主机:192.168.182.130)是可以直接访问该容器的(首先该容器的IP属于external network) 3.1.2、passthru模式
这种模式,只允许单个子接口连接主接口,且必须设置成混杂模式,一般用于子接口桥接和创建 VLAN 子接口的场景。
3.1.3、private模式
隔离功能比VPEA更强,阻断了广播和组播,即使交换机开启hairpin也无法通信。
3.1.4、bridge模式
在这种模式下,寄生在同一个物理设备的macvlan设备可以直接通讯,不需要外接的hairpin设备帮助,使用如下的命令创建一个bridge的macvlan网络。
3.2、相同 macvlan 网络之间的通信原理 1)准备两台机器
host1:192.168.182.130 ens33
host2:192.168.182.152 bond0
2)创建两台宿主机上macvlan
$ docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33 mac1
$ docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.11.1 -o parent=bond0 mac1
$ docker network ls
参数解释 -d/–driver 指定 Docker 网络 driver –subnet 指定 macvlan 网络所在的网络 –gateway 指定网关 -o parent 指定用来分配 macvlan 网络的物理网卡
3)使用上面创建的macvlan网络创建容器
$ docker run -itd --name c1 --ip=172.16.10.2 --network mac1 busybox
$ docker run -itd --name c2 --ip=172.16.10.3 --network mac1 busybox
–ip 指定容器 c1 使用的 IP,这样做的目的是防止自动分配,造成 IP 冲突 –network 指定 macvlan 网络
4)验证,在 host1 c1 中 ping host2 c2
$ docker exec c1 ping -c 2 172.16.10.3
3.2、不同 macvlan 网络之间的通信 准备三台机器(Centos8),桥接模式
host1:
ens33(NAT) 192.168.182.153
ens34(桥接) 192.168.0.110
host2:
ens33(NAT) 192.168.182.154
ens34(桥接) 192.168.0.111
host3:
ens33(NAT) 192.168.182.155
ens34(桥接) 192.168.0.112
第一步:先实现相同macvlan网络之间的通信
接下来,我们来看看相同 macvlan 网络之间的连通性,搭建以下的拓扑环境:
由于 macvlan 网络会独占物理网卡,也就是说一张物理网卡只能创建一个 macvlan 网络,如果我们想创建多个 macvlan 网络就得用多张网卡。
好在 macvlan 网络也是支持 VLAN 子接口的,所以,我们可以通过 VLAN技术将一个网口划分出多个子网口,这样就可以基于子网口来创建 macvlan 网络了,下面是具体的创建过程。
1)开启混杂模式
$ ip link set ens34 promisc on
2)首先分别在两台主机上将物理网口 ens33创建出两个 VLAN 子接口。
$ ip link add link ens34 name ens34.10 type vlan id 100
$ ip link add link ens34 name ens34.20 type vlan id 101
$ ip link set ens34.10 up
$ ip link set ens34.20 up
3)分别在 host1 和 host2 上基于两个 VLAN 子接口创建 2 个 macvlan 网络,macvlan10 和 macvlan20。
$ docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens34.10 mac_net10
$ docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=ens34.20 mac_net20
4)分别在 host1 和 host2 上运行容器,并指定不同的 macvlan 网络。
$ docker run -itd --name bbox1 --ip=172.16.10.10 --network mac_net10 busybox
$ docker run -itd --name bbox2 --ip=172.16.20.10 --network mac_net20 busybox
$ docker run -itd --name bbox3 --ip=172.16.10.11 --network mac_net10 busybox
$ docker run -itd --name bbox4 --ip=172.16.20.11 --network mac_net20 busybox
通过验证,bbox1 和 bbox3,bbox2 和 bbox4 在同一 macvlan 网络下,互相可以 ping 通,bbox1 和 bbox2,bbox1 和 bbox4 在不同的 macvlan 网络下,互相 ping 不通。
$ docker exec -it bbox1 ping 172.16.10.11
$ docker exec -it bbox2 ping 172.16.20.11
$ docker exec -it bbox1 ping 172.16.20.10
$ docker exec -it bbox1 ping 172.16.20.11
注意:如果你是vmware环境的话,由于VMware虚拟机的原因,必须将两台主机默认的NAT模式修改为桥接模式才能够正常通信
第二步:不同macvlan网络之间的通信实现
通过上面验证同一个二层macvlan网络是可以互通,但是不通macvlan网络是不通的,如果需要通,则需要通过三层的路由,我们这就来验证下。
就加一台 host3,以下操作都是在host3上操作的,通过打开 ip_forward 把它改造成一台路由器,用来打通不同 macvlan 网络,大概的图示如下所示: 1)首先对 host3 执行 sysctl -w net.ipv4.ip_forward=1 打开路由开关。
$ sysctl -w net.ipv4.ip_forward=1
$ sysctl net.ipv4.ip_forward
$ cat /proc/sys/net/ipv4/ip_forward
2)然后host3创建两个 VLAN 子接口,一个作为 macvlan 网络 mac10 的网关,一个作为 mac20 的网关。
$ ip link add link ens34 name ens34.100 type vlan id 100
$ ip link add link ens34 name ens34.200 type vlan id 101
$ ip addr add 172.16.10.1/24 dev ens34.100
$ ip link set ens34.100 up
$ ip addr add 172.16.20.1/24 dev ens34.200
$ ip link set ens34.200 up
3)这样之后再从 bbox1 和 bbox2,bbox1 和 bbox4,就可以 ping 通了。
$ docker exec -it bbox1 ping 172.16.20.10
$ docker exec -it bbox1 ping 172.16.20.11
可能有些系统做了安全限制,可能 ping 不通,这时候可以添加以下 iptables 规则,目的是让系统能够转发不通 VLAN 的数据包。我这里是没加也是可以通的。
$ iptables -t nat -A POSTROUTING -o ens34.10 -j MASQUERADE
$ iptables -t nat -A POSTROUTING -o ens34.20 -j MASQUERADE
$ iptables -A FORWARD -i ens34.10 -o ens34.20 -m state --state RELATED,ESTABLISHED -j ACCEPT
$ iptables -A FORWARD -i ens34.20 -o ens34.10 -m state --state RELATED,ESTABLISHED -j ACCEPT
$ iptables -A FORWARD -i ens34.10 -o ens34.20 -j ACCEPT
$ iptables -A FORWARD -i ens34.20 -o ens34.10 -j ACCEPT
缺点:不能自动校验ip冲突,得人为区分,只能容器之间访问,而且无法访问到外网,overlay可以补足
四、自定义overlay网络
Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发;而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。
docker官方文档的示例中,overlay网络是在swarm集群中配置的,但实际上,overlay网络可以独立于swarm集群实现,只需要满足以下前提条件即可。
- 有consul或者etcd,zookeeper的集群key-value存储服务
- 组成集群的所有主机的主机名不允许重复,因为docker守护进程与consul通信时,以主机名相互区分
- 所有主机都可以访问集群key-value的服务端口,按具体类型需要打开进行配置。例如docker daemon启动时增加参数
–cluster-store=etcd://:4001 - -cluster-advertise=eth0:2376 - overlay网络依赖宿主机三层网络的组播实现,需要在所有宿主机的防火墙上打开下列端口
协议 | 端口 | 说明 |
---|
udp | 4789 | 容器之间流量的vxlan端口 | tcp/udp | 7946 | docker守护进程的控制端口 |
- 还需要宿主机内核版本3.10以上(1.9版本时,要求3.16以上)
其实要求也不少,还是等后续讲完docker集群模式后再回来细讲overlay网络模式。尽情期待……
|