docker swarm 网络实现

2019-04-26  本文已影响0人  lzp1234

前言

swarm创建得应用网络模式均为overlay。
swarm得网络需要拆成两部分来说:

环境

操作系统:centos7。
docker版本:18.09。
使用swarm启动一个应用(这里不再介绍如何启动,本文章提及得应用外部映射端口为31883)。

安装网络相关软件工具
yum install -y bridge-utils
yum install -y iptables

外部访问swarm应用得流量完整路径介绍

基础介绍:

docker得网络命名空间位于: /var/run/docker/netns/
使用方式为:

nsenter --net=/var/run/docker/netns/ingress_sbox ip a

与 ip netns除了进入命令不同,其它一致。

容器、ingress_sbox(docker swarm使用的网络命名空间)、ingress(docker swarm使用的网络命名空间)、以及创建的其它网络均在 netns 目录下。
注意 ingress网络命名空间的名称需要通过 docker network list 转换一下才能找到,如下图:

image.png
整体介绍:
  1. 流量首先到达宿主机

  2. 宿主机上得iptables将流量转发至 ingress_sbox网络命名空间。

  3. ingress_sbox 又将流量导向 ingress网络命名空间

  4. ingress 通过网桥、veth pair 与本机容器互联,通过vxlan 与其它物理主机的容器实现互联。

进一步介绍:
宿主机到ingress_box的流量路径。

在宿主机上执行:

iptables -t nat -S
image.png

上图可以看到,将流量转发至 172.18.0.2 。

查看路由信息:

route -n
image.png

上图可以看到,将流量发往 docker_gwbridge

查看网桥:

brctl show
image.png

上图可以看到,网桥中挂载了多个 veth pair。而这个 "veth2c615a1"与ingress_sbox中的某个网卡 是一组 veth pair。

至于其它的veth 开头的网卡,是容器直接使用这个网络时创建的。

ingress_sbox原理

ingress_sbox得eth0与ingress得veth0是一对veth pair。
ingress_sbox得iptables、ipvs、route结合将流量指向eth0,通过veth pair特性,流量进入ingress得veth0。

进入ingress_sbox 网络命名空间执行以下4个步骤:

  1. 在流量进入ingress_sbox,通过iptables的mangle表将报文打上mark。这里的mark是二进制,在ipvs中显示的十进制。
    命令参考:
iptables -t mangle -S
  1. ipvs 根据mark(十进制显示)将流量指向私网地址。
    命令参考(无此命令直接安装,包名: ipvsadm):
ipvsadm -Ln
  1. 结合路由可以看到将流量通过eth0发送出去。
    命令参考:
route -n
  1. iptables 的nat表,在将流量发送出去的同时修改了源ip,这样的目的是让包可以回来。
    命令参考:
iptables -t nat -S
ingress原理

ingress 中有一个网桥,网桥上连接着veth pair,而veth pair的另一端在容器中。
流量在到达ingress时,结合路由将流量发送到网桥上,流量到达网桥后,可以直接通过veth pair 特性进入到本机容器中。

如果容器不在本地机器上:
ingress中还有一个端口 vxlan0,vxlan0挂载在网桥上。在每一台物理机器上的ingress中都有一个vxlan0,通过此端口实现了不同物理主机的ingress上的网桥的互联,从而实现了overlay网络。

overlay具体实现原理

在ingress中实现了overlay,效果就是:在某台物理机的ingress中可以ping通其它物理上的容器overlay地址。也就是让所有overlay网络下的容器,即使不同物理机也能互相通信。

目前只知道是通过vxlan实现得overlay,具体实现原理还未清楚。TODO

扩展

1. 容器的网络命名空间在哪?
docker inspect 984 |grep SandboxID

通过此ID 可以在 /var/run/docker/netns/ 下找到对应的文件。
这就是此容器的网络命名空间。

注意事项

由于ingress_sbox会更改源ip为统一得源ip,因此一个swarm集群似乎只能承载60k tcp连接。
可能得解决方案:将源ip负载得形式更改为多个,成倍得提升tcp连接数。

上一篇 下一篇

猜你喜欢

热点阅读