Swarm网络分析(2)

首先创建swarm集群:

docker swarm init 并在work节点上执行docker swarm join 加入集群

创建网络:docker netwrok create mynet -d overlay

创建服务:docker service create --name web --network mynet -p 8080:80 --replicas 2 nginx:latest

注意:如果在work节点无法下载镜像,会导致work节点启动不起来

查看容器状态

查看网络:

主节点:

Swarm网络分析(2)_第1张图片

work节点:

Swarm网络分析(2)_第2张图片

他们是一样的

服务启动起来之后,在node1 和node2上都可以访问到容器这个可以理解,但是我们访问node3 ,也能访问到容器

Swarm网络分析(2)_第3张图片

在node1 和node2上,有容器运行,并且都监听了8080 端口:

在node3 上,没有容器运行,但是也监听了8080 端口:

那么我们分别看下node1,和node3 的iptables:

在manager节点上查看iptables:

Swarm网络分析(2)_第4张图片

这里需要注意的是最后有个 DOCKER-INGRESS: 吧所有的8080端口的包都转发致了172.18.0.2:8080端口

这里还需要注意一点是POSTROUTING里面:有一条 docker_gwbridge网桥的流量都nat转换为本机ip也就是通过nat修改了地址的(MASQUERADE)

那我们在work节点看下有没有:

Swarm网络分析(2)_第5张图片

也是一样,都吧8080端口的包转发到了172.18.0.2:8080

那么这个172.18.0.2是什么地址呢:

我们通过ifconfig 可以看到 docker_gwbridge的网段是172.18.0.2

Swarm网络分析(2)_第6张图片

然后查看网桥

上面插了一个网卡:veth84f003c

我们查看docker的网络详情

Swarm网络分析(2)_第7张图片

docker_gwbridge上面插了一个容器网卡, ingress-sbox 这个其实是一个网络命名空间:

通过docker run -it --rm -v /var/run/docker/netns:/netns --privileged=true nicolaka/netshoot nsenter --net=/netns/ingress_sbox sh进入命名空间

这个命名空间有两个网卡:

Swarm网络分析(2)_第8张图片

一个是10.255.0.5/16 一个是172.18.0.2/16 而宿主机上172.18.0.2则是docker_gwbridge的网段,而第一个地址其实是连接到了ingress 这个后面说

并且这个172.18.0.2网络地址,正是宿主机8080端口转发的地址.

Swarm网络分析(2)_第9张图片

这个网络命名空间里面:将进来的8080端口的统一做了一个MARK,值为0x101也就是十进制的257

而下面的ipvsadm显示将257的做了一个负载均衡

那么也就是说,外面进来的地址,通过docker_gwbridge转发到了ingress_bos ,然后通过ipvs做了一个负载均衡

在运行了服务容器的节点上进入ingress_box命名空间查看:

Swarm网络分析(2)_第10张图片

也是一样的结果

但是这里有个问题:负载均衡的地址是10.255.0.7和10.255.0.8 这两个地址到底是什么,还有就是上面的ingress 这个网络到底是啥?

首先这里在提一下ingress ,这是一个网桥,网桥的作用就是根据mac地址进行请求转发,比如docker0网桥,单机docker容器的通信就是靠他来进行转发,容器的网络设备是一对veth设备,

一端在容器内,一段插到docker0,这样,容器向容器内网络命名空间网络设备发送的包都会出现在docker0 上,而docker0根据ip地址和mac地址进行转发,就实现了容器间的通信

那么这里的ingress网络,是一个overlay网络,overlay是一个覆盖网络,基于linux的vxlan在三层网络上组成的二层网络,我们看到docker_gwbridge的驱动是local,也就是说他是一个本地的网络设备,

而ingress是overlay网络,也就是说我们在本地找不到这个设备,但是到达ingress的请求都会被封vxlan的请求头以及解封vxlan的请求,进行转发

我们查看ingress详情:

Swarm网络分析(2)_第11张图片

可以看到,他的网段是10.255.0.0/16而接入他的有两个容器,一个是ingress-box,一个是web.2的一个容器,他的ip是10.255.0.8,下面的peers是集群的所有节点

那么也就是说,接入这个ingress网络的有两个容器,一个是ingress-sbox ,一个是web.2容器

我们的web.2正是在node1 节点上,而如果我们在node2上查看ingress详情:

Swarm网络分析(2)_第12张图片

如果我们查看docker_gwbridge详情可以看到上面是有一个ingress-sbox的而他的地址,正是172.18.0.2,并且在所有节点上,这个地址都是不变的,下面分别是node1和node2

