相关概念:
node
#udp工做模式用到的docker
TUN设备:是一种工做在三层(网络层)的虚拟网络设备;主要做用是,在内核和应用程序间传递IP包;数据库
flannel0:是由flanneld建立的TUN设备;bash
#vxlan工做模式用到的网络
VTEP设备:它是在二层进行封装和解封装操做ide
flannel.1:是由flanneld建立的VTEP设备,.1(VNI)的做用是让VTEP设备识别数据帧是否是由本身处理的标识优化
#flannel进程spa
subnet:子网(flannel会为每一个节点分配一个子网,保存在etcd中)orm
flanneld:负责子网的路由信息,在每台node上生成路由信息blog
flannel的工做模式:overlay(叠加)网络
1.UDP(最先出现的工做模式,效率最低的一种)
2.VxLAN(Virtual Extensible LAN,虚拟可扩展局域网,Linux内核自己支持的网络虚拟化技术)
3.host-gw(效率最高,不能跨网段)
flannel工做示例:如下2个container须要跨主机通讯
Node1的容器container-1的IP:100.96.1.2
Node2的容器container-2的IP:100.96.2.3
UDP工做模式:须要在用户态和内核态之间切换
查看node1上的路由;
# 在 Node 1 上 $ ip route default via 10.168.0.1 dev eth0 100.96.0.0/16 dev flannel0 proto kernel scope link src 100.96.1.0 100.96.1.0/24 dev docker0 proto kernel scope link src 100.96.1.1 10.168.0.0/24 dev eth0 proto kernel scope link src 10.168.0.2
能够看到container-1须要访问container-2时,须要经过第一条路由规则(经过flannel0),而后交给flanneld处理;
数据包在通过flanneld处理完成以后,交由第三条路由规则(经过eth0)发出;
数据包走向过程:能够看到有3次的用户态和内核态的数据拷贝
第一次:用户态的容器进程发出的 IP 包通过 docker0 网桥进入内核态;
第二次:IP 包根据路由表进入 TUN(flannel0)设备,从而回到用户态的 flanneld 进程;
第三次:flanneld 进行 UDP 封包以后从新进入内核态,将 UDP 包经过宿主机的 eth0 发出去。
注:因为屡次发生了用户态到内核态的切换,这是形成效率低的缘由,也是优化的重点;
VxLAN工做模式:直接在内核态完成数据包的封装
在vxlan模式下,会建立一个名字为flannel.1的VTEP设备;
此设备的做用是在内核中将收到的IP包进行封装,发送给目的VTEP设备;
问:要发送给目的VTEP设备就须要知道目的VTEP设备的MAC地址,如何知道呢?
答:在新node启动flanneld时,会自动在已有的node上记录新node的flannel.1网段和MAC地址(经过ip neigh查看)
flannel.1知道了目的VTEP设备的IP段和MAC地址,就能够在内核态进行封包工做了;
[root@node03 ~]# ip neigh show dev flannel.1 172.20.0.0 lladdr 9e:24:d0:e5:55:04 PERMANENT 172.20.3.0 lladdr 02:12:d3:96:d3:a1 PERMANENT 172.20.1.0 lladdr 3a:cb:a3:a0:48:29 PERMANENT 172.20.2.0 lladdr 26:3b:4e:6e:7c:69 PERMANENT
问:知道了目的VTEP设备的MAC后,数据包最终要发给哪台物理机呢?
答:flannel.1转发的依据,来自于一个叫做FDB的转发数据库(由flanneld进程维护),能够经过bridge fdb命令查看;
此转换数据库记录了要访问目标VTEP设备的MAC地址,所在真实机器的IP;
[root@node01 ~]# bridge fdb show dev flannel.1 a6:23:df:7c:e5:10 dst 192.168.10.107 self permanent 02:12:d3:96:d3:a1 dst 192.168.10.53 self permanent 9e:24:d0:e5:55:04 dst 192.168.10.103 self permanent 3a:cb:a3:a0:48:29 dst 192.168.10.104 self permanent
在目标node收到数据包解封后,根据VNI=1的值,来决定是否是由flannel.1进行处理(拆包操做),并最终交由docker0处理;
特别注意:docker0网桥的地址范围必须是Flannel为宿主机分配的子网的子网;这样在经过flannel0或者flannel.1设备后,才会交给docker0处理;
总结:
1.vxlan模式经过建立的flannel.1设备,在内核态完成数据封装和解封,提升转发效率;
2.新节点加入flannel网络时,会在老的flannel节点增长到新节点的flannel.1设备的网段信息、mac地址信息、所在物理节点的ip(由flanneld进程维护)
3.经过知道路由信息、mac地址信息、物理ip(经过bridge fdb查看)后就能够开始数据包的封装操做;
host-gw工做模式:无须要封包、解包操做,效率最高
host-gw原理:其实就是将每一个flannel的子网的下一跳,设置成该子网对应的宿主机的IP地址(路由规则,route -n查看);
host-gw经过host-gw的方式,实现了将数据包经过路由规则直接转发,而无须进行封包、解包;
host-gw的核心:在于IP包在封装成帧发送出去的时候,会使用路由表的“下一跳”来设置目的MAC地址;因为经过二层网络到达目的宿主机;
因此:host-gw模式必需要求集群宿主机之间是二层连通的;
经过路由规则进行转发示意图: