ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

【Kubernetes从入门到精通】第45篇:Calico——高性能的纯三层网络方案,BGP才是真男人的浪漫

【Kubernetes从入门到精通】第45篇:Calico——高性能的纯三层网络方案,BGP才是真男人的浪漫

上一篇【第44篇】Flannel——最简单的K8s网络方案
下一篇【第46篇】K8s DNS——CoreDNS的"黄页"服务


摘要

上一讲我们聊了Flannel——一个"能跑就行"的买菜车。它用VXLAN把Pod包打包封装,丢到物理网络上传输。简单是简单,但封装/解封装是有性能损耗的,带宽一般要打9折。

今天要讲的Calico,完全是另一种思路。它压根不走overlay封装,而是直接把Pod的IP"宣告"到物理网络的路由表里,让Pod IP成为真正可路由的三层地址。用一个词概括:BGP直连,裸奔到底

Calico的核心魅力有三点:(1)性能几乎等于物理网络,没有隧道开销;(2)NetworkPolicy支持最完整,是零信任网络的标配;(3)可观测性、可调试性极强——因为Pod IP就在路由表里,你用ip route就能看到一切。

不过Calico也有门槛:它要求你对底层网络有一定掌控力(至少得让BGP能通)。如果你在公有云上动不了路由器,那Calico的BGP模式可能玩不转,只能退而用IPIP/VXLAN封装。

读完这篇,你就知道为什么"大型生产集群基本都选Calico"——以及它和Flannel到底差在哪。


一、Calico的架构——三个组件各司其职

1.1 全景图

Calico不像Flannel那样"一个二进制搞定一切",它的组件分得更细:

【Calico 核心组件全景】 ┌──────────────────────────────────────────────────────────┐ │ Control Plane │ │ │ │ ┌────────────────┐ ┌────────────────┐ │ │ │ Typha │ │ kube-controllers│ │ │ │ (大规模优化) │ │ (同步K8s资源) │ │ │ └────────────────┘ └────────────────┘ │ └───────────────────────────────┬────────────────────────────┘ │ 读取/下发配置 ▼ ┌──────────────────────────────────────────────────────────┐ │ 每个 Node 上的 "守护三剑客" │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Felix │ │ BIRD │ │ confd │ │ │ │ (安全执行者) │ │ (BGP路由守护) │ │ (模板渲染) │ │ │ │ │ │ │ │ │ │ │ │ • 写iptables │ │ • 跑BGP协议 │ │ • 监听etcd │ │ │ │ • 写路由表 │ │ • 宣告Pod路由 │ │ • 渲染BIRD配置│ │ │ │ • 执行Network │ │ • 学习邻居路由 │ │ │ │ │ │ Policy │ │ │ │ │ │ │ └──────┬───────┘ └──────┬───────┘ └──────────────┘ │ │ │ │ │ └─────────┼──────────────────┼────────────────────────────────┘ ▼ ▼ ┌──────────────────┐ ┌──────────────────────────────────────┐ │ Linux 路由表 │ │ BGP 邻居 (其他Node的BIRD) │ │ (Pod CIDR路由) │ │ "我这台机器上有这些Pod,听我说!" │ └──────────────────┘ └──────────────────────────────────────┘

要点:Calico的核心是FelixBIRD。Felix负责在每个节点上"落地"——写iptables规则(实现NetworkPolicy)、写路由表;BIRD是一个标准的BGP客户端,负责把"我这台机器上有哪些Pod"这件事通过BGP协议告诉其他节点。confd负责把etcd里的配置渲染成BIRD的配置文件。三者配合,就实现了"Pod IP全网可路由"。

1.2 为什么需要三个组件?

你可能会问:Flannel一个二进制就搞定了,Calico搞这么复杂干嘛?

答案是——因为Calico要做两件Flannel做不了的事

【Flannel vs Calico 能力对比】 Flannel: • 只管"Pod包怎么到对端" → 一个二进制够用 • 不管网络策略 → 没有iptables规则要维护 • 不做路由宣告 → 不需要BGP Calico: • 管"Pod包怎么到对端" → Felix写路由 + BIRD宣告 • 还要管"哪些Pod能通哪些不能" → Felix写一大堆iptables • 还要管"动态学习路由" → BIRD跑BGP → 事情多了,自然要分工

二、BGP——Calico性能神话的源头

2.1 BGP是什么——“路由界的八卦协议”

