docker swarm 网络架构
swarm网络
网络架构
Overlay Network:
Swarm使用Overlay网络来实现跨主机容器的通信。Overlay网络在每个节点上创建虚拟网络,用于连接不同主机上的容器。
优点:容器可以跨节点直接通信,简化了网络配置。
缺点:可能会增加一些网络开销,影响到延迟和吞吐量。
网络延迟
延迟来源:
数据包在跨节点传输过程中,会经过多个网络设备和链路,增加了通信延迟。
Overlay网络在封装和解封装数据包时也会引入额外的延迟。
(1) overlay 网络简介
overlay 网络,也称为重叠网络或覆盖网络,是一种构建于 underlay 网络之上的逻辑虚拟网络。即在物理网络的基础上,通过节点间的单播隧道机制将主机两两相连形成的一种虚拟的、独立的网络。
Docker Swarm 集群中的 overlay 网络主要是通过 iptables、ipvs、vxlan 等技术实现的、基于其本身通信需求的网络模型。
(2) overlay 网络模型
Docker Swarm 集群的 overlay 网络模型在创建时,会创建出两个网络:docker_gwbidge
网络与 ingress 网络。这就是典型的 overlay 网络——在宿主机的物理网络之上又创建出新的
网络。同时还创建出了 docker_gwbidge 网关与 br0 网关,及 ingress-sbox 容器。
当请求到达后会首先经由 docker_gwbidge 网关跳转到 ingress-sbox 容器,在其中具有当
前整个service的所有容器IP,在其中通过轮询负载均衡方式选择一个容器IP作为目标地址,
然后再跳转到 br0 网关。在 br0 网关中会根据目标地址所在主机进行判断。若目标地址为本
地容器 IP,则直接将请求转发给该容器处理即可。若目标地址非本地容器 IP,则会将请求经
由 vxlan 接口,通过 vxlan 隧道技术将请求转发给目标地址容器。
docker_gwbridg 网络
查看 docker_gwbridge 网络详情可以看到,docker_gwbridge 网络包含的子网为
172.20.0.0/16,其网关为 172.20.0.1。那么,这个网关是谁呢?
docker_gwbridge 的网络详情中的网关 172.20.0.1 是谁?
在宿主机中通过 ip a 命令查看宿主机的网络接口,可以看到 docker_gwbridge 接口的 IP
为 172.20.0.1。同时还看到,下面的 3 个接口全部都是连接在 docker_gwbridge 上的。
查看 docker_gwbridge 网络的容器的接口情况,可以看到这些容器中正好有接口与docker_gwbridge 网关中的相应接口构成 veth paire
到这里,不难发现docker_gwbridge 网络与容器的关系,当前节点创建一个容器,相应的就会创建一个虚拟网络对(veth paire),Veth设备的作用主要用来连接两个网络命名空间,如同一对网卡中间连着一条网线。
从这里看上去,容器与容器之间的通信可以通过这个veth paire进行通信
如何查看docker_gwbridge网络的ingress-sbox容器的接口情况呢?
每个容器都具有一个独立的网络命名空间,而每个 docker 主机中的网络命名空间,都是以文件的形式保存在目录/var/run/docker/netns 中。
通过 nsenter 命令可进入ingress-sbox命名空间并查看其接口情况。可以看到该命名空间中正好也存在接口与 docker_gwbridge 网关中的相应接口构成 veth paire。
我们前面已经说过ingress-sbox是管理整个service内容器ip的,这个时候他们就变成了
至此,docker swarm中docker_gwbidge网络与容器之间的关系已经浮出水面了 ,但还有一个小问题没有解答,我们在 docker_gwbridge的网络详情截图中明明看到ingress-sbox明明也是一个容器,为什么docker ps看不到它呢?
首先我们需要理解docker ps中的ps是什么,它是process status的缩写,它的意思是当前主机中真实存在的容器进程的状态。但是ingress-sbox 容器是由 overlay 网络虚拟出来的,并不是真实存在的进程,
所以通过 docker ps 命令是查看不到的。
ingress 网络
我们上面提到overlay 网络除了创建了 docker_gwbridge 网络外,还创建了一个 ingress 网络。
同样的,我们需要了解这个网络先去看它的网络详情
ingress 网络包含的子网为 10.0.0.0/24,其网关为 10.0.0.1。
同时还看到,该网络中也包含了 3 个容器,这 3 个容器与 docker_gwbridge 网络中的 3个容器是相同的容器,虽然 Name 不同,IP 不同,但容器 ID 相同。说明这 3 个容器都同时连接在 2 个网络中。
10.0.0.1是谁?我们提到过每个容器都具有一个独立的网络空间,而每个 docker 主机中的网络命名空间,都是以文件的形式保存在/var/run/docker/netns 目录中,不如去这里面找找答案看一下
一个个开始找,很幸运在第一个上就找到了
可以看到 2 号接口 br0 的 IP 为 10.0.0.1,即 ingress 网络的网关为 1-wjtggfss4z 命名空间中的 br0。同时还看到,br0 上还连接着 4 个接口。那么,都是谁连接在这 4 个接口上呢?那我们再回到容器去找
这个时候我们再回顾一下最上面的流程 br0网关的作用是将请求转发到容器
本地容器我们刚刚查看可以通过veth paire进行通信,那么非本地呢?如果他们都需要用到br0这个网关进行通信,他们会不会拥有同一个网络命名空间呢?去第二个节点上找,果然找到了
very nice 全部对上了又
虽然信息能够全部对上,但网络流程的关系我还是感觉有点模模糊糊。一个请求到底是怎么到宿主机,又到docker,再到容器的呢?
先看下宿主机的路由
请求过来默认都会走enp4s0这个接口
接口的地址就是我们常访问的地址,再看下路由转发表
DOCKER-INGRESS 路由链路中的 DNAT 映射规则中指出,对于任何源 IP,只要其访问端
口号为 9000,就会将其转换为 172.20.0.2:9000 的请求,即将请求转发到 172.20.0.2。那么请
求是如何到达 172.20.0.2 的呢?好像还是不太明白
再回去看宿主机的路由,又观察到一个熟悉的字段docker_gwbidge
可以看出,所有对 172.20.0.0/16 网络的请求,都需要经过 docker_gwbridge 接口,而该
接口连接的 IP 为 172.20.0.1。即 docker_gwbridge 接口会处理该请求。由一个网络去访问另
一个网络必须要经过该目标网络的网关。经前面的学习知道,docker_gwbridge 正好就是
172.20.0.0/16 网络的网关。
也就是说,客户端提交的 192.168.0.201:9000 的请求,经 docker_gwbridge 网关,被
路由到了 IP 为 172.20.0.2 的接口。那么谁的 IP 是 172.20.0.2 呢?经过前面网络基础信息查
看可知,docker_gwbridge 网络中包含 IP 为 172.20.0.2 的 ingress-sbox 容器。
docker swarm是有自己的负载均衡的,但是它在哪个环节实现的,我们之前一直没有仔细考虑过,当请求到了ingress-sbox之后,突然想起来这个容器的功能就是选择ip,那很可能负载均衡就是在这里实现的了。
ingress_sbox 的负载均衡
查看 ingress_sbox 的 mangle 表
mangle 表的主要功能是根据规则修改数据包的一些标志位,以便其他规则或程序可以利用这种标志对数据包进行过滤或路由。
该路由链中为任意源地址端口为 9000 的请求打了一个 MARK 标记 0x100,该 MARK 标记将被 IPVS 用于负载均衡。
查看 ingress_sbox 负载均衡规则
端口为 9000/9001 的请求被打上了一个数值为 256 的 MARK 标记,该标记通过 LVS 的 IPVS 的负载均衡,将该请求转发到了下面的 3 个 IP 接口,且这 3 个接口的权重 weight 是相同的,都是 1。这 3个 IP 接口具有一个共同点,全部来自于 10.0.0.0/24 网络。那么,如何能到达10.0.0.0/24 网络呢?
查看命名空间路由
通过前面查找的资料可知,若要由一个网络转发到另一个网络,则必须要先到目标网络的网关。由于目前尚在 172.20.0.0/16 网络,预转发到 10.0.0.0/24 网络,所以必须要先到 10.0.0.0/24网络的网关 10.0.0.1,即 br0。
但存在的问题是,请求目前尚在 ingress_sbox 命名空间中,怎样才能从 ingress_sbox 命名空间中出去,然后跳转到 br0 呢?查看 ingress_sbox 命名空间中的静态 IP 路由:
可以看出,所有对 10.0.0.0/24 网络的请求,都需要经过 eth0 接口,而该接口连接的 IP为 10.0.0.2。在 ingress_sbox 命名空间中 eth0 接口就是 8 号接口,其 veth pair 接口就是 br0中的 9 号接口。所以,ingress_sbox 命名空间中请求经由 8 号接口跳转到了 br0 网关。
br0 网关的处理
到达 br0 后,再将请求从 br0 的哪个接口转发出去,是由目标地址决定的,而目标地址就是 IPVS 负载均衡选择出的 IP。请求到达 br0 后,首先会将目标地址与本地的 task 容器地址进行比较,若恰好就是当前宿主机中的 task 容器的 IP,那么直接将请求通过相应的接口将其转发;若不是当前宿主机中的 IP,则会将请求转发到 vxlan0 接口。经过 vxlan0 接口,可经由 VXLAN 技术将请求通过“网络隧道”发送到目标地址。
VXLAN 是一种隧道技术,可以将不同协议的数据包重新封装后发送。新的包头提供了路由信息,从而使被封装的数据包在隧道的两个端点间通过公共互联网络进行路由。被封装的数据包在公共互联网络上传递时所经过的逻辑路径称为隧道。一旦到达网络终点,数据将被解包并转发到最终目的地。
整体架构图:
标签:网关,容器,ingress,架构,网络,接口,swarm,docker From: https://blog.csdn.net/weixin_41438870/article/details/139916754