Routing Mesh(路由网格)
个人理解,我们在常见服务的时候,使用-p 来映射端口,当创建完成后,我们可以使用任何一台docker swarm 节点的ip+port
来访问对应的服务。如下图(图片是网络资源,如有侵权,请告知,立马删除)
以上的图片也说明了一个问题,就是我们还要一个负载均衡器来均衡流量到不同的主机,如果没有这个负载均衡器,如果某台主机挂到了,那么访问这个主机+port的流量一样是挂掉的。所以还需要上层一个负载均衡器来负载流量到不同主机,然后主机上ingress网络在将request均衡到不同的container内。
具体网络流程如下图(来自网络,如有侵权,请告知,立马删除)
以下举例说明整个流程
场景:
swarm manager: 192.168.3.43
swarm worker : 192.168.3.42
docker service create --name nginx -p 80:80 --replicas 2 ningzaige2013/nginx:ds
使用如上的命令来创建一个nginx service
创建后
service VIP: 10.0.0.6
container in swarm manger(C1): 10.0.0.7
container in swarm worker (C2) : 10.0.0.8
当我们在浏览器上访问 http://192.168.3.43的时候
流程如下:
1. 首先流量从swarm manager 这台主机 192.168.3.43这个网卡进来,然后iptables PREROUTING 的规则有一条
我们可以看到当进来的流量目的端口是80的时候,会被dnat到172.18.0.2,这里我们需要知道172.18.0.2是谁的设备。这里需要知道的是,当我们docker swarm init后,会创建两个网络一个事ingress overlay 一个是docker_gwbridge.同时还会创建一个容器,这个容器的名字叫ingress_sbox,这个容器中会有两块网卡,一块在ingress overlay 网络中,一块是链接在docker_gwbridge 网桥上。而这个网卡的地址就是172.18.0.2.
2 .这里我们知道了流量会被发到ingress_sbox这个容器,但是这个容器,我们是不能直接用docker exec 进去的。但是我们可以进到这个容器的网络命名空间中去。
nsenter --net=/var/run/docker/netns/ingress-sbox
我们查看一下这个container中的iptables mangle表
我们PREROUTING这个hook点有一条当tcp dst port是80的时候,需要进行MARK 。mangle这个表大概做的事情,就是修改流量的内容。这里我们可以在主机上安装ipvsadm这个软件,来查看mark具体的功能。
0x101=257
可以看到 这条规则的目的是随机选择一个目的ip进行转发流量,同时做了Masq,就是使用10.0.0.2 这个地址。
当然这里看到有个weight,应该是可以设置权重来动态更改负载均衡的效果的。
这里我们可以在ingress-sbox的eth0网卡上抓包来验证我们这个观点
从以上的截图可以看到我们的观点是正确的,也就是说当我们用hostname+port来访问container服务的时候,最后相应服务的不一定是当前主机的container。
3. 接下来,我们假设负载均衡器选择10.0.0.7这个ip地址,然后我们从10.0.0.2 这台网卡出去。接下来会发生什么。
我们可以看到 10.0.0.2 这个网卡是veth类型的,我们来看下这个网卡的另一端在哪里
我们进去 overlay (ingress) 网络的命令空间中看下
nsenter --net=1-<ingress network id>
待续。。。。。