文章目录
#作者:程宏斌
前言
Calico是一个统一的平台,用于提供网络、网络安全和可观察性,适用于云端、本地或边缘的任何Kubernetes发行版。无论您是刚开始使用Kubernetes,还是进行大规模运营,Calico的开源版本、企业版本和云版本都能提供您所需的网络、安全和可观察性。
Calico的主要优势
单一平台可满足Kubernetes环境的所有网络、网络安全和可观察性需求
为任何Kubernetes发行版提供一致的网络和网络安全控制,确保工作负载的可移植性
无需额外软件即可将网络和网络安全扩展到多集群应用程序、虚拟机和裸机服务器
核心组件及其作用


Calico架构总结

calico网络模式
Calico是Kubernetes生态中主流的CNI网络插件之一,支持多种网络模式,核心围绕控制平面(路由分发)与数据平面(流量封装)的灵活组合。不同模式可根据部署环境、底层网络能力和性能需求自由选择。
控制平面与数据平面
| 平面类型 | 作用 | 可选技术 |
|---|---|---|
| 控制平面 | 负责分发和同步Pod路由信息 | BGP、KubernetesAPI(集中式) |
| 数据平面 | 负责实际的Pod间流量传输 | 纯路由(无封装)、IPIP、VXLAN |
Calico模式=控制平面+数据平面的组合,需整体考虑,不能单独配置。
Calico支持的主要网络模式
1.纯BGP模式(BGP+无封装)
关键点:
PodIP是全局可达的三层IP(不是overlay虚拟网络)
不需要VXLAN/IPIP封装,流量走原生IP路由
BGP仅用于控制平面(分发路由),数据平面是纯IP转发
BGP机制
-
"BGP通过学习到路由"
节点A运行BIRD(BGP 守护进程)
节点B向A宣告:我拥有10.244.2.0/26,下一跳是10.0.12.12
节点A的BIRD接收并解析 这条UPDATE消息
→ 学习到一条新路由
-
"将这条路由安装到本地路由表中"
BIRD调用内核接口(如 netlink),将路由写入Linux内核路由表
-
"包通过路由下一跳的方式转发"
当本机Pod(如 10.244.1.5)访问10.244.2.5时:
内核查路由表,匹配到上述条目
确定下一跳IP = 10.0.12.12
查ARP表(或发ARP请求)获取10.0.12.12的MAC地址
构造以太帧:
目的MAC = 节点B的物理网卡MAC
IP包:源=10.244.1.5,目的=10.244.2.5
从eth0发出
总结:通过学习并接收来自其他路由器的路由信息,将这些路由安装到本地路由表中,数据包随后依据路由表中的下一跳信息进行转发
工作流程详解:
步骤1:Pod创建
Kubelet调用CNI(Calico)
Calico从IPPool中分配一个IP(如10.244.1.5)
在节点上创建vethpair:caliXXXX↔Podeth0
步骤2:本地路由注入
Felix在本机添加直连路由:
iproute add 10.244.1.5/32 dev caliXXXX scope link
同时为本节点分配的整个块(如/26)添加blackhole路由(防环):
iproute add blackhole 10.244.1.0/26 proto bird
步骤3:BGP路由宣告
BIRD将10.244.1.0/26作为BGP路由,通过BGP会话宣告给其他所有节点
宣告内容:"前往10.244.1.0/26,请发给我(节点IP:10.0.12.11)"
步骤4:其他节点学习路由
节点B的BIRD收到路由后,写入内核路由表:
iproute add 10.244.1.0/26 via 10.0.12.11 dev eth0 proto bird
步骤5:Pod跨节点通信
PodA(10.244.2.5)→PodB(10.244.1.5)
节点A查路由表:10.244.1.0/26via10.0.12.11
直接发送IP包:源=10.244.2.5,目的=10.244.1.5
底层网络将包路由到节点B(10.0.12.11)
节点B收到后,根据本地直连路由转发给Pod
配置示例:
- IPPool(BGP模式)
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
cidr: 10.244.0.0/16
ipipMode: Never # 关键:禁用 IPIP
vxlanMode: Never # 关键:禁用 VXLAN
natOutgoing: true
nodeSelector: all()
全局启用BGP(Calicov3.20+)
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
calicoNetwork:
bgp: Enabled # 显式启用 BGP
在旧版Calico(非Operator安装),BGP默认启用,无需额外配置。
- IPIP模式(BGP+IPIP封装)
用BGP告诉其他节点"我拥有哪些PodIP段",但实际通信时将PodIP包封装在节点IP的IP包中(IPIP),穿越不支持Pod路由的网络。
关键点:
控制平面:BGP(BIRD)负责分发Pod子网路由(如10.244.1.0/26via10.0.12.11)
数据平面:IPIP(IP-in-IP,协议号4)负责封装Pod流量
适用场景:节点跨子网、公有云、NAT网络、防火墙只允许节点IP通信等
IPIP封装机制
-
什么是IPIP?
IPIP(IP Encapsulation with in IP)是Linux内核原生支持的隧道协议(RFC2003)
将一个IP包(内层:Pod→Pod)封装在另一个IP包(外层:Node→Node)中
协议号为4(区别于TCP=6、UDP=17)
-
封装格式
外层IP头\]\[内层IP头+TCP/UDP+数据
外层源IP:源节点IP(如10.0.12.11)
外层目的IP:目标节点IP(如10.0.12.12)
内层源IP:源PodIP(如10.244.1.5)
内层目的IP:目标PodIP(如10.244.2.5)
-
MTU调整
IPIP增加20字节头部
默认MTU1500→Pod网络MTU通常设为1440
避免分片,提升性能
总结:将一个 IP 包(内层包)封装到另一个标准的 IPv4 包(外层包)中,实现数据的转发;接收端在收到封装包后对其进行解封装,恢复出原始的内层 IP 包。
工作流程详解:
场景:PodA(Node1)→PodB(Node2)
步骤1:Pod创建与路由注入(同BGP模式)
Node1分配PodIP:10.244.1.5
Felix添加本地路由:
iproute add 10.244.1.5/32 dev caliXXXX
iproute add blackhole 10.244.1.0/26 proto bird
步骤2:BGP宣告Pod子网
Node1的BIRD向其他节点宣告:
"前往10.244.1.0/26,请发给我(10.0.12.11)"
Node2收到后,写入路由表:
iproute add 10.244.1.0/26 via 10.0.12.11 dev eth0 proto bird
步骤3:PodA发起通信
PodA(10.244.1.5)→PodB(10.244.2.5)
Node1查路由:10.244.2.0/26via10.0.12.12
步骤4:IPIP封装(关键!)
因为配置了ipipMode:Always,Felix拦截该流量
将原始包(10.244.1.5→10.244.2.5)封装为:
外层:10.0.12.11→10.0.12.12(协议号4)
内层:10.244.1.5→10.244.2.5
从eth0发出
步骤5:Node2解封装
Node2收到IPIP包(协议号4)
内核自动解封装(通过tunl0接口)
得到原始包:10.244.1.5→10.244.2.5
根据本地直连路由转发给PodB