【Calico系列】3 Calico的组件、架构与原理
2020-01-11 tech calico 12 mins 6 图 4237 字
本文是 Calico 系列的第三篇文章,继上一篇了解 BGP 的基本概念,这一篇真正进入 Calico 的笔记。本篇以 Calico 3.4 版本 为基准。
由于网络的水深与个人能力有限,本文不免存在错误之处。如有疑问,请查阅文末参考资料或与我线上/线下讨论。
目录:
一、Calico架构
- Felix 跑在每个节点上,负责配置路由、ACL、向etcd宣告状态等;
- Orchestrator plugin 适配不同架构的插件;
- etcd 主要负责网络元数据一致性,确保Calico网络状态的准确性;
- BGP Client (BIRD) 负责把 Felix 写入Kernel的路由信息 分发到整个 Calico网络,确保 workload 连通;
- BGP Route Reflector (BIRD) BGP路由反射器,大规模部署时使用,通过一个或者多个BGP Route Reflector来完成集中式的路由分发。
通过将整个互联网的可扩展 IP 网络原则压缩到数据中心级别,Calico 在每一个计算节点利用 Linux kernel 实现了一个高效的 vRouter 来负责数据转发,每个vRouter通过BGP协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络传播。
这样保证最终所有的 workload 之间的数据流量都是通过 IP 包的方式完成互联的。
calico的各个组件通过操作linux 路由表、iptables等来控制数据包的流向,本身不接触数据包。即使停掉calico组件,只要路由表记录还在,便不影响容器通信。
特别地,在 kubernetes 架构中,当 calico 作为策略和网络组件时,实际运行了两类容器:
$ kubectl get po -n kube-system |grep calico
calico-kube-controllers-5f6db94794-cmqs4 1/1 Running 1 74d
calico-node-k92qh 1/1 Running 1 74d
calico-node-lt7sn 1/1 Running 1 74d
calico-node-qh596 1/1 Running 1 74d
calico-node-wt8n9 1/1 Running 1 74d
在每个节点上运行的calico-node 的pod,pod 内部实际上运行了如下进程:
另外还有一个 kube-controller 的pod:
它们的具体作用后面的文章再做详细介绍.
Felix
Felix 负责最终网络相关的配置,也就是容器网络在 linux 上的配置工作,比如:
- 更新节点上的路由表项
- 更新节点上的 iptables 表项
它的主要工作是从 etcd 中读取网络的配置,然后根据配置更新节点的路由和 iptables,felix 的代码在 github projectcalico/felix。
Orchestrator Plugin
不同的平台有不同的 plugin,例如 Kubernetes 有 Calico CNI,OpenStack 有 Calico Neutron ML2 mechanism driver,负责calico与各个平台的适配:
- API 翻译
- 返回 calico 的网络状态,比如felix探活、标记 endpoints 失败等。
Etcd
Etcd 是一个分布式的键值存储数据库,保存了 calico 网络元数据,用来协调 calico 网络多个节点:
- 存储
- 不同组件间交互数据
etcd每个目录保存的数据大致功能如下:
/calico/ipam
:IP 地址分配管理,保存了节点上分配的各个子网段以及网段中 IP 地址的分配情况/calico/v1
:profile 和 policy 的配置信息,节点上运行的容器 endpoint 信息(IP 地址、veth pair interface 的名字等),/calico/bgp
:和 BGP 相关的信息,包括 mesh 是否开启,每个节点作为 gateway 通信的 IP 地址,AS number 等
BGP Client (BIRD)
BIRD(BIRD Internet Routing Daemon) 是一个常用的网络路由软件,支持很多路由协议(BGP、RIP、OSPF等),calico 用它在节点之间共享路由信息。
Calico 会在所有跑 Felix 节点部署一个 BGP Client。BGP client 會读取 Felix 在 kernel 中的设定,并将其共享到其他节点。
关于 BIRD 如何配置 BGP 协议,可以参考官方文档。
BGP route reflector (BIRD)
全互联模式(full mesh)会造成路由条目过大,无法在大规模集群中部署。使用BGP RR(中心化)的方式交换路由,能够有效降低节点间的连接数。
二、Calico 数据路径——路由与iptables
我们可以将 workload(工作负载) 当成容器或者虚拟机。
在 calico 中,计算节点充当了路由器的角色。它们为运行在本机上的容器或是虚拟机提供路由。我们称之为 vRouter
。Linux Kernel 负责数据数据包路由, 通过BPG协议来控制路由分发, Flelix
来管理路由信息。
处于节点上的 Endpoint 只能同本节点 vRouter
通信, 数据包的第一条和最后一条都是通过 vRouter
中路由规则来实现。vRouter
间通过BGP协议来同步节点上的 Endpoint 信息。
假设容器的ip段为 10.65.0.0/16
,主机的ip段为172.18.203/24
,主机上的路由表如下:
route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.18.203.1 0.0.0.0 UG 0 0 0 eth0
10.65.0.0 0.0.0.0 255.255.0.0 U 0 0 0 ns-db03ab89-b4
10.65.0.21 172.18.203.126 255.255.255.255 UGH 0 0 0 eth0
10.65.0.22 172.18.203.129 255.255.255.255 UGH 0 0 0 eth0
10.65.0.23 172.18.203.129 255.255.255.255 UGH 0 0 0 eth0
10.65.0.24 0.0.0.0 255.255.255.255 UH 0 0 0 tapa429fb36-04
172.18.203.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
ip地址为10.65.0.24的容器,通过 tap(或veth等)接口从主机进行访问,所以可以看到有一条直接路由(direct routes):
10.65.0.24 0.0.0.0 255.255.255.255 UH 0 0 0 tapa429fb36-04
其它的几个容器.21 .22 .23在另外两个主机上,所以他们的网关在另外的主机上:
10.65.0.21 172.18.203.126 255.255.255.255 UGH 0 0 0 eth0
10.65.0.22 172.18.203.129 255.255.255.255 UGH 0 0 0 eth0
10.65.0.23 172.18.203.129 255.255.255.255 UGH 0 0 0 eth0
当容器创建后,由当前所在主机的 Felix 创建这条直接路由(direct routes)。创建后,BGP客户端 BIRD 会监控到路由变化,然后将它们宣告到其它主机的 BIRD 上,其它主机上便出现了下一跳为当前主机的路由。
安全性
通过上面的路由设置,任何容器之间都可以互访。然而作为运维角色,我们希望限制这种流通性,比如多租户功能。Calico 通过操作主机上的 iptables 来达到这样的功能,作为防火墙一样的存在,隔离不同的容器。隔离不同主机上两个容器X和Y的规则,会在X和Y所在的主机上都建立相应的 iptables 条目,双重保障。
更多
calico的工作就是这些,通过主机mac、ip路由表 和 iptables合力完成静态路由的配置。
对于如何管理路由、安全信息和容器动态漂移等工作,Calico还做了更多的事情。但究其运行的实质,就是上面所描述的。