网站首页 > 技术文章 正文
一、概述
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
# 在host1创建macvlan网络
$ docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens33 mac1
# 在192.168.182.152上创建macvlan网络
$ 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网络创建容器
# 在host1上创建以macvlan网络的容器
$ docker run -itd --name c1 --ip=172.16.10.2 --network mac1 busybox
# 在host2上创建macvlan网络
$ 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 网络。
# host1
$ 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
# host2
$ 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 网络,大概的图示如下所示:
跨主机通信已经不从虚线走了,都从host3走,因为host3充当着两个maclvan的网关,当然也是路由器的角色。
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 的网关。
# host1,host2创建子接口,注意name和id必须要跟上面的两台机器一样,要不然会网络不通
$ ip link add link ens34 name ens34.100 type vlan id 100
$ ip link add link ens34 name ens34.200 type vlan id 101
# 对 vlan 子接口配置IP充当网关 IP 并启用
$ 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网络(swarm网络)
4.1、介绍
Overlay网络模式,在多个docker daemon 主机之间穿件一个分布式的网络,该网络(overlay)位于docker主机层次之上,允许容器(同一集群服务的容器)之间加密通讯,因此,docker需要处理每一个主机(docker daemon)和每个分布的容器之间的包路由。
每当初始化一个集群(swarm)或者添加一个docker主机到集群时,则在该主机上会自动创建两个网络(ingress和docker_gwbridge),但是swarm集群需要三个网络,还有一个自定义overlay网络。
# 查看docker网络
$ docker network ls
# 在192.168.0.113机器上初始化一个swarm集群
$ docker swarm init --advertise-addr 192.168.0.113
# 再查看docker网络
$ docker network ls
- ingress网络是一个特殊的 overlay 网络,该网络处理集群服务间的控制和数据信息。当创建一个集群服务、但未指定用户自定义网络时,该服务上的节点默认连接到ingree网络。
- docker_gwbridge桥接网络,该网络,连接单个主机的守护进程(docker daemon)与其他主机的守护进程,参与集群服务。
- 自定义Overlay networks 管理 Swarm 中 Docker 守护进程间的通信。你可以将服务附加到一个或多个已存在的 overlay 网络上,使得服务与服务之间能够通信。以下就是创建一个overlay网络:
$ docker network create -d overlay my-overlay
4.2、overlay netwrok 操作
1)环境
host1 192.168.0.113 ens33 centos8
host1 192.168.0.114 ens33 centos8
2)准备工作
- 2377/tcp:管理端口
- 7496/tcp/udp:节点间通信端口,发现网络的
- 4789/udp: 覆盖网的流量交互(例如密钥交互等)
放通这三个端口(所有节点都执行)
# 放通2377/tcp,7946/udp,4789/udp端口
$ firewall-cmd --zone=public --add-port=2377/tcp --permanent
$ firewall-cmd --zone=public --add-port=7946/tcp --permanent
$ firewall-cmd --zone=public --add-port=7946/udp --permanent
$ firewall-cmd --zone=public --add-port=4789/udp --permanent
# 重新加载生效
$ firewall-cmd --reload
# 查看
$ firewall-cmd --list-ports
清理上面创建的swarm集群和创建出来的网络
# 删除集群节点,因为上面初始化了,相对于删除了集群了,删除集群后会自动把swarm网络删掉,所以这里只需要手动删除docker_gwbridge。
$ docker swarm leave -f
$ docker network rm docker_gwbridge
以下操作在host1上执行
3)初始化一个swarm集群
$ docker swarm init --advertise-addr 192.168.0.113
# 查看集群
$ docker node ls
# 查看网络
$ docker network ls
3)创建 overlay network
$ docker network create --attachable -d overlay my-overlay
# 或者指定子网,不指定会随机生成一个子网
$ docker network create -d overlay --subnet=10.0.1.0/24 --gateway=10.0.1.1 --attachable my-overlay
# 查看
$ docker network inspect my-overlay
--attachable:允许集群服务间的容器交互连接或者独立的容器之间能够连接。swarm在设计之初是为了service(一组container)而服务的,因此通过swarm创建的overlay网络在一开始并不支持单独的container加入其中。但是在docker1.13, 我们可以通过“--attach” 参数声明当前创建的overlay网络可以被container直接加入。
4)把host2加入集群
# 在host1上执行,查看加入命令
$ docker swarm join-token worker
# 在host2上执行,把host2加入到swarm集群
$ docker swarm join --token SWMTKN-1-54jufnlpeihtnedmpsexqvayz2jbm8f78ijlt4pik7huie9bmr-djfn6m3lz143e0fyjbcocnqhl 192.168.0.113:2377
5)查看swarm集群
$ docker node ls
6)在host1 manager节点上创建一个容器busybox1,指定上面创建的overlay网络
$ docker run -itd --name=busybox1 --network=my-overlay busybox /bin/sh
再次查看网络,可以发现有了容器的IP及LB IP
$ docker network inspect my-overlay
7)在host2 worker节点上创建一个容器busybox2:
$ docker run -itd --name=busybox2 --network=my-overlay busybox /bin/sh
# 查看网络
$ docker network inspect my-overlay
8)在上面刚创建的2个容器内互相PING对方做测试
再ping外网
从上图看,既可以ping内网,也可以ping外网,得益于每个容器有两块网卡,一块内网通信,一块直接桥接到docker_gwbridge出外网。
根据上面讲解和实验,容器间的网络架构图如下:
其实从上图看,可能有朋友会发现,为啥有vxlan的标注,因为vxlan才是实体,overlay只是网络模型;一句话就是vxlan是overlay网络的一种实现,如果不清楚vxlan的,可以看这里。
其实可以查看my-overlay网络的具体信息,里面会有vxlan的一些参数
$ docker network inspect my-overlay
猜你喜欢
- 2024-10-14 Docker Overlay 网络学习 dockercompose 网络
- 2024-10-14 盘点c++几种常见的设计模式及具体实现
- 2024-10-14 Docker新手福音!这个开源控制面板让你更快上手Docker
- 2024-10-14 Docker-掌握这三种方法,创建自己的docker镜像
- 2024-10-14 docker 基础概念 docker基于什么
- 2024-10-14 小白也能轻松上手,深度体验绿联私有云DX4600 Docker功能
- 2024-10-14 一文带你了解docker常用命令 docker常用命令及参数
- 2024-10-14 Docker最佳实践的反模式 docker反向代理
- 2024-10-14 docker中容器如何实现通信 docker容器之间如何通信
- 2024-10-14 工程化Docker:确保应用程序的可靠性、可扩展性和可维护性
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)