Calico作为CNI插件,基于纯IP的方案实现Pod网络的互通。为了能够让集群外的主机(假设称为NodeA)能够直接访问Pod IP,实际上只要将Kubernetes集群的路由信息完整同步NodeA上即可。

假设当前Kubernetes包括以下4个节点,且默认 calico 中只包含一个ipPool,cidr为30.233.0.0/16,blockSize为26,每个Node在该ipPool中分配到的地址段为:

1
2
3
4
5
NAME    ASN       IPV4                 podCIDR
node1   (64512)   192.168.121.104/24   30.233.166.128/26       
node2   (64512)   192.168.121.153/24   30.233.104.0/26       
node3   (64512)   192.168.121.192/24   30.233.135.0/26       
node4   (64512)   192.168.121.13/24    30.233.3.64/26

相同子网

主机 NodeA 的IP地址 192.168.121.210/24和node1~4二层互通。 为了让NodeA可以访问集群中的Pod,用户可以手工添加以下静态路由:

1
2
3
4
ip route add 30.233.166.128/26  via 192.168.121.104
ip route add 30.233.104.0/26  via 192.168.121.153
ip route add 30.233.135.0/26  via 192.168.121.192
ip route add 30.233.3.64/26  via 192.168.121.13

这种情况NodeA和集群的所有节点是2层互通的,只要指对路由就可以打通Pod网络。

跨子网

当主机 NodeA 和 node1~4 不是IP互通时,无法添加路由规则。 此时可以通过在 NodeA 上部署容器化的 Calico/Node 服务,通过在BGP协议将 K8S 路由信息自动同步到 NodeA 节点,并且借助 Calico/Node 可以在节点上自动创建 IPIP 隧道,解决跨子网问题。

当用户使用Kubernetes作为存储后端时,Calico基于Kubernetes Node建立BGP Peer,为了让 NodeA 能够和其他节点建立Session。我们需要手工在Kubernets中创建一个name为“node-ext”的虚拟节点。

1
2
3
4
5
6
kubectl apply -f - <<EOF
kind: Node
apiVersion: v1
metadata:
  name: node-ext
EOF

假设 NodeA 节点IP为 192.168.222.210,通过以下命令在 NodeA 中启动 Calico 容器:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
docker run --net=host --privileged \
 --name=calico-node \
 -e NODENAME="node-ext" \
 -e IP="192.168.222.210" \
 -e CALICO_NETWORKING_BACKEND=bird \
 -e NO_DEFAULT_POOLS=true \
 -e DATASTORE_TYPE=kubernetes \
 -e KUBECONFIG=/calico/calico-kubeconfig \
 -e CALICO_STARTUP_LOGLEVEL=DEBUG \
 -v /etc/calico/calico-kubeconfig:/calico/calico-kubeconfig \
 -v /var/log/calico:/var/log/calico \
 -v /var/lib/calico:/var/lib/calico \
 -v /var/run/calico:/var/run/calico \
 -v /run/docker/plugins:/run/docker/plugins \
 -v /lib/modules:/lib/modules \
 registry.hci.io/calico/node:v3.20.0

KUBECONFIG 指定的 kubeconfig 可以从中/etc/kubernetes/admin.conf 获取

calico-node 的相关日志信息保存在 /var/log/calico 目录中

上述方案在跨子网的环境上可以成功,但是在一些特殊环境无法成功。

浮动IP场景,集群内节点只能通过 NodeA 的浮动ip访问,并且浮动ip是通过NAT的方式映射的

目前这种玩法,实际上calico官方并不支持。

参考:https://github.com/projectcalico/calico/issues/3407