Calico是一个用于容器、虚拟机和基于本地主机的工作负载的开源网络和网络安全解决方案。
Calico支持广泛的平台,包括Kubernetes、OpenShift、Docker EE、OpenStack和bare metal服务。Calico将灵活的网络功能与随处运行的安全实施相结合,提供了一个具有本地Linux内核性能和真正的云本地可伸缩性的解决方案。
Calico是一个纯三层的数据中心网络方案(不需要 Overlay),它在每一个计算节点利用 Linux Kernel 实现了一个高效的 vRouter 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络内传播——小规模部署可以直接互联,大规模下可通过指定的 BGP route reflector 来完成。 这样保证最终所有的 workload 之间的数据流量都是通过 IP 路由的方式完成互联的。
Calico 节点组网可以直接利用数据中心的网络结构(无论是 L2 或者 L3),不需要额外的 NAT,隧道或者 Overlay Network。
此外,Calico 基于 iptables 还提供了丰富而灵活的网络 Policy,保证通过各个节点上的 ACLs 来提供 Workload 的多租户隔离、安全组以及其他可达性限制等功能。
calico的核心组件,运行在每个节点上。主要的功能有接口管理、路由规则、ACL规则和状态报告
etcd保证数据一致性的数据库,存储集群中节点的所有路由信息。为保证数据的可靠和容错建议至少三个以上etcd节点。
协调器插件负责允许kubernetes或OpenStack等原生云平台方便管理Calico,可以通过各自的API来配置Calico网络实现无缝集成。如kubernetes的cni网络插件。
BGP客户端,Calico在每个节点上的都会部署一个BGP客户端,它的作用是将Felix写入内核的路由信息,通过BGP协议在集群中分发。当Felix将路由插入到Linux内核FIB中时,BGP客户端将获取这些路由并将它们分发到部署中的其他节点。这可以确保在部署时有效地路由流量。
大型网络仅仅使用 BGP client 形成 mesh 全网互联的方案就会导致规模限制,所有节点需要 N^2 个连接,为了解决这个规模问题,可以采用 BGP 的 Router Reflector 的方法,使所有 BGP Client 仅与特定 RR 节点互联并做路由同步,从而大大减少连接数。
calico 命令行管理工具
BGP 边界网关协议(Border Gateway Protocol,BGP):是外部路由协议(边界网关路由协议),是互联网上一个核心的去中心化自治路由协议。BGP不使用传统的内部网关协议(IGP)的指标。
基本功能是在自治系统间自动交换无环路的路由信息,通过交换带有自治系统号序列属性的路径可达信息,来构造自治系统的拓扑图,从而消除路由环路并实施用户配置的路由策略。
全互联模式 每一个BGP Speaker都需要和其他BGP Speaker建立BGP连接,这样BGP连接总数就是N^2,如果数量过大会消耗大量连接。如果集群数量超过100台官方不建议使用此种模式。
RR模式 中会指定一个或多个BGP Speaker为RouterReflection,它与网络中其他Speaker建立连接,每个Speaker只要与Router Reflection建立BGP就可以获得全网的路由信息。在calico中可以通过Global Peer实现RR模式。
calico的工作示意图见上图,其中的绿色实线标出的路径,就是一个 IP 包从 Node 1 上的 Container 1,到达 Node 2 上的 Container 4 的完整路径。可以看到,Calico 的 CNI 插件会为每个容器设置一个 Veth Pair 设备,然后把其中的一端放置在宿主机上(它的名字以 cali 前缀开头)。
此外,由于 Calico 没有使用 CNI 的网桥模式,Calico 的 CNI 插件还需要在宿主机上为每个容器的 Veth Pair 设备配置一条路由规则,用于接收传入的 IP 包。比如,宿主机 Node 2 上的 Container 4 对应的路由规则,如下所示:
# 发往 10.233.2.3 的 IP 包,应该进入 cali5863f3 设备。
10.233.2.3 dev cali5863f3 scope link
有了这样的 Veth Pair 设备之后,容器发出的 IP 包就会经过 Veth Pair 设备出现在宿主机上。然后,宿主机网络栈就会根据路由规则的下一跳 IP 地址,把它们转发给正确的网关。其中,这里最核心的“下一跳”路由规则,就是由 Calico 的 Felix 进程负责维护的。这些路由规则信息,则是通过 BGP Client 也就是 BIRD 组件,使用 BGP 协议传输而来的。
以上所说,都是在节点的二层网络都通的情况下,如果节点的二层网络不连通,怎么办?
按照我们前面的讲述,Calico 会尝试在 Node 1 上添加如下所示的一条路由规则:
10.233.2.0/16 via 192.168.2.2 eth0
但是,这时候问题就来了。上面这条规则里的下一跳地址是 192.168.2.2,可是它对应的 Node2 跟 Node1 却根本不在一个子网里,没办法通过二层网络把 IP 包发送到下一跳地址。
在这种情况下,你就需要为 Calico 打开 IPIP 模式。(略看)
下一跳地址仍然是 Node2 的 IP 地址,但这一次,要负责将 IP 包发出去的设备,变成了 tunl0。其中tunl0 设备,是一个 IP 隧道(IP tunnel)设备。