工作原理

BGP

Calico采用的BGP,就是在大规模网络中实现节点路由信息共享的一种协议。全称是Border Gateway Protocol,即:边界网关协议。它是一个Linux内核原生就支持的、专门用在大规模数据中心里维护不同的 “自治系统” 之间路由信息的、无中心的路由协议。

由于没有使用CNI的网桥,CalicoCNI插件需要为每个容器设置一个Veth Pair设备,然后把其中的一端放置在宿主机上,还需要在宿主机上为每个容器的Veth Pair设备配置一条路由规则,用于接收传入的IP包。如下图所示:

Calico

可以使用calicoctl查看Node 1的节点连接情况:

~ calicoctl get no
NAME
node1
node2
node3
~ calicoctl node status
Calico process is running.

IPv4 BGP status
+---------------+-------------------+-------+------------+-------------+
| PEER ADDRESS  |     PEER TYPE     | STATE |   SINCE    |    INFO     |
+---------------+-------------------+-------+------------+-------------+
| 192.168.50.11 | node-to-node mesh | up    | 2020-09-28 | Established |
| 192.168.50.12 | node-to-node mesh | up    | 2020-09-28 | Established |
+---------------+-------------------+-------+------------+-------------+

IPv6 BGP status
No IPv6 peers found.

可以看到整个calico集群上有3个节点,Node 1和另外两个节点处于连接状态,模式为 “Node-to-Node Mesh”。再看下Node 1上的路由信息如下:

~ ip route
default via 192.168.50.1 dev ens33 proto static metric 100
10.244.104.0/26 via 192.168.50.11 dev ens33 proto bird
10.244.135.0/26 via 192.168.50.12 dev ens33 proto bird
10.244.166.128 dev cali717821d73f3 scope link
blackhole 10.244.166.128/26 proto bird
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
192.168.50.0/24 dev ens33 proto kernel scope link src 192.168.50.10 metric 100

其中,第2条的路由规则表明10.244.104.0/26网段的数据包通过bird协议由ens33设备发往网关192.168.50.11。这也就定义了目的ipNode 2Pod请求的走向。第3条路由规则与之类似。

IPIP模式

IPIP模式为了解决两个Node不在一个子网的问题。只要将名为calico-nodedaemonset的环境变量CALICOIPV4POOLIPIP设置为 “Always” 即可。如下:

- name: CALICO_IPV4POOL_IPIP
  value: "Off"

IPIP模式的Calico使用了tunl0设备,这是一个IP隧道设备。IP包进入tunl0后,内核会将原始IP包直接封装在宿主机的IP包中;封装后的IP包的目的地址为下一跳地址,即Node 2IP地址。由于宿主机之间已经使用路由器配置了三层转发,所以这个IP包在离开Node 1之后,就可以经过路由器,最终发送到Node 2上。如下图所示。

Calico IPIP 模式

由于IPIP模式的Calico额外多出了封包和拆包的过程,集群的网络性能受到了影响,所以在集群的二层网络通的情况下,建议不要使用IPIP模式。看下Node1上的路由信息:

~ ip route
default via 192.168.50.1 dev ens33 proto static metric 100
10.244.104.0/26 via 192.168.50.11 dev tunl0 proto bird onlink
10.244.135.0/26 via 192.168.50.12 dev tunl0 proto bird onlink
blackhole 10.244.166.128/26 proto bird
10.244.166.129 dev calif3c799362a5 scope link
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
192.168.50.0/24 dev ens33 proto kernel scope link src 192.168.50.10 metric 100

可以看到,与之前不一样的是,目的IPNode 2上的Pod的数据包是经由tunl0发送到网关192.168.50.11