Calico
Calico 是一个基于 BGP 的纯三层的数据中心网络方案(不需要 Overlay),并且与 OpenStack、Kubernetes、AWS、GCE 等 IaaS 和容器平台都有良好的集成。
Calico 在每一个计算节点利用 Linux Kernel 实现了一个高效的 vRouter 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息像整个 Calico 网络内传播——小规模部署可以直接互联,大规模下可通过指定的 BGP route reflector 来完成。 这样保证最终所有的 workload 之间的数据流量都是通过 IP 路由的方式完成互联的。Calico 节点组网可以直接利用数据中心的网络结构(无论是 L2 或者 L3),不需要额外的 NAT,隧道或者 Overlay Network。
此外,Calico 基于 iptables 还提供了丰富而灵活的网络 Policy,保证通过各个节点上的 ACLs 来提供 Workload 的多租户隔离、安全组以及其他可达性限制等功能。
Calico 采用和 Flannel host-gw 类似的方式,即通过修改主机路由的方式实现容器间的跨主机通信,不同的地方在于 Flannel 通过 flanneld 进程逐一添加主机静态路由实现,而 Calico 则是通过 BGP 协议实现节点间路由规则的相互学习广播。
Architecture
Calico 由以下组件组成,在部署 Calico 的时候部分组件是可选的。
Calico API Server
Main task : Lets you manage Calico resources directly with kubectl.
Felix
Felix 以 agent 代理的形式在每台机器端点上运行。对路由和 ACL 以及主机编程,为该主机上的端点提供所需的连接。根据具体的编排器环境,Felix 负责:
- 接口管理: 将有关接口的信息编入内核,以便内核能够正确处理来自该端点的流量。特别是,确保主机响应来自每个工作负载的 ARP 请求,提供主机的 MAC,并为它所管理的接口启用 IP 转发。它还监控接口,以确保编程在适当的时候应用。
- 路由编程: 将其主机上的端点的路由编程到 Linux 内核的 FIB(转发信息库)。这可以确保到达主机上的以这些端点为目的地的数据包被相应地转发。
- ACL 编程: 在 Linux 内核中编程 ACL,以确保只有有效的流量可以在端点之间发送,并且端点不能规避 Calico 的安全措施。*
- 状态报告: 提供网络健康数据。特别是在配置其主机时报告错误和问题。这些数据被写入数据存储,以便对网络的其他组件和运营商可见。
Bird
从 Felix 获取路由,并分发到网络上的 BGP peer,用于主机间的路由。在每个 Felix 代理的节点上运行。BGP 客户端负责:
- 路由分配:当 Felix 将路由插入 Linux 内核的 FIB 时,BGP 客户端将它们分配给部署中的其他节点。这确保了部署中的有效流量路由。
- BGP 路由反射器的配置: BGP 路由反射器通常是为大型部署而配置的,而不是一个标准的 BGP 客户端。BGP 路由反射器作为连接 BGP 客户端的一个中心点。(标准 BGP 要求每个 BGP 客户端在网状拓扑结构中与其他每个 BGP 客户端连接,这很难维护)。
- 为了实现冗余,你可以无缝部署多个 BGP 路由反射器。BGP 路由反射器只参与网络的控制:没有终端数据通过它们。当 Calico BGP 客户端将其 FIB 中的路由通告给路由反射器时,路由反射器将这些路由通告给部署中的其他节点。
confd
开源的、轻量级的配置管理工具。监控 Calico 数据存储对 BGP 配置和全局默认的日志变更,如 AS 号、日志级别和 IPAM 信息。Confd 根据存储中的数据更新,动态生成 BIRD 配置文件。当配置文件发生变化时,confd 会触发 BIRD 加载新的文件。
Diskastes
执行 Istio 服务网格的网络策略。作为 Istio Envoy 的一个Sidecar代理,在集群上运行。
- Dikastes 是可选的。Calico 在 Linux 内核(使用 iptables,在三、四层)和三到七层使用 Envoy 的Sidecar代理 Dikastes 为工作负载执行网络策略,对请求进行加密认证。使用多个执行点可以根据多个标准确定远程端点的身份。即使工作负载 Pod 破坏,Envoy 代理被绕过,主机 Linux 内核的执行也能保护你的工作负载。
Typha
通过减少每个节点对数据存储的影响来增加规模。作为数据存储和 Felix 实例之间的一个守护程序运行。默认安装,但没有配置。
Typha 代表 Felix 和 confd 等所有客户端维护一个单一的数据存储连接。它缓存数据存储的状态,并复制事件,以便它们可以被推广到更多监听器。因为一个 Typha 实例可以支持数百个 Felix 实例,可以将数据存储的负载降低很多。由于 Typha 可以过滤掉与 Felix 无关的更新,它也减少了 Felix 的 CPU 使用。在一个大规模(100 多个节点)的 Kubernetes 集群中,这是至关重要的,因为 API 服务器产生的更新数量随着节点数量的增加而增加。
kube-controller
监控 Kubernetes 的 API,并根据集群状态执行行动。tigera/kube-controllers 容器包括以下控制器:
- Policy 控制器
- Namespace 控制器
- ServiceAccount 控制器
- WorkloadEndpoint 控制器
- Node 控制器
IPAM 插件
使用 Calico 的 IP 池资源来控制如何将 IP 地址分配给集群中的 pod。它是大多数 Calico 安装所使用的默认插件。它是 Calico CNI 插件之一。
IPAM
Calico 也会像 Flannel 一样会为每个主机节点分配一个子网,只不过 Calico 默认分配的是 26 位子网,不同于 Flannel 默认分配的 24 位子网:
| Node Name | Node IP | Node Subnet |
|---|---|---|
| Node 1 | 172.16.31.155 | 10.1.83.192 ⁄ 26 |
| Node 2 | 172.16.32.117 | 10.1.32.192 ⁄ 26 |
| Node 2 | 172.16.32.120 | 10.1.147.128 ⁄ 26 |
BGP
Calico 通过 BGP 协议动态调价路由,那么我们就来看看主机的路由规则:
|
|
可以看到,Calico 修改主机路由来实现容器间的跨主机通信方式和 Flannel host-gw 一样,下一跳直接指向对应主机的 IP,把主机当作容器的网关。但 Calico 会增加一条 blackhole 的规则,将非法的容器 IP 直接丢弃;另外一个不一样的地方是数据包到达宿主机后,Flannel 会通过路由转发流量到 bridge 网络设备中,再由 bridge 设备转发给容器,而 Calico 则为每个容器 IP 生成一条路由规则,直接指向容器的网卡对端。当容器数量达到一定规模之后,主机路由规则数量也会越来越多,性能会是个问题。Calico 给出的解决方案是路由反射器(route reflector)。
此外,需要注意的是,我们知道 Flannel host-gw 的方式只支持每个宿主机在同一个子网内,才可以添加静态路由规则,不能支持跨网段的主机 node,那么 Calico 支持吗?
Overlay
IPIP
答案是肯定的,Calico 在安装的时候可以指定是否打开 IPIP 模式,也就是 IPIP 隧道。在我的实验环境中,IPIP 模式已经打开,如果你观察得够仔细的话,你会发现主机路由中发往其他主机上的容器的路由要经过 tunl0 网络设备,我们来看一下 tunl0 网络设备的类型:
|
|
可以看到,tunl0其实是 Linux 的 TUN 网络设备,它会在不同主机节点间开启 IPIP 隧道,也就是说,即使主机节点处于三层(IP)网络中,数据包还是可以通过隧道发送到目标主机,在由目标主机转发给对应的容器。这时 Calico 其实采用的是 overlay 的方式。
VxLAN
-
No backlinks found.