Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来讲,它的功能是让集群中的不一样节点主机建立的Docker容器都具备全集群惟一的虚拟IP地址。html
在默认的Docker配置中,每一个节点上的Docker服务会分别负责所在节点容器的IP分配。这样致使的一个问题是,不一样节点上容器可能得到相同的内外IP地址。并使这些容器之间可以之间经过IP地址相互找到,也就是相互ping通。node
Flannel的设计目的就是为集群中的全部节点从新规划IP地址的使用规则,从而使得不一样节点上的容器可以得到“同属一个内网”且”不重复的”IP地址,并让属于不一样节点上的容器可以直接经过内网IP通讯。docker
Flannel实质上是一种“覆盖网络(overlaynetwork)”,也就是将TCP数据包装在另外一种网络包里面进行路由转发和通讯,目前已经支持udp、vxlan、host-gw、aws-vpc、gce和alloc路由等数据转发方式,默认的节点间数据通讯方式是UDP转发。网络
1.使集群中的不一样Node主机建立的Docker容器都具备全集群惟一的虚拟IP地址。架构
2.创建一个覆盖网络(overlay network),经过这个覆盖网络,将数据包原封不动的传递到目标容器。覆盖网络是创建在另外一个网络之上并由其基础设施支持的虚拟网络。覆盖网络经过将一个分组封装在另外一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后,将其解封装。并发
3.建立一个新的虚拟网卡flannel0接收docker网桥的数据,经过维护路由表,对接收到的数据进行封包和转发(vxlan)。测试
4.etcd保证了全部node上flanned所看到的配置是一致的。同时每一个node上的flanned监听etcd上的数据变化,实时感知集群中node的变化。spa
1.flannel利用kubernetes Api经过ETCD存储整个集群的网络配置,根据配置记录集群使用的网段设计
2.flannel在每一个主机上英雄flanneld做为agent,它会为所在主机从集群的网络地址空间中获取一个小网段subnet,本主机内全部容器IP将从中分配3d
1)Node01节点
2)Node02节点
在flannel network中,每一个Pod都会分配一个惟一的IP地址,且每一个k8s Node的subnet不重叠
1.flanneld将本机获取的subnet以及主机之间通讯的public ip经过etcd存储起来,须要时发给相应模块
2.flanneld经过各类backend mechanism,如vxlan、udp等跨主机转发容器之间的网络流量,完成容器之间的跨主机通讯
1.cni0:网桥设备,每建立一个Pod都会建立一对veth pair,其中一端是pod的eth0,另外一端是cni0网桥中的端口(网卡),Pod中从eth0的流量都会发送到cni端口(网卡)上
Cni0设备获取到的地址,是分配到本机网段的第一个IP
2.Flannel.1:overlay网络的设备,用来进行vxlan的报文处理(封包和解包);不一样node之间的Pod数据流量都从overlay设备以隧道的形式发送到对端
3.flanneld:flannel会在每一个主机运营flanneld做为agent,它会会主机在集群网络地址空间中获取一个小网段,本机内全部容器的IP地址都从中分配;
同时flanneld会监听etcd,为flannel.1设备提供封装时必要的mac、ip等网络数据信息
1.pod中产生数据,根据pod的路由信息.将数据发送到cni0
2.cni0根据节点的路由表,将数据发送到隧道设备flannel.1
3.flannel.1查看数据包的目的IP,从flanneld获取对端隧道设备的信息,封装数据包
4.flannel.1将数据发送给对端设备,对端节点的网卡接收到数据包,发现是overlay数据包,解开外层封装.并发送内层封装到flannel.1设备
5.flannel.1查看数据包,根据路由表匹配,将数据发送给cni0设备
6.cni0匹配路由表,发送数据给网桥上对应的端口
测试Node1的Pod和Node2的Pod通讯流程
Node1上的PodIP是:10.244.1.3,命名为Pod1
Node2上的PodIP是:10.244.2.2,命名为Pod3
1)Pod1能Ping通Pod3
2)Ping包的dst ip为10.244.2.2,根据路由表匹配到第二条路由表项,去往10.244.0.0/16的包都转发给10.244.1.1
3)去宿主机Node1上查看cni0的IP地址是 10.244.1.1
1)当icmp包到达cni0后,cni发现dst ip为10.244.2.2,cni根据路由表来查找匹配项目
根据最小匹配原则,匹配到图上的一条路由表,去往10.244.2.0网段的包,发送到10.244.2.0网关,网关设备是flannel.1
flannel .1为vxlan设备,当数据包来到flannel.1时,须要将数据包封装起来,此时的dest ip为10.244.2.2,src ip为10.244.1.3,数据包须要知道10.244.2.2的mac地址.此时flannel.1不会发送arp请求去得到10.244.2.2的mac地址,而是由Linux kernel将一个"L3 miss"事件请求发送给用户空间的flanned程序.flanneld程序收到内核的请求事件后,从etcd查找可以匹配该地址的子网的flannel.1设备的mac地址;flannel在为node分配ip网段时记录了全部的网段和mac等信息,因此能知道,交互流程以下图:↓↓↓
flanneld将查询到的信息放入master node host的arp cache表中
此时,vxlan的内层数据包就完成了封装,格式以下所示
简单总结这个流程
当内核得到了发往机器的IP地址后,arp获得mac地址,以后就能完成vxlan的外层封装
Node节点的eth0网卡接收到vxlan数据包,kernel将识别出这事一个vxlan数据包,将包拆开后转给节点上的flannel.1设备,这样数据包就从发送节点到达目的节点,flannel.1将收到这样一个数据包
目的地址为10. 244.2.2,flannel.1查找本身的路由表(node02上的flannel.1),根据路由表完成转发
根据最小匹配原则,flannel.1将去往10.244.2.0的流量转发到cni0上去
cni0是一个网桥设备.当cni0拿到数据包后,经过veth pair,将数据发送给pod.
1)查看node2节点中的网桥
2)在node2节点上经过arp解析能够看出,10.244.2.2的mac地址为:c2:33:c5:49:c0:0d
3)该地址为pod的网卡eth0的地址(node2的容器)
经过以上能够看出,cni0经过veth pair把流量转发给Pod3
简单总结cni0转发流量的原理