Calico 默认走 BGP 而非 VXLAN,因其绕过隧道封装、直写主机路由表,降低延迟与 CPU 消耗;但需网络设备支持 BGP 且运维熟悉 BGP 策略,否则自动降级为 IPIP/VXLAN。

Calico 为什么默认走 BGP 而不是 VXLAN?
Calico 默认启用 BGP 模式,是因为它能绕过隧道封装开销,直接在主机路由表里写 Pod CIDR 的下一跳。你用 ip route 就能看到类似 10.244.1.0/24 via 192.168.5.2 dev eth0 proto bird 这样的条目——bird 是 Calico 的 BGP 守护进程。这比 VXLAN 少一层封包/解包,延迟低、CPU 消耗小。
但前提是你的网络设备(或 ToR 交换机)支持 BGP 邻居宣告,且运维团队熟悉 BGP 路由策略。如果只是单机测试或云上环境(如 AWS EC2 默认不开放 BGP),Calico 会 fallback 到 IPIP 或 VXLAN,这时性能和排障方式就完全变了。
- BGP 模式下 NetworkPolicy 生效路径清晰:
iptables+ipset+calico-felix同步策略,tcpdump -i eth0能直接看到原始 Pod 流量 - VXLAN 模式下所有跨节点流量被封装进 UDP 包,
tcpdump -i eth0 port 8472才能看到,NetworkPolicy 实际作用在 vxlan0 接口之后,行为更难验证 - 云厂商托管集群(如 EKS、AKS)通常禁用 BGP,Calico 自动降级;你得手动检查
calicoctl get ipippool -o wide和calicoctl get bgppeers确认当前模式
Cilium 的 eBPF 网络策略到底改了什么?
Cilium 不是在 iptables 上叠规则,而是把策略逻辑编译成 eBPF 程序,挂载到内核的网络收发路径(如 tc ingress 或 socket filter)。这意味着:策略生效不依赖 netfilter,也不受 conntrack 表项限制,L7 协议(HTTP/gRPC)识别是原生能力,不是靠用户态代理。
但代价也很实在:eBPF 程序必须适配内核版本,4.19+ 是硬门槛,5.4+ 才支持完整功能。你在 CentOS 7(默认 3.10 内核)上硬装 Cilium,cilium status 会卡在 KubeProxyReplacement: Disabled,且所有策略静默失效。
- 确认是否启用 eBPF 加速:
cilium status | grep "KubeProxyReplacement",输出Strict才表示接管成功 - L7 策略(如
http.method == "POST")只在 eBPF 模式下生效;fallback 到 iptables 模式时,这类规则会被忽略,但不会报错 - 调试时别只看
iptables -t filter -L,得用cilium monitor --type l7或bpftrace -e 'kprobe:__cgroup_bpf_run_filter_skb { printf("hit: %s\n", comm); }'
Flannel 的 host-gw 模式为何只适合二层同网段?
host-gw 是 Flannel 最轻量的后端,原理就是每个节点往其他节点的 Pod 子网加一条静态路由,下一跳指向对方节点的物理 IP。比如节点 A(192.168.1.10)运行 10.244.1.0/24,节点 B(192.168.1.11)运行 10.244.2.0/24,那么 A 上会自动添加 ip route add 10.244.2.0/24 via 192.168.1.11。
问题在于:这个 via 必须是直连路由(即同一子网),否则 Linux 内核无法解析下一跳 MAC 地址。如果你的节点分布在不同 VLAN 或跨机房,host-gw 会静默退化为 vxlan,但配置文件里没显式声明,你得从 journalctl -u kubelet | grep flannel 里翻出 "Using backend vxlan" 才知道。
- 检查实际使用的后端:
ps aux | grep flanneld,看启动参数里是--backend-type=host-gw还是--backend-type=vxlan - host-gw 下 NetworkPolicy 完全不生效——Flannel 本身不集成策略引擎,得靠额外组件(如 Calico 的
canal方案) - 云上环境基本不能用 host-gw:AWS/Azure 的节点 IP 是私有地址,但底层网络不是二层直连,ARP 请求根本发不出去
NetworkPolicy 不生效?先盯住 CNI 插件的 “IPAM 类型”
很多人的 NetworkPolicy 写对了,却始终不拦截流量,根源常在 IPAM(IP 地址管理)配置。比如你用 Calico,但误用了 host-local IPAM(常见于手动写的 bridge 配置),会导致每个节点分配的 Pod IP 子网不一致,Calico 的 felix 进程无法同步全局策略状态。
正确做法是让 Calico 管理自己的 IPAM:calicoctl create -f - 。这时候 <code>felix 才会基于该池生成 ipset 并下发策略。
- 验证 IPAM 是否由 CNI 插件自身管理:
ls /etc/cni/net.d/ | grep -E "(calico|cilium)",配置里不应出现"type": "host-local" - Flannel +
host-local是安全组合,但 NetworkPolicy 必须搭配 Calico/Cilium 等策略插件,不能指望 Flannel 自己实现 - Canal(Calico + Flannel)方案里,Flannel 只管 IP 分配,Calico 管策略——但两者共享同一个
ippool,配置冲突会导致felix反复重启
CNI 选型不是挑一个名字安上去,而是确认它是否真正在你的网络拓扑、内核版本、运维能力边界内完成三件事:IP 分配可收敛、路由路径可验证、策略执行可审计。少看文档里的“支持”,多跑一遍 ip route、tc filter show、cilium policy trace。


















