Calico

Calico

前面介绍Flannel的三层网络解决方案是host-gw,其实还有一个非常出名的单独的三层网络解决方案Calico,它的工作模式和host-gw基本一致,也是会在每台宿主机上添加如下格式的路由规则:

<目的容器IP地址段> via <网关的IP地址> dev eth0

其中网关的IP地址就是目的容器所在的宿主机的IP地址。而且这个三层网络得以正常工作的核心就是为每个容器的IP地址找到它所对应的下一跳的网关地址。

不同于Flannel,Calico是通过BGP(Border Gateway Protocol 边界网关协议)来自动的在集群中分发路由信息。BGP是Linux原生就支持的专门用在大规模数据中心维护不同的"自治系统"之间的路由信息、无中心得路由协议。而所谓得"自治系统"就是一个组织管辖下得所有IP网络和路由器的全体。如下图所示AS1和AS2就是独立的"自治系统",这两个"自治系统"要进行通信,就必须要用路由器把它们连接起来。

Calico

如上,比如AS1的10.10.0.2要访问172.17.0.2,它发出的IP包就会先到达AS1的route1,然后根据里面的规则找到从C口出去到达router2,然后经过route2的路由表到达目的地172.17.0.2。

像这样负责把"自治系统"连接在一起的路由器,我们称之为"边界 网关",它跟普通的路由器的不同之处在于它的路由表里拥有其他自治系统里的主机路由信息。

而BGP就可以认为是在每个边界网关上运行的一个小程序,其作用将各自的路由表信息通过TCP传输给其他的边界网关,而其他边界网关上的小程序就会对接收到的数据进行处理分析,将需要的路由表添加到自己的路由表里。所以,所谓的BGP,就是大规模网络中实现节点路由信息共享的一种协议。

明白了BGP的大体工作原理后,其Calico的工作架构就非常容易理解,它主要由Felix,BGP Client,BGP Router Reflector组成:

  1. Felix:Calico Agent,每个节点都需要运行,主要负责配置路由,处理ACL,报告状态等;
  2. BGP Client:负责将Felix配置的路由信息分发到其他节点
  3. BGP Router Reflector:大规模集群需要使用到,作为BGP Client的中心连接点,避免每个节点互联

Calico

如上就是Calico的工作原理(Calico不会在宿主机上创建任何网桥设备,这与Flannel是不同的)。

其工作流程如下:

  1. 首先CNI会创建一对Veth Pair设备,其中一端放在宿主机上;
  2. 由于Calico没有使用CNI的网桥模式,所以还需要在宿主机上为每个容器的Veth Pair添加一条路由规则,用于接收传入的IP包,例如在Container4上会添加" 10.233.2.3 dev cali5863f3 scope link",即发往10.233.2.3的IP包应该进入cali5863f3设备;
  3. 然后的流程在路由表中找到下一跳的信息,然后找到MAC地址,通过eth0传到下一跳,再进行解包转发等,和Flannel host-gw的工作流程一样;

从上面可以看到Calico将集群中的所有节点都当作是边界路由器来处理,它们之间组成了一个全连通的网络,互相之间通过BGP协议交换路由规则,这些节点我们称之为BGP Peer。

Node-to-Node Mesh

Calico的默认模式是Node-to-Node Mesh,这种模式下,所有主机上的BGP Client都需要于其他主机进行通信交换路由规则信息,但是随着节点N的增加,其连接数也是N*2倍增加,从而给集群的网络带来很大的眼里,所以使用该模式,一般建议集群节点在100个之内。

Route Reflector

如果节点数超过了100,那么就可以使用Route Reflector模式,它会指定一个或者几个专门的节点,来负责跟所有的BGP建立连接从而学习全局的路由规则,而其他的节点只需要跟这个专门的节点进行路由信息的交换,就可以获取整个集群的路由信息了。而这些专门的节点就是Route Reflector节点,它扮演中间代理的角色。

IP-IP

如果不同子网的宿主机要进行通信,则需要打开IPIP模式了,如下:

Calico

在Calico的IPIP模式下,Felix进程就会在Node上添加如下路由规则,如Node1:

10.233.2.0/24 via 192.168.2.2 tunl0

其中的tunl0就是一个IP Tunnel设备。IP包进入IP隧道后就会被Linux内核中的IPIP驱动接管,IPIP驱动会将这个IP包直接封装在一个宿主机网络的IP包中,经过封装后的IP包的目的地址就是原IP包的下一跳地址,即目的容器所在的宿主机的IP地址,然后将IP包直接转发到目的宿主机,然后会使用IPIP驱动进行解包,然后根据本地的路由信息转发到对应的容器中去。

参考文档:

  • 极客时间《深入剖析Kubernetes》之解读kubernetes三层网络方案
上一篇:干货 | 华为HCIP-RS实验培训视频教程


下一篇:Git