• Kubernetes网络组件对比


    Flannel网络

    简介

    flannel是CoreOS提供用于解决Dokcer集群跨主机通讯的覆盖网络工具。它的主要思路是:预先留出一个网段,每个主机使用其中一部分,然后每个容器被分配不同的ip;让所有的容器认为大家在同一个直连的网络,底层通过UDP/VxLAN等进行报文的封装和转发。

    IP地址管理

    flannel会利用Kubernetes API或者etcd用于存储整个集群的网络配置,flannel会在每个主机中运行flanneld作为agent,它会为所在主机从集群的网络地址空间中,获取一个小的网段subnet,本主机内所有容器的IP地址都将从中分配。然后,flanneld再将本主机获取的subnet以及用于主机间通信的Public IP,同样通过kubernetes API或者etcd存储起来。

    最后,flannel利用各种backend mechanism,例如udp,vxlan等等,跨主机转发容器间的网络流量,完成容器间的跨主机通信。

    支持的网络模式

    UDP: 使用用户态udp封装,默认使用8285端口。由于是在用户态封装和解包,性能上有较大的损失。

    VXLAN: vxlan封装,需要配置VNI,Port(默认8472)和GBP; 是Linux内核本身支持的一种网络虚拟化技术,是内核的一个模块,在内核态实现封装解封装,构建出覆盖网络,其实就是一个由各宿主机上的Flannel.1设备组成的虚拟二层网络,由于VXLAN由于额外的封包解包,导致其性能较差;VXLAN Directrouting模式也支持类似host-gw的玩法,如果两个节点在同一网段时使用host-gw通信,如果不在同一网段中,即 当前pod所在节点与目标pod所在节点中间有路由器,就使用VXLAN这种方式,使用叠加网络

    Host-gw: 直接路由的方式,将容器网络的路由信息直接更新到主机的路由表中,仅适用于二层直接可达的网络 推荐使用,效率极高

    不同网络模式下数据包流向

    UDP模式

    img

    1. 容器直接使用目标容器的ip访问,默认通过容器内部的eth0发送出去。

    2. 报文通过veth pair被发送到vethXXX。

    3. vethXXX是直接连接到虚拟交换机docker0的,报文通过虚拟bridge docker0发送出去。

    4. 根据路由表,外部容器ip的报文都会转发到flannel0虚拟网卡,这是一个P2P的虚拟网卡,然后报文就被转发到监听在另一端的flanneld。

    5. flanneld通过etcd维护了各个节点之间的路由表,把原来的报文UDP封装一层,通过配置的iface发送出去

    6. 报文通过主机之间的网络找到目标主机。

    7. 报文继续往上,到传输层,交给监听在8285端口的flanneld程序处理。

    8. 数据被解包,然后发送给flannel0虚拟网卡。

    9. 查找路由表,发现对应容器的报文要交给docker0。

    10. docker0找到连到自己的容器,把报文发送过去。

    vxLan模式

    img

    1. 源容器veth0向目标容器发送数据,根据容器内的默认路由,数据首先发送给宿主机的docker0网桥

    2. 宿主机docker0网桥接受到数据后,宿主机查询路由表,pod相关的路由都是交由flannel.1网卡,因此,将其转发给flannel.1虚拟网卡处理

    3. flannel.1接受到数据后,查询etcd数据库,获取目标pod网段对应的目标宿主机地址、目标宿主机的flannel网卡的mac地址、vxlan vnid等信息。然后对数据进行udp封装, 完成以上udp封装后,将数据转发给物理机的eth0网卡

    4. 宿主机eth0接收到来自flannel.1的udp包,还需要将其封装成正常的通信用的数据包,为它加上通用的ip头、二层头,这项工作在由linux内核来完成。通过此次封装,一个真正可用的数据包就封装完成,可以通过物理网络传输了

    5. 目标宿主机的eth0接收到数据后,对数据包进行拆封,拆到udp层后,将其转发给8427端口的flannel进程

    6. 目标宿主机端flannel拆除udp头、vxlan头,获取到内部的原始数据帧,在原始数据帧内部,解析出源容器ip、目标容器ip,重新封装成通用的数据包,查询路由表,转发给docker0网桥

    7. 最后,docker0网桥将数据送达目标容器内的veth0网卡,完成容器之间的数据通信

    host-gw模式

    hostgw是最简单的backend,它的原理非常简单,直接添加路由,将目的主机当做网关,直接路由原始封包。例如,我们从etcd中监听到一个EventAdded事件:subnet为10.1.15.0/24被分配给主机Public IP 192.168.0.100,hostgw要做的工作非常简单,在本主机上添加一条目的地址为10.1.15.0/24,网关地址为192.168.0.100,输出设备为上文中选择的集群间交互的网卡即可。对于EventRemoved事件,删除对应的路由即可。

    img

    1. 源容器veth0向目标容器发送数据,根据容器内的默认路由,数据首先发送给宿主机的docker0网桥,并进入内核协议栈

    2. 经过netfilter的 PREROUTING,再进入到路由子系统,此时由于宿主机没有任何额外的设备,匹配到默认路由,从宿主机的eth0发出,数据包直接发送至目的节点所在的宿主机

    3. 数据帧通过宿主机的二层网络顺利到达节点目的节点

    Calico网络

    img

    calico主要组件

    1. Felix:运行在每一台 Host 的 agent 进程,主要负责网络接口管理和监听、路由、ARP 管理、ACL 管理和同步、状态上报等。Felix会监听ECTD中心的存储,从它获取事件,比如说用户在这台机器上加了一个IP,或者是创建了一个容器等。用户创建pod后,Felix负责将其网卡、IP、MAC都设置好,然后在内核的路由表里面写一条,注明这个IP应该到这张网卡。同样如果用户制定了隔离策略,Felix同样会将该策略创建到ACL中,以实现隔离。

    2. etcd:分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性,可以与kubernetes共用;

    3. BGP Client(BIRD):Calico 为每一台 Host 部署一个 BGP Client,使用 BIRD 实现,BIRD 是一个单独的持续发展的项目,实现了众多动态路由协议比如 BGP、OSPF、RIP 等。在 Calico 的角色是监听 Host 上由 Felix 注入的路由信息,然后通过 BGP 协议广播告诉剩余 Host 节点,从而实现网络互通。BIRD是一个标准的路由程序,它会从内核里面获取哪一些IP的路由发生了变化,然后通过标准BGP的路由协议扩散到整个其他的宿主机上,让外界都知道这个IP在这里,你们路由的时候得到这里来。

    4. BGP Route Reflector:在大型网络规模中,如果仅仅使用 BGP client 形成 mesh 全网互联的方案就会导致规模限制,因为所有节点之间俩俩互联,需要 N^2 个连接,为了解决这个规模问题,可以采用 BGP 的 Router Reflector 的方法,使所有 BGP Client 仅与特定 RR 节点互联并做路由同步,从而大大减少连接数。

    网络管理过程

    1. k8s 下发pod

    2. kubelet 调用calico-cni 接口,然后calico守护进程Felix 创建veth-pair,一端连接pod,一端连接cali虚拟网卡,并写主机路由表。同时将数据(网卡,ip,mac)写入到etcd存储中。

    3. bird 检测到内核路由,bgp广播到集群内的所有节点

    数据包流向

    未完待续

    Canel网络

    Terway网络

  • 相关阅读:
    调试常用命令
    android获取手机机型、厂商、deviceID基本信息
    融云即时通讯 添加地理位置信息的功能
    Linux centOS下搭建RTMP服务器的具体步骤
    数组与字符串 1.4
    数组与字符串 1.5
    数组与字符串 1.3
    数组与字符串 1.2
    数组与字符串 1.1
    笔记本自开wifi设置
  • 原文地址:https://www.cnblogs.com/vinsent/p/15825422.html
Copyright © 2020-2023  润新知