上篇:《Calico网络架构与实现深度解析(上)》
链接: link
#作者:程宏斌
文章目录
- [可选:启用 eBPF Service 代理](#可选:启用 eBPF Service 代理)
CalicoIPIP模式类型对照表

配置示例:
IPPool配置(IPIP模式)
apiVersion:crd.projectcalico.org/v1
kind:IPPool
metadata:
name:default-ipv4-ippool
spec:
cidr:10.244.0.0/16
ipipMode:Always#或CrossSubnet
vxlanMode:Never#必须禁用VXLAN
natOutgoing:true
nodeSelector:all()
ipipMode和vxlanMode不能同时启用。
- VXLAN模式(集中控制+VXLAN封装)
关键特点:
控制平面:无BGP,由Calico控制器(calico-typha+calico-kube-controllers)集中管理
数据平面:VXLAN封装(UDP4789),构建二层overlay网络
路由分发:通过Felix监听API,动态更新本地VXLANFDB(ForwardingDatabase)
无需底层网络支持Pod路由:所有跨节点通信走overlay
VXLAN封装机制
-
什么是VXLAN?
VirtualeXtensibleLAN,一种overlay隧道协议(RFC7348)
将二层以太帧封装在UDP包中,穿越三层网络
使用VNI(VXLANNetworkIdentifier)隔离租户(Calico默认VNI=4096)
-
封装格式
外层MAC\]\[外层IP\]\[UDP\]\[VXLAN头\]\[内层MAC\]\[内层IP+TCP/UDP+数据
外层源/目的IP:节点IP(如10.0.12.11→10.0.12.12)
UDP目的端口:4789(IANA标准VXLAN端口)
VNI:Calico默认为4096
内层IP:PodIP(如10.244.1.5→10.244.2.5)
-
MTU要求
VXLAN增加约50字节头部(UDP+VXLAN+外层IP)
建议底层网络MTU≥1550,或Pod网络MTU设为1450
总结:将完整的二层以太网帧作为负载(payload),封装在 UDP/IP 数据包中,通过三层网络进行传输;对端在接收到数据后解封装,还原出原始的二层以太网帧。
工作流程详解
场景:PodA(Node1)→PodB(Node2)
步骤1:Pod创建与CIDR分配
calico-kube-controllers为Node1分配Pod块:10.244.1.0/26
Felix在Node1创建veth接口(caliXXXX),分配PodIP
步骤2:VXLAN接口与FDB配置
Felix自动创建vxlan.calico接口:
ip link addv xlan.calico type vxlan id 4096 dev eth0 dstport 4789
同时监听API,得知Node2的IP和其PodCIDR(10.244.2.0/26)
更新FDB表(ForwardingDatabase):
bridge fdb append 00:00:00:00:00:00 dev vxlan.calico dst 10.0.12.12
步骤3:PodA发起通信
PodA(10.244.1.5)→PodB(10.244.2.5)
Node1查路由表:
10.244.2.0/26 dev vxlan.calico scope link
流量被导向vxlan.calico接口
步骤4:VXLAN封装
内核VXLAN模块根据FDB表,将帧封装为:
UDP10.0.12.11:任意→10.0.12.12:4789
→VXLAN(VNI=4096)
→[EthernetFrame:10.244.1.5→10.244.2.5]
从eth0发出
步骤5:Node2解封装
Node2收到UDP4789包
内核VXLAN模块解封装,得到原始以太帧
根据本地路由转发给PodB
配置示例
- IPPool配置
yaml
编辑
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
cidr: 10.244.0.0/16
ipipMode: Never # 必须禁用IPIP
vxlanMode: Always # 启用VXLAN
natOutgoing: true
nodeSelector: all() - 全局禁用BGP(Calico v3.20+)
yaml
编辑
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
calicoNetwork:
bgp: Disabled # 显式关闭BGP
如果未显式禁用BGP,某些旧版本可能仍启动BIRD,但不会用于Pod路由。
混合模式(Cross-Subnet智能封装)
| 模式 | 同子网 | 跨子网 |
|---|---|---|
| IPIPCross-Subnet | 无封装 | IPIP封装 |
| VXLANCross-Subnet | 无封装 | VXLAN封装 |
实现机制详解:
-
控制平面:BGP 仍然工作
所有节点仍运行 BIRD,通过 BGP 互相宣告 Pod CIDR
路由表中仍然存在类似条目:
10.244.2.0/26 via 10.0.12.12 dev eth0 proto bird
-
数据平面:Felix 动态决策是否封装
当 Pod 流量匹配到跨节点路由时,Felix(Calico 的 agent)会检查:
"目标节点 IP(NEXT_HOP)和本节点 IP 是否在同一个子网?"
判断逻辑(简化):
python
编辑
if (local_node_ip & subnet_mask) == (remote_node_ip & subnet_mask):
同子网 → 不封装,直接转发
else:
跨子网 → 封装 IPIP
- 转发
IPIPCross-Subnet:
同一子网内的节点之间:不封装,直接通过 BGP 路由通信(高性能)。
不同子网的节点之间:启用 IPIP 封装,将 Pod 流量封装在额外的 IP 包头中传输。
VXLANCross-Subnet:
同一子网内:不封装,直接路由。
跨子网:启用 VXLAN 封装,将 L2 帧封装在 UDP 报文中传输。
工作流程示例
场景
Node A:10.0.12.11(子网 10.0.12.0/24)
Node B:10.0.12.12(同子网)
Node C:10.0.13.11(子网 10.0.13.0/24)
同子网:Pod A(Node A) → Pod B(Node B)
Felix判断:10.0.12.11 和 10.0.12.12 同属 /24 → 同子网
不封装,直接发 IP 包:10.244.1.5 → 10.244.2.5
底层交换机二层可达,通信高效
不同子网:Pod A(Node A) → Pod C(Node C)
无论是 IPIP 还是 VXLAN Cross-Subnet 模式,在 跨子网通信 时,Calico 的封装逻辑都一样,不同的是封装方式,外层协议以及头部和端口不一样。
Felix 判断:10.0.12.11 vs 10.0.13.11 → 不同子网
启用IPIP封装:
外层:10.0.12.11 → 10.0.13.11 (协议号 4)
内层:10.244.1.5 → 10.244.3.5
穿越三层网络(如路由器、防火墙),确保可达
启用VXLAN封装
内层报文(原始):
源 IP:10.244.1.5(Pod A)
目的 IP:10.244.3.5(Pod C)
VXLAN 封装后(外层):
源 IP:10.0.12.11(Node A)
目的 IP:10.0.13.11(Node C)
协议:UDP(目的端口通常为 4789)
配置方式
IPPool 配置(关键)
# IPIP Cross-Subnet
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: default-pool
spec:
cidr: 192.168.0.0/16
ipipMode: CrossSubnet
natOutgoing: true
# VXLAN Cross-Subnet
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: default-pool
spec:
cidr: 192.168.0.0/16
vxlanMode: CrossSubnet
natOutgoing: true
eBPF模式(高性能新特性)
eBPF 模式如何工作
传统Calico(iptables 模式):
Pod → veth → netfilter (iptables) → routing → physical NIC
eBPF模式:
Pod → veth → eBPF program (attached to veth/tc/qdisc) → direct forwarding
eBPF程序直接挂载在veth接口或tc(traffic control)qdisc上,在数据包进入/离开Pod时立即处理,避免了iptables的复杂规则匹配和conntrack开销。
启用 Calico eBPF 模式
-
前提条件
Linux 内核 ≥ 4.19(推荐 5.4+)
所有节点L3互通(Pod CIDR 可路由)
禁用kube-proxy(或设为 --proxy-mode=iptables 但不生效)
-
配置方式(通过 FelixConfiguration)
apiVersion: crd.projectcalico.org/v1
kind: FelixConfiguration
metadata:
name: default
spec:
bpfEnabled: true
bpfLogLevel: ""
可选:启用 eBPF Service 代理
bpfKubeProxyIptablesCleanupEnabled: true
bpfKubeProxyMinSyncPeriod: 1s
启用后,Calico会自动:
加载eBPF程序到内核
清理kube-proxy创建的iptables规则(如果启用cleanup)
接管Service 和策略处理
模式对比表

推荐选择

网络要求

calico安装
节点要求
x86-64、arm64、ppc64le或s390x处理器
Calico必须能够管理cali主机上的接口。启用IPIP(默认)时,Calico也需要能够管理tunl接口。启用VXLAN时,Calico也需要能够管理vxlan.calico接口。
Linux内核3.10或更高版本,以及所需的依赖项。以下发行版具有所需的内核及其依赖项。
RedHatLinux7
CentOS7
Flatcar容器Linux
FedoraCore操作系统
Ubuntu18.04
Debian8
网络要求

安装方法
标准安装方式(使用Operator,推荐)
安装 Tigera Operator 和自定义资源定义。
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/operator-crds.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/tigera-operator.yaml
下载配置Calico所需的自定义资源。
curl https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/custom-resources.yaml -O
创建清单以安装 Calico。
kubectl create -f custom-resources.yaml
验证集群中的 Calico 安装。
kubectl get pods -n calico-system
快速安装
适用于单节点或简单测试集群
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml
此 YAML 文件中默认使用:
Pod CIDR: 192.168.0.0/16
封装模式:IPIP
如果你的集群使用其他 CIDR(如 10.244.0.0/16),需先编辑该YAML文件,修改CALICO_IPV4POOL_CIDR环境变量。