Swarm网络分析(2)_第13张图片
Swarm网络分析(2)_第14张图片

那么到此为止:

外面来的请求会根据iptables规则,转发到172.18.0.2来处理,172.18.0.2则是ingress_sbox网络空间,这个会根据端口来吧流量打上标签,然后根据标签进行负载均衡转发

转发的地址则是各个节点的ingress地址,

172.168.137.0/24 网段是宿主机网段

172.18.0.0/16网段是docker_gwbridge网段

10.255.0.0/16 是ingress网段

10.0.0.0/24 是mynet网段

ingress_sbox有两个网卡,一个插在docker_gwbridge上,一个插在ingress上

而每个容器也有两个网卡,一个插在docker_gwbridge上,一个插在mynet上

Swarm网络分析(2)_第15张图片

IP 情况:

ingress_sbox:

宿主机

192.168.137.131

192.168.137.132

192.168.137.133

docker_gwbridge

172.18.0.1/16

172.18.0.1/16

172.18.0.1/16

ingress

10.255.0.1/16

10.255.0.1/16

10.255.0.1/16

mynet

10.0.0.1/16

10.0.0.1/16

10.0.0.1/16

ingress_sbox

10.255.0.3/16 172.18.0.2/16

10.255.0.4/16 172.18.0.2/16

10.255.0.5/16 172.18.0.2/16

web

10.255.0.2/16 10.0.0.4/24

10.255.0.7/16 10.0.0.3/24

ip route(宿主机)

172.18.0.0/16 docker_gwbridge处理

172.18.0.0/16 docker_gwbridge处理

172.18.0.0/16 docker_gwbridge处理

ip tables(宿主机 nat)

tcp dpt:8080 to 172.18.0.2:8080

tcp dpt:8080 to 172.18.0.2:8080

tcp dpt:8080 to 172.18.0.2:8080

ip route(ingress sbox)

10.255.0.0/16 -> eth0(10.255.0.3)

172.18.0.0/16 -> eth1(172.18.0.2)

10.255.0.0/16 -> eth0(10.255.0.4)

172.18.0.0/16 -> eth1(172.18.0.2)

10.255.0.0/16 -> eth0(10.255.0.5)

172.18.0.0/16 -> eth1(172.18.0.2)

ip tables(ingress sbox)

tcp dpt:8080 MARK set 0x100

dst 10.255.0.6 MARK set 0x100

tcp dpt:8080 MARK set 0x100

dst 10.255.0.6 MARK set 0x100

tcp dpt:8080 MARK set 0x100

dst 10.255.0.6 MARK set 0x100

ipvsadm(ingress sbox)

256 -> 10.255.0.2 & 10.255.0.7

256 -> 10.255.0.2 & 10.255.0.7

256 -> 10.255.0.2 & 10.255.0.7

那么在mynet网域内,访问172.18.0.2则会进入到ingress_sbox,然后进行标记负载均衡分发

外网访问只能通过宿主机的映射端口来进行访问,宿主机收到请求走iptables请求转发,给172.18.0.2那么又是走到上面的逻辑

那么留下一个问题:mynet是如何处理请求的:

请求交给172.18.0.2之后,会通过ipvs进行负载均衡,负载的节点ip是10.255.0.2 & 10.255.0.7,这个地址是mynet的地址,所以这个流量会根据iproute规则给mynet处理,mynet则是通过vxlan来进行分包发送给对应的地址,

也就是说容器启动后实际有三个网卡,一个连接到ingress 用于容器间通信,一个连接到docker_gwbridge用于访问外网,一个是加入了我们自己创建的网络mynet也是用于荣期间通信,ingress和mynet的区别是 mynet存在dns解析即服务发现功能

容器上有三个网络设备:

一个是连接docker_gwbridge的veth设备,用于容器访问外网

一个是接入mynet的 vtep 设备(vxlan),用于通过服务名访问(即服务发现),比如两个service, web 和redis,如果他们需要互相访问,则可以加入到同一个网络,然后直接通过服务名即可访问

一个是接入ingress的vtep设备(vxlan),用于容器之间的访问,以及外网访问的负载均衡

那vxlan是如何工作的呢:

Swarm网络分析(2)_第16张图片

这里借一张图:

Swarm网络分析(2)_第17张图片

实例文章:https://www.cnblogs.com/lkun/p/8034039.html

你可能感兴趣的:(Java从开发到设计,docker,运维,网络)