简介:
    image.png
    Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址

    在默认的Docker配置中,每个节点上的Docker服务会分别负责所在节点容器的IP分配,这样导致的一个问题是,不同节点上容器可能获得相同的内外IP地址,并使这些容器之间能够之间通过IP地址相互找到,也就是相互ping通

    Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信

    Flannel实质上是一种“覆盖网络(overlaynetwork)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持udp、vxlan、host-gw、aws-vpc、gce和alloc路由等数据转发方式,默认的节点间数据通信方式是UDP转发

    原理图:
    下方两图都是比较好的图解
    image.png
    image.png
    原理图解释说明

    1. 安装Flannel时会创建一个名为Flannel0的网桥,这个网桥的一端连接Docker0的网桥,另一端连接一个名为Flanneld的服务进程

    2. Flanneld守护进程:它需要连Etcd,利用Etcd来管理可分配的IP资源,同时监控Etcd中每个Pod的实际地址,将Docker0发给它的数据包装起来,利用物理网络的连接将数据包投递到目标Flanneld上,从而完成pod到pod之间的通信

    image.png
    通信原理

    1. 在发送端的node1节点上,数据请求从nginx容器(10.0.46.2:2379)发出后,首先经由所在主机的Docker0虚拟网卡(10.0.46.1)转发到Flannel0虚拟网卡(10.0.46.0)
    2. 接着Flannel服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的Flanneld服务,在此包中,包含有router-ip(宿主机源ip:192.168.8.227 ;宿主机目的ip:192.168.8.228),还有容器ip(source:10.0.46.2:2379dest:10.0.90.2:8080)等数据信息
    3. 然后在接收端node2节点上,数据到达以后被解包,直接进入目的节点的Flannel0虚拟网卡中(10.0.90.0),且被转发到目的主机的Docker0虚拟网卡(10.0.90.1),最后就像本机容器通信一样由Docker0路由到达目标 tomcat 容器(10.0.90.2:8080)

    特点:

    1. 使集群中的不同Node主机创建的Docker容器都具有全集群唯一的虚拟IP地址
    2. 建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器,覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络,覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离,在将封装的数据包转发到端点后,将其解封装
    3. 创建一个新的虚拟网卡Flannel0接收docker网桥的数据,通过维护路由表,对接收到的数据进行封包和转发(vxlan)
    4. Etcd保证了所有node上Flanned所看到的配置是一致的,同时每个node上的Flanned监听Etcd上的数据变化,实时感知集群中node的变化

    路由转发方式详解:
    image.png
    vxlan-两种模式

    1. vxlan:叠加网络模式,利用内核级别的VXLAN来封装host之间传送的包
    2. Directrouting:直接路由模式,当主机位于同一子网时,启用直接路由(类似host-gw),通过宿主机的物理网卡通信

    与UDP方式不同的是Docker0网桥被替换程了CNI网桥,容器的IP MAC信息被VxLan保存后,通过NAT,修改为Node的IP和MAC,从Node1传递到Node2,放到Flannel,删除掉外层,变回内存ip和mac,寻址到最终目的ip和地址

    下方两图都是比较好的图解
    image.png
    image.png
    host-gw

    1. host-gw: host-gw就是将子网保存的对那个ip换成节Node ip,将数据直接转发出去 ,直接路由模式,要求所有pod在同一个网段中,host-gw性能好,依赖少,并且易于设置

    image.png
    UDP

    1. UDP: 不可用于生产环境,仅在内核或网络无法使用VXLAN或 host-gw时,用 UDP 进行调试,数据从node1发送到node2的时候:在主机上有一系列的规则,当容器ip的目的地址匹配的时候,只能匹配的Flannel设备,数据包被转发到这个设备——-再匹配路由表,匹配到子网——-子网名称对应的ip保存在etcd中,Flannel设备查询etcd中子网对那个的ip,将数据转发到node2节点,数据发送的时候是将ip包以UDP的方式发送出去的

    总结:

    总的来说,Flannel更像是经典的桥接模式的扩展,我们知道,在桥接模式中,每台主机的容器都将使用一个默认的网段,容器与容器之间,主机与容器之间都能互相通信,要是,我们能手动配置每台主机的网段,使它们互不冲突,接着再想点办法,将目的地址为非本机容器的流量送到相应主机:如果集群的主机都在一个子网内,就搞一条路由转发过去;若是不在一个子网内,就搞一条隧道转发过去,这样以来,容器的跨网络通信问题就解决了,而Flannel做的,其实就是将这些工作自动化了而已

    优缺点:
    image.png

    优点:

    1. 集群中的不同Node主机创建的Docker容器都具有全集群唯一的虚拟IP地址。
    2. Etcd保证了所有node上Flanned所看到的配置是一致的,同时每个node上的Flanned监听Etcd上的数据变化,实时感知集群中node的变化

    缺点
    不支持pod之间的网络隔离,不支持网路策略( 可以达到多租户网络隔离,可以控制入网和出网流量,入网和出网ip访问的一种策略 )

    建议参考文献:https://www.cnblogs.com/goldsunshine/p/10740928.html