欢迎大家来到IT世界,在知识的湖畔探索吧!
阅读本文,你将了解以下内容
- Docker 下多主机容器互相访问原理
- docker 如何配置 flannel
- flannel的工作原理
前言
在上一篇文章 Docker网络这样理解会更简单(一) 中介绍了容器在单机内的互相通信原理,涉及到网桥、VethPair、路由等相关的内容,这一篇我们在此基础上,再来了解下Docker在跨主机的通信原理。
跨网络方案
在前面我们提到过,在同一台主机内的容器,通过 docker0 进行通信,那有没有办法将这个docker0再进行提升一个层级,成为以下的架构方案呢?
上面的方案其实就是通过软件构建一个覆盖在主机网络之上,可以将所有容器进行连通的虚拟网络,这也就是跨主机网络的核心,称为覆盖网络(overlay network)。
在目前容器主流的覆盖网络方案中,不得不提的是 Flannel, 它是CoreOS 公司主推的方案。
服务器准备 |
|||
节点 |
容器名称 |
容器ip |
网桥 |
NodeA |
containerA |
10.2.5.2 |
10.2.5.1/24 |
NodeB |
containerB |
10.2.14.2 |
10.2.14.1/24 |
docker 接入 flannel
- 从 coreOs 下载 etcd(3.5.7) 和 flannel(0.21.1) 的安装包,分别安装
- etcd(192.168.136.128:2379)
- 在启动 flannel 之前,在 etcd 创建对应的配置
etcdctl --endpoints http://192.168.136.128:2379 put /coreos.com/network/config '{"Network":"10.2.0.0/16","SubnetLen":24,"SubnetMin":"10.2.1.0","SubnetMax":"10.2.20.0","Backend":{"Type":"UDP"}}'
欢迎大家来到IT世界,在知识的湖畔探索吧!
- 启动flannel,分别在NodeA 和 NodeB 上启动,会生成/run/flannel/subnet.env,配置当前主机的网段
欢迎大家来到IT世界,在知识的湖畔探索吧!flanneld -etcd-endpoints=http://192.168.136.128:2379 -iface=ens33 -etcd-prefix=/coreos.com/network
- 在NodeA 上查看路由规则
Destination Gateway Genmask Flags Metric Ref Use Iface
default gateway 0.0.0.0 UG 100 0 0 ens33
10.2.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel0
10.2.5.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0
- docker 配置bip,修改 /usr/lib/systemd/system/docker.service的配置, 红色部分和当前机器下flannel的配置中的FLANNEL_SUBNET->bip , FLANNEL_MTU->mtu
ExecStart=/usr/bin/dockerd -H fd:// –containerd=/run/containerd/containerd.sock —bip=10.2.14.1/24 –mtu=1450
至此,当我们在NodeA上ping 10.2.14.2 时,也是可以通的
Flannel 原理介绍
Flannel 项目本身也只一个架构方案,它的实现依赖于三种后端实现: VxLan、host-GW、UDP。
而在这三种方案中,UDP 是最早支持的,但它也是性能最差的(为什么差,在后面的分析中可以得到结论)。但从这个实现方案入手是最直接和最容易理解的。以下内容我们就从UDP的实现方式进行分析。
要实现 ContainerA -> ContainerB
由于 10.2.14.2 不在 NodeA docker0的网段里,所以这个ip要按默认的路由规则, 从上篇文章知道,会经过容器的网关进行docker0网桥,从而出现在宿主机里。再经过宿主机上的路由机制。Flannel 机制会为每个主机分配一个subnet(子网), Flannel 介绍请查看 5分钟带你了解Kubernetes网络之flannel,并为宿主机创建出了一系列的路由规则.
[root@master flannel]# ip route
default via 192.168.136.2 dev ens33 proto dhcp metric 100
10.2.0.0/16 dev flannel0
10.2.5.0/24 dev docker0 proto kernel scope link src 10.2.5.1
192.168.136.0/24 dev ens33 proto kernel scope link src 192.168.136.133 metric 100
可以看到 10.2.14.2,会匹配到第二条规则,从而进入到 flannel0 设备中,这是一个tunnel 设备,是工作在三层的虚拟网络设备,它只是用作操作系统与用户应用之间进行ip包传递。
当操作系统将ip包发送flannel0 设备后,flannel0 会把这个包转交给创建这个设备的应用程序,即是 Flannel 进程,这是一个内核态向用户态的一个过程。
同样的,Flannel进程向 flanne0设备进行发送IP包时,这个IP包就会进入宿主机的网络栈里了,依据路由表的规则进行处理,这是从用户态到内核态的一个过程。
大致整理下应该是: 容器发送Ip包,经过docker0,进入宿主机网络栈,查询路由表规则进入到flannel0设备后,会经过Flannel 进程,Flannel 确认是 10.2.14.2 地址,会把数据发往到 Node2。
在这里,Flannel 进程是如何将10.2.14.2 这个地址与 Node2 进行匹配呢?
在 Flannel 架构这篇文章中,有提到,Flanneld在创建时候,就会给主机分配一个子网,这台主机上创建的容器都是属于这个子网,我们可以 etcd 中查看节点的信息
欢迎大家来到IT世界,在知识的湖畔探索吧![root@k8s-node1]# ./etcdctl --endpoints=http://192.168.136.128:2379 get /coreos.com/network/subnets --prefix
/coreos.com/network/subnets/10.2.14.0-24
{"PublicIP":"192.168.136.128","PublicIPv6":null}
/coreos.com/network/subnets/10.2.5.0-24
{"PublicIP":"192.168.136.133","PublicIPv6":null}
在Flannel 进程获取到这个ip包时,会获取对应网段的配置信息,从而可以拿到对应的ip地址,将数据包发出去,而数据是通过Flannel 进程的端口8285进行数据接收,之后再将数据包进入到宿主机的网络栈,再通过路由规则将数据进入 flannel0设备,再给docker0 。
在Node2 上的路由信息也是类似的
[root@k8s-node1]# ip route
default via 192.168.136.2 dev ens33 proto dhcp metric 100
10.2.0.0/16 dev flannel0
10.2.14.0/24 dev docker0 proto kernel scope link src 10.2.14.1
Flannel UDP大致流程如下:
该流程里,可以看到在内核和用户态,在一个节点上发送过程中,就会经过三次
- 用户容器-> docker0
- 数据包-> flanneld
- flanneld 封装好数据包-> eth0
这也是上面提到UDP的方式存在的性能问题所在,在用户态和内核态之间在几次的切换,代价是很大的,那有什么办法进行优化呢?先给出答案,就是 VxLan, 下一节会再次展开。
除了flannel 之外,你还有处理过哪些方式的覆盖网络方案呢?
#头条创作挑战赛#
#把地球的故事讲给宇宙#
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/22778.html