前言
上一节讲到了 7-2 网络组件flannel总结 ,还有一种流行的更安全的网络组件为Calico。
Calico 是一个开源网络和网络安全解决方案,适用于容器、虚拟机和基于本地主机的工作负载。Calico 支持广泛的平台,包括 Kubernetes、OpenShift、Mirantis Kubernetes Engine (MKE)、OpenStack 和裸机服务。
无论您选择使用 Calico 的 eBPF 数据平面还是 Linux 的标准网络管道,Calico 都能提供超快的性能和真正的云原生可扩展性。Calico 为开发人员和集群运营商提供一致的体验和一组功能,无论是在公共云或本地、单个节点上还是跨数千个节点的集群上运行。
虽然Flannel被公认为是最简单的选择,但Calico以其性能、灵活性而闻名。Calico的功能更为全面,不仅提供主机和pod之间的网络连接,还涉及网络安全和管理。从Calico 3.x开始,默认配置使用的是IPIP模式这种Overlay的传输方案而非BGP。
架构组件
Calico网络模型主要工作组件:
Felix:运行在每一台 Host 的 agent 进程,主要负责网络接口管理和监听、路由、ARP 管理、ACL 管理和同步、状态上报等。
etcd:分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性,可以与kubernetes共用;
BGP Client(BIRD):Calico 为每一台 Host 部署一个 BGP Client,使用 BIRD 实现,BIRD 是一个单独的持续发展的项目,实现了众多动态路由协议比如 BGP、OSPF、RIP 等。在 Calico 的角色是监听 Host 上由 Felix 注入的路由信息,然后通过 BGP 协议广播告诉剩余 Host 节点,从而实现网络互通。
BGP Route Reflector:在大型网络规模中,如果仅仅使用 BGP client 形成 mesh 全网互联的方案就会导致规模限制,因为所有节点之间俩俩互联,需要 N^2 个连接,为了解决这个规模问题,可以采用 BGP 的 Router Reflector 的方法,使所有 BGP Client 仅与特定 RR 节点互联并做路由同步,从而大大减少连接数。
此外,etcd组件是Calico组件运行的依赖组件,需事先在集群中部署etcd服务,或复用Kubernetes的etcd;Calico官方也提供了calicoctl管理工具,用于与Calico Node进行状态确认、状态配置等操作。
工作模式
IPIP
从字面来理解,就是把一个IP数据包又套在一个IP包里,即把 IP 层封装到 IP 层的一个 tunnel。它的作用其实基本上就相当于一个基于IP层的网桥!一般来说,普通的网桥是基于mac层的,根本不需 IP,而这个 ipip 则是通过两端的路由做一个 tunnel,把两个本来不通的网络通过点对点连接起来。
IPIP模式基于linux kernel的ipip隧道技术实现,即IP报文外面又封装了一层IP报文。内层的IP报文为原报文,外层报文的源IP和目的IP,即是隧道两端的IP。也就是说,应用想要通过隧道在源IP报文外再封装一层IP报文,从而使得原报文能够通过隧道路由到对端。对端的IPIP隧道模块,把原来的外层IP拆解掉,从而还原出原来的IP报文。
IPIP主要做的就是封包,解包的过程。通过IPIP封解包,原始IP报文能够在外层IP的托运下,通过路由穿过隧道,抵达隧道的对端,并且还原出原来的IP报文。这就是IPIP隧道的核心思想。
在使用ipip模式之后,每个node上会自动添加一个tunl0网卡,用于IPIP协议的支持。
BGP
边界网关协议(Border Gateway Protocol, BGP)是互联网上一个核心的去中心化自治路由协议。它通过维护IP路由表或‘前缀’表来实现自治系统(AS)之间的可达性,属于矢量路由协议。BGP不使用传统的内部网关协议(IGP)的指标,而使用基于路径、网络策略或规则集来决定路由。因此,它更适合被称为矢量性协议,而不是路由协议。BGP,通俗的讲就是讲接入到机房的多条线路(如电信、联通、移动等)融合为一体,实现多线单IP,BGP 机房的优点:服务器只需要设置一个IP地址,最佳访问路由是由网络上的骨干路由器根据路由跳数与其它技术指标来确定的,不会占用服务器的任何系统。
网络策略
Calico 与Flannel最大的不同,它实现了灵活配置网络策略 Network Policy,可以灵活配置两个容器通或者不通。
虚拟机中的安全组,是用 iptables 实现的。Calico 中也是用 iptables 实现的。这个图里的内容是 iptables 在内核处理网络包的过程中可以嵌入的处理点。Calico 也是在这些点上设置相应的规则。
当网络包进入物理机上的时候,进入 PREOUTING 规则,这里面有一个规则是 cali-fip-dnat,这是实现浮动 IP(Floating IP)的场景,主要将外网的 IP 地址 dnat 作为容器内的 IP 地址。在虚拟机场景下,路由器的网络 namespace 里面有一个外网网卡上,也设置过这样一个 DNAT 规则。
接下来可以根据路由判断,是到本地的,还是要转发出去的。
如果是本地的,走 INPUT 规则,里面有个规则是 cali-wl-to-host,wl 的意思是 workload,也即容器,也即这是用来判断从容器发到物理机的网络包是否符合规则的。这里面内嵌一个规则 cali-from-wl-dispatch,也是匹配从容器来的包。如果有两个容器,则会有两个容器网卡,这里面内嵌有详细的规则“cali-fw-cali 网卡 1”和“cali-fw-cali 网卡 2”,fw 就是 from workload,也就是匹配从容器 1 来的网络包和从容器 2 来的网络包。
如果是转发出去的,走 FORWARD 规则,里面有个规则 cali-FORWARD。这里面分两种情况,一种是从容器里面发出来,转发到外面的;另一种是从外面发进来,转发到容器里面的。