Calico网络方案解析
在上一篇博客中,介绍了Flannel的三种工作模式,本文主要介绍Calico网络方案的工作原理,并和Flannel host-gw模式做简单对比。
BGP
BGP是一个 Linux 内核原生就支持的、专门用在大规模数据中心里维护不同的“自治系统”之间路由信息的、无中心的路由协议。在正常情况下,两个自治系统之间是不会有任何的“来往”的,如果这样两个自治系统里的主机,要通过 IP 地址直接进行通信,我们就必须使用路由器把这两个自治系统连接起来,并且需要网络管理员给路由器添加对应的路由规则,像上面这样负责把自治系统连接在一起的路由器,我们就把它形象地称为:边界网关。它跟普通路由器的不同之处在于,它的路由表里拥有其他自治系统里的主机路由信息。
Calico
Calico 项目提供的网络解决方案,与 Flannel 的 host-gw 模式,几乎是完全一样的,也会在每台宿主机上添加每个子网段对应的路由规则,其中,下一跳的网关就是目的宿主机的ip地址。也会在每台宿主机上创建一个虚拟路由器,不过,不同于 Flannel 通过 Etcd 和宿主机上的 flanneld 来维护路由信息的做法,Calico 项目使用BGP协议来自动地在整个集群中分发路由信息。Calico 项目由三个部分组成:
1、 Calico 的 CNI 插件。这是 Calico 与 Kubernetes 对接的部分;
2、 Felix。它是一个 DaemonSet,负责在宿主机上插入路由规则以及维护 Calico 所需的网络设备等工作;
3、 BIRD。它就是 BGP 的客户端,专门负责在集群里分发路由规则信息。而其他边界网关上的这个小程序,则会对收到的这些数据进行分析,然后将需要的信息添加到自己的路由表里;
除了对路由信息的维护方式之外,Calico 项目与 Flannel 的 host-gw 模式的另一个不同之处,就是它不会在宿主机上创建任何网桥设备。工作方式如下图:

工作流程为:Calico 的 CNI 插件会为每个容器设置一个 Veth Pair 设备,然后把其中的一端放置在宿主机上(没有网桥),而且会在宿主机上为每个容器的 Veth Pair 设备配置一条路由规则,用于接收传入的 IP 包。对于发出的IP包,也会设置相应的路由规则,其中,这里最核心的“下一跳”路由规则,就是由 Calico 的 Felix 进程负责维护的。这些路由规则信息,则是通过 BGP 客户端也就是 BIRD 组件,使用 BGP 协议传输而来的。
需要注意的是,Calico 维护的网络在默认配置下,是一个被称为“Node-to-Node Mesh”的模式。这时候,每台宿主机上的 BGP Client 都需要跟其他所有节点的 BGP Client 进行通信以便交换路由信息。但是,随着节点数量 N 的增加,这些连接的数量就会以 N²的规模快速增长,从而给集群本身的网络带来巨大的压力。所以,Node-to-Node Mesh 模式一般推荐用在少于 100 个节点的集群里。而在更大规模的集群中,你需要用到的是一个叫作 Route Reflector 的模式。
在这种模式下,Calico 会指定一个或者几个专门的节点,来负责跟所有节点建立 BGP 连接从而学习到全局的路由规则。而其他节点,只需要跟这几个专门的节点交换路由信息,就可以获得整个集群的路由规则信息了。这些专门的节点,就是所谓的 Route Reflector 节点,它们实际上扮演了“中间代理”的角色,从而把 BGP 连接的规模控制在 N 的数量级上。
Calico也是要求集群宿主机之间是二层连通的,这点和Flannel host-gw 模式一样,如果需要通信的宿主机处于不同的子网,二层不通,但是三层可通,在这种情况下,你就需要为 Calico 打开 IPIP 模式,如下图所示:

当 Calico 使用 IPIP 模式的时候,集群的网络性能会因为额外的封包和解包工作而下降。在实际测试中,Calico IPIP 模式与 Flannel VXLAN 模式的性能大致相当。所以,在实际使用时,如非硬性需求,我建议你将所有宿主机节点放在一个子网里,避免使用 IPIP。
与Flannel 的 host-gw的对比
都是三层网络方案;
host-gw使用etcd和flanneld维护路由信息,而Calico使用BGP自动分发路由信息;
host-gw会创建cni0虚拟网桥,Calico不会创建任何网桥设备;
因为每个容器都需要一条路由规则,所以Calico在宿主机上的路由规则要比Flannel多得多;
如果宿主机是三层连通的,则可以使用IPIP模式;
浙公网安备 33010602011771号