BGP(Border Gateway Protocol)本来是互联网的核心路由协议,用来在各大运营商之间交换路由信息。你可以把它理解成**“路由界的八卦协议”**——每个路由器都在喊:“我能到这些网段!走我这儿!”

Calico把这套机制搬到了K8s集群里:

【Calico BGP 路由宣告——"Pod IP长腿了自己跑"】 Node1 (10.0.0.1) Node2 (10.0.0.2) ┌────────────────────┐ ┌────────────────────┐ │ Pod A: 10.244.1.5 │ │ Pod C: 10.244.2.5 │ │ Pod B: 10.244.1.6 │ │ Pod D: 10.244.2.6 │ └─────────┬──────────┘ └─────────┬──────────┘ │ │ BIRD 宣告: BIRD 宣告: "10.244.1.0/24 "10.244.2.0/24 经过我 10.0.0.1" 经过我 10.0.0.2" │ │ └────────── BGP 交换 ────────────────┘ │ ▼ Node1 的路由表现在多了: 10.244.2.0/24 via 10.0.0.2 Node2 的路由表现在多了: 10.244.1.0/24 via 10.0.0.1 → Pod A 访问 Pod C 时,包直接走物理路由,没有任何封装!

要点:这是Calico和Flannel最本质的区别。Flannel(VXLAN模式)把Pod包塞进UDP包里再发;Calico(BGP模式)直接让Pod IP成为物理网络的可路由地址。前者多了一层封装(约50字节开销+内核处理),后者几乎没有开销。在中大规模集群、高吞吐场景下,这个差距会被放大得很明显。

2.2 BGP vs VXLAN 性能对比

维度Calico BGP (Direct)Flannel VXLANCalico IPIP
是否封装❌ 无封装✅ VXLAN封装✅ IPIP封装
额外字节开销0~50字节~20字节
走物理路由✅ 是❌ 走隧道❌ 走隧道
性能极高(≈裸网)中等(打折)高(略打折)
对底层网络要求高(需BGP可达)低(只要IP通)
跨网段/跨云受限(需支持BGP)✅ 任意IP可达✅ 任意IP可达
调试难度低(路由表可见)高(隧道难追)

三、Calico的三种模式——什么时候用什么

3.1 IPIP / VXLAN / Direct 怎么选

Calico很贴心,给了你三种封装模式,按底层网络能力挑:

# 查看当前Calico的封装模式kubectl get ippool-oyaml|grep-E"encapsulation|vxlanMode|ipipMode"# 三种模式配置示例# 1. IPIP模式 (跨子网时封装,同子网直连)kubectl edit ippool default-ipv4-ippool# ipipMode: CrossSubnet ← 同二层广播域直连,跨子网才封装# ipipMode: Always ← 永远封装(最稳但最慢)# ipipMode: Never ← 完全不封装(就是纯BGP,要求网络可达)# 2. VXLAN模式 (不需要BGP,纯overlay)# vxlanMode: CrossSubnet / Always# 3. 纯BGP (Direct) —— ipipMode: Never 且 vxlanMode: Never# 性能最好,但要求所有Node之间IP层直接可达(无NAT、无防火墙挡BGP)
【Calico 三种模式决策树】 你的底层网络能跑BGP吗?(Node间能直接交换路由?) │ ├─ 能 → 选 Direct (ipipMode: Never) │ ✅ 性能最佳,Pod IP全网可路由 │ ⚠️ 要求:无NAT、防火墙放行BGP(179端口)、二层可达 │ ├─ 不能,但同子网内可达 → 选 IPIP: CrossSubnet │ ✅ 同子网直连(快),跨子网才封装(兜底) │ └─ 完全不可控(公有云/跨VPC) → 选 VXLAN / IPIP: Always ✅ 任意IP可达环境都能用 ❌ 有封装开销,性能略降

3.2 一张表总结

模式封装性能适用场景关键配置
Direct (BGP)⭐⭐⭐⭐⭐自建机房/可控网络/性能敏感ipipMode: Never
IPIP CrossSubnet部分⭐⭐⭐⭐混合网络(同子网多)ipipMode: CrossSubnet
IPIP Always⭐⭐⭐跨VPC/公有云ipipMode: Always
VXLAN⭐⭐⭐不要BGP又要overlayvxlanMode: Always

四、NetworkPolicy——Calico的"杀手锏"

