4、Calico架构与组件:Felix、BIRD、confd、etcd/kubernetes datastore、Calico CNI插件、IPAM与IP池管理
Calico 是云原生领域应用最广泛的 CNI 方案之一,其核心设计理念是“基于三层路由实现 Pod 互联”,而非依赖 Overlay 隧道。理解 Calico 的架构,关键在于厘清其控制平面与数据平面的分工:控制平面负责策略分发与路由计算,数据平面则依托 Linux 内核的 iptables/ipset 与路由表完成实际转发。本章将深入拆解 Calico 的六大核心组件——Felix、BIRD、confd、etcd/kubernetes datastore、Calico CNI 插件以及 IPAM 与 IP 池管理,并结合实战场景说明它们如何协同工作。
4.1 核心原理:控制平面与数据平面的解耦设计
Calico 的架构设计遵循“控制与转发分离”的经典网络原则。控制平面由运行在每个节点上的代理进程组成,负责从数据存储中读取期望状态(Desired State),并将其转化为内核数据平面的实际配置。数据平面则完全依赖 Linux 内核的既有能力——路由表、iptables、ipset 和 veth 虚拟网卡——实现高性能的三层转发。
这种设计带来三个关键优势:性能高,因为数据包走内核原生路由路径,无隧道封装开销;可扩展性强,BGP 协议天然支持大规模路由分发;策略能力强,iptables 提供细粒度的五元组匹配能力。但同时也要求运维人员对 Linux 网络栈有较深理解,排障时需同时关注路由表、iptables 链和 BGP 会话状态。
4.2 组件详解与职责边界
4.2.1 Felix:节点代理与策略执行引擎
Felix 是运行在每个 Kubernetes 节点上的守护进程,它通过 watch 机制监听 datastore 中的资源变化(如 NetworkPolicy、WorkloadEndpoint、IPPool 等),并将这些期望状态翻译为内核配置。具体职责包括:
- 编程 iptables 规则:为每个 WorkloadEndpoint 生成 INPUT/OUTPUT/FORWARD 链规则,实现 NetworkPolicy 的允许/拒绝逻辑。
- 维护 ipset 集合:将 IP 地址、端口等匹配条件组织为 ipset,减少 iptables 规则数量,提升匹配效率。
- 管理路由表:为本地 Pod 添加直连路由,并确保路由表与当前节点上的端点状态一致。
- 接口监控:监听 veth 接口的创建与删除,动态调整策略。
Felix 的性能直接影响节点转发能力。在大型集群中,Felix 需要处理数千条 iptables 规则,因此 Calico 引入了 XDP 加速和 eBPF 数据面(可选)来优化性能。
4.2.2 BIRD:BGP 路由反射与分发
BIRD(BIRD Internet Routing Daemon)是 Calico 默认的 BGP 客户端,负责将本节点的 Pod 网段路由通告给其他节点。在集群内部,BIRD 运行在两种模式之一:
- Node-to-Node Mesh(全互联模式):每个节点与所有其他节点建立 BGP 会话,适合节点数少于 50 的小型集群。
- Route Reflector(路由反射模式):指定若干节点作为路由反射器,其他节点只与反射器建立会话,适合大规模集群。
BIRD 的配置由 confd 动态生成,当 Felix 更新路由表后,BIRD 会通过 BGP 协议将新的路由通告出去。运维人员可通过 birdctl show route 查看 BIRD 学习到的全部路由。
4.2.3 confd:模板驱动的配置生成器
confd 是一个轻量级的配置管理工具,它监听 datastore 中的键值变化,并根据预定义的模板(如 bird.cfg.template)重新生成 BIRD 配置文件。当配置变更时,confd 会触发 BIRD 重新加载配置,而无需重启进程。
confd 的存在使得 Calico 的配置管理变得声明式:用户只需修改 datastore 中的资源对象,confd 自动完成配置下发。这种模式避免了手工编辑配置文件的错误,也便于版本控制。
4.2.4 Datastore:etcd 与 Kubernetes API Server 双模式
Calico 支持两种数据存储方式:
| 特性 | etcd 模式 | Kubernetes datastore 模式(KDD) |
|---|---|---|
| 存储位置 | 独立 etcd 集群 | Kubernetes API Server 中的 CRD |
| 适用场景 | 非 Kubernetes 环境(如 OpenStack) | Kubernetes 原生环境 |
| 运维复杂度 | 需额外维护 etcd 集群 | 复用 K8s 高可用能力 |
| 一致性 | etcd 自身保证 | 依赖 K8s 的乐观锁机制 |
| 推荐度 | 已逐步淘汰 | 官方推荐,默认模式 |
在 KDD 模式下,Calico 将 WorkloadEndpoint、NetworkPolicy、IPPool 等资源定义为 CRD(Custom Resource Definition),通过 Kubernetes API 进行读写。这种方式简化了部署,但需要注意 CRD 的版本兼容性。
4.2.5 Calico CNI 插件:Pod 网络接入的“最后一公里”
Calico CNI 插件是 kubelet 调用的二进制文件,负责在 Pod 创建时完成网络接入。其工作流程如下:
- 创建 veth pair:一端放入 Pod 网络命名空间,另一端连接到宿主机 root 命名空间。
- 配置 Pod 侧 IP:调用 IPAM 插件从指定 IP 池分配 IP 地址。
- 设置路由:在 Pod 内添加默认路由指向 veth 对端。
- 通知 Felix:将新创建的 WorkloadEndpoint 信息写入 datastore,触发 Felix 编程策略。
CNI 插件本身不负责策略执行,它只做“连接”和“地址分配”,策略由 Felix 在后续异步完成。这种设计保证了 CNI 操作的快速响应。
4.2.6 IPAM 与 IP 池管理
Calico 的 IPAM(IP Address Management)模块负责从 IPPool 中分配和回收 IP 地址。IPPool 是 Calico 的核心资源对象,定义了可用的 CIDR 范围、是否允许重叠、是否启用 NAT 等属性。
# 查看当前集群的 IP 池
calicoctl get ippool -o yaml
# 创建新的 IP 池
calicoctl create -f - <<EOF
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: production-pod-cidr
spec:
cidr: 10.244.0.0/16
ipipMode: Always
natOutgoing: true
disabled: false
EOF
IPAM 支持两种分配策略:自动分配(按顺序从 IP 池中选取)和 手动指定(通过注解 cni.projectcalico.org/ipAddrs 指定)。生产环境建议为不同业务规划独立 IP 池,便于网络隔离和故障排查。
4.3 实战场景:跨节点 Pod 通信的完整链路
假设集群有两个节点:Node A(10.0.0.1)和 Node B(10.0.0.2),Pod A 运行在 Node A 上,IP 为 10.244.1.5;Pod B 运行在 Node B 上,IP 为 10.244.2.7。当 Pod A 向 Pod B 发送数据包时,完整链路如下:
- Pod A 发出数据包:目标 IP 为 10.244.2.7,源 IP 为 10.244.1.5,通过 veth 进入 Node A 的 root 命名空间。
- Node A 路由查询:内核查询路由表,发现 10.244.2.0/24 网段的路由下一跳为 10.0.0.2(Node B),出接口为 eth0。
- iptables 检查:数据包经过 FORWARD 链,Felix 预先配置的规则允许该流量(基于 NetworkPolicy 判断)。
- BGP 路由来源:Node A 的路由表由 Felix 写入,而 Node B 的 10.244.2.0/24 路由是通过 BIRD 从 Node B 学习到的。
- Node B 接收:数据包到达 Node B 的 eth0,内核查询路由表,发现 10.244.2.7 是本地直连路由,通过 veth 转发给 Pod B。
1.
ip route 查看路由表是否存在目标网段路由;2.
birdctl show route 确认 BIRD 是否学习到该路由;3.
iptables -L -n -v | grep 10.244.2.7 检查是否有策略丢弃;4.
calicoctl node status 查看 Felix 与 BIRD 的健康状态。
4.4 常见误区与最佳实践
误区二:忽略 IP 池规划。如果多个集群共用同一 CIDR,会导致路由冲突。建议为每个集群规划独立的 IP 池,并预留扩展空间。
误区三:盲目调整 Felix 参数。例如,将
FelixChainInsertMode 改为 Append 可能导致策略被其他规则绕过。
最佳实践建议:
- 生产环境启用
natOutgoing: true,确保 Pod 访问外部网络时源地址被正确转换。 - 对于大规模集群(超过 100 节点),配置 BGP Route Reflector,避免全互联带来的会话数爆炸。
- 定期使用
calicoctl get workloadendpoint检查端点状态,确保与 Pod 实际状态一致。 - 监控 Felix 的 iptables 规则数量,若超过 5000 条,考虑使用 ipset 或 eBPF 数据面优化。
总结而言,Calico 的架构设计体现了“简单、高效、可扩展”的理念。理解每个组件的职责边界与交互方式,是进行网络排障、性能调优和容量规划的基础。在实际运维中,建议结合 calicoctl 命令行工具和日志分析,逐步建立对集群网络状态的全局视图。