k8s中的网络组件.
    flannel为每个host分配一个subnet, 容器从这个subnet中获取ip.
    flannel中网络配置存放在etcd中.
    flannel网络包由beckend实现. 支持以下方式:
    UDP 就用纯粹的UDP报文进行传输,这种比VxLAN方式性能更差。因为它是用普通的UDP报文转发的,不是VxLAN专用的UDP报文转发的
    VxLan 默认 需要封装报文 如果源Pod所在的节点与目标Pod所在的节点在同一个二层网络中,就是在同一个网咯中,那么大家直接使用host-gw通信,但是假如源Pod所在的节点与目标Pod所在的节点不在同一个网络中,就是中间有路由的,那么就自动降级为VxLAN叠加隧道进行通信。整个通信过程目的终端不会感知到物理网络的存在。

    flannel - 图1
    host-gw 效率最高(不封装报文) 两个节点上的Pod各自拥有一个网段,我们把主机自己所在的网络接口当做是网关来使用。在物理机上创建一个虚拟接口,每一个Pod也有个虚拟接口,Pod的虚拟接口在传输报文时,不是通过隧道承载传送过去的,当它需要传输报文时,发现目标主机不是本地的,它把报文传给物理机上的虚拟接口,把它当做网关来用,这个网关看到报文后要查路由表,这个路由表中记录了到达哪个网络要发给谁。比如发给10.244.1.0网络的要发给对端主机的物理网卡,然后经过物理网卡就发出去了。对端的物理网卡收到后一看是本物理机的另外一块虚拟网卡接口,所以报文传给那个虚拟网卡接口,然后在传到到Pod的虚拟接口。这里面没有使用叠加,报文通过路由就到达对端主机了,把主机所在的节点所在的地址额外加一个接口当网关,但是这样子就使得路由表很大。这种方式比vxlan性能要好很多,几乎没有什么多余的开销,除了本地路由之外。但是默认没有使用这种方式,因为有个缺陷,要求k8s节点必须在同一个二层网络中,如果两台主机之间要有路由,就没办法定义清楚了,不知道发哪去了。

    flannel - 图2
    AWS VPC
    GCE

    flannel刚刚被发明出来的时候,Linux内核不支持VxLAN,Linux内核级没有VxLAN模块,而那个时候host-gw又有很高的门槛,所以早期flannel用的是UDP,最差的方式。因此在网上产生了一种偏见,认为flannel性能很差,现在使用host-gw方式的性能比calico性能都要好

    flannel启动过程:
    1.取出etcd中network配置
    2.划分subnet 并在etcd中进行注册
    3.将子网信息记录到/run/flannel/subnet.env中