4.1 为什么Calico的政策最完整

这是Calico和Flannel拉开差距的地方。Flannel根本不支持NetworkPolicy——它只管连通,不管隔离。而Calico从一开始就把网络策略当成核心能力。

# Calico 实现的高性能 NetworkPolicy 示例apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:deny-all-except-dnsnamespace:prodspec:podSelector:{}# 选中该namespace所有PodpolicyTypes:-Ingressingress:-ports:-port:53# 只允许DNS出站(否则Pod连名字都解析不了)protocol:UDP-port:53protocol:TCP
# Calico 还支持更强大的 GlobalNetworkPolicy (集群级)kubectl apply-f-<<EOF apiVersion: crd.projectcalico.org/v1 kind: GlobalNetworkPolicy metadata: name: default-deny-all spec: selector: all() types: - Ingress - Egress EOF# ↑ 这条规则会"默认拒绝一切"——典型零信任起点

要点:Calico的NetworkPolicy不是用iptables"暴力实现"的(那会像Flannel+其他插件那样规则爆炸),而是用** Felix + ipset** 高效实现的。ipset把大量IP放进一个集合,iptables只需一条规则就能匹配整个集合,性能比纯iptables链好太多。这也是为什么大规模集群的网络策略首选Calico。

4.2 Felix写规则的过程

【Felix 把 NetworkPolicy 翻译成 iptables】 你写: NetworkPolicy "只允许frontend访问backend:8080" │ ▼ Calico API (etcd/datastore) 通知 Felix │ ▼ Felix 计算: backend Pod IP集合 = {10.244.2.5, 10.244.2.6} frontend Pod IP集合 = {10.244.1.5, 10.244.1.6} │ ▼ Felix 调用 ipset 创建集合 ipset create cali-s:src frontend-ips ipset add cali-s:src 10.244.1.5 ipset add cali-s:src 10.244.1.6 │ ▼ Felix 写一条iptables规则搞定 -A FORWARD -m set --match-set cali-s:src src \ -m set --match-set cali-d:dst dst \ -p tcp --dport 8080 -j ACCEPT

五、实战:装一个Calico并验证BGP

5.1 安装(kubeadm场景)

# 下载官方manifestcurlhttps://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml-O# 按需修改 CIDR(要和 kubeadm --pod-network-cidr 一致)# 然后一把梭安装kubectl apply-fcalico.yaml# 等所有 calico-node 变成 Runningkubectl get pods-nkube-system-w|grepcalico

5.2 验证BGP邻居建立

# 进到某个 calico-node 容器里看BGP邻居kubectlexec-nkube-system calico-node-xxxxx --\calicoctlnodestatus# 输出示例:# Calico process is running.# IPv4 BGP status# +--------------+-------------------+-------+----------+-------------+# | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |# +--------------+-------------------+-------+----------+-------------+# | 10.0.0.2 | node-to-node mesh | up | 10:23:11 | Established |# | 10.0.0.3 | node-to-node mesh | up | 10:23:12 | Established |# +--------------+-------------------+-------+----------+-------------+# ↑ 看到 up / Established 就说明BGP邻居建立成功了!# 看路由表,确认学到了其他Node的Pod网段iproute show|grepbird# 10.244.2.0/24 via 10.0.0.2 dev eth0 proto bird# 10.244.3.0/24 via 10.0.0.3 dev eth0 proto bird

要点:看到proto bird的路由就是Calico通过BGP学到的。这说明Pod IP已经"上路由"了——从这一刻起,Pod间的通信走的是纯三层路由,没有任何overlay封装。你可以ping一下别的Node上的Pod IP验证连通性。


本篇小结

Calico的思路和Flannel完全相反:它不靠overlay封装,而是用BGP把Pod IP宣告成物理网络的可路由地址,性能几乎等于裸网。它的三大组件Felix(写规则/路由)、BIRD(跑BGP)、confd(渲染配置)配合默契,其中Felix+ipset实现的高效NetworkPolicy是它最硬的"杀手锏"。

选模式时记住决策树:网络可控就Direct(最猛),公有云受限就IPIP/VXLAN(兜底)。后面我们会看到CoreDNS——另一个"看不见但离不开"的基础设施。


上一篇【第44篇】Flannel——最简单的K8s网络方案
下一篇【第46篇】K8s DNS——CoreDNS的"黄页"服务


返回列表