第276篇:Flannel、Calico、Cilium 方案对比

关键词:Flannel、Calico、Cilium、CNI、网络方案、BGP、Iptables、eBPF、Kubernetes网络


一、引言

Kubernetes的CNI插件机制允许用户选择不同的网络方案来实现Pod间的通信、服务发现和网络安全。Flannel、Calico和Cilium是Kubernetes生态中最流行的三大CNI方案,它们各自采用了不同的技术路线,适用于不同的场景。

本文将从技术原理、性能、功能和安全等多个维度对这三种方案进行全面对比,帮助读者根据自身需求做出合理选择。

二、核心概念

2.1 Flannel

Flannel是最简单、最早成熟的Kubernetes CNI方案之一:

核心特点: - 基于Overlay隧道(VXLAN或Host-GW)实现Pod网络 - 配置简单,开箱即用 - 支持多种后端(VXLAN、Host-GW、UDP、WireGuard) - 不支持网络策略(NetworkPolicy)

Flannel的后端对比:

后端 原理 性能 跨子网
VXLAN MAC-in-UDP封装 中 支持
Host-GW 静态路由 高 不支持(需同子网)
UDP User-space UDP转发 低 支持
WireGuard WireGuard加密隧道 中高 支持

2.2 Calico

Calico是由Tigera(现VMware)开发的基于BGP的CNI方案:

核心特点: - 使用BGP协议分发Pod路由(无Overlay) - 支持Iptables/eBPF两种数据面 - 强大的网络策略(NetworkPolicy)支持 - 支持跨主机、跨子网部署

Calico的架构组件:

组件 说明
calico-node 节点上的DaemonSet,运行BGP和veth配置
calico-typha 大规模集群的BGP连接聚合器
Federation 跨K8s集群的联邦路由
BIRD BGP协议实现

2.3 Cilium

Cilium是基于eBPF/XDP技术的高性能CNI方案:

核心特点: - 基于eBPF/XDP的数据面,绕过iptables - 原生支持L7网络策略(HTTP/gRPC/Kafka) - 集成可观测性(Hubble) - 支持Service Mesh(Cilium Service Mesh)

Cilium架构:

组件 说明
cilium-agent 节点上的eBPF程序管理和网络配置
cilium-operator 集群级别的控制面
Hubble 网络可观测性工具
eBPF程序 数据面转发和策略执行

三、技术细节

3.1 网络模型对比

网络模型对比 - 图示

3.2 性能对比

指标 Flannel(VXLAN) Calico(BGP) Cilium(eBPF)
Pod间延迟 中(封装开销) 低(路由转发) 最低(XDP卸载)
吞吐量 中 高 最高
CPU占用 中(内核封装) 低(路由) 极低(eBPF)
连接建立延迟 中 低 低
大规模Pod性能 下降 稳定 稳定

3.3 功能对比

功能 Flannel Calico Cilium
Pod网络 ✓ ✓ ✓
Service ✓(K8s原生) ✓(K8s原生) ✓(可替代kube-proxy)
NetworkPolicy ✗ ✓(L3/L4) ✓(L3-L7)
L7策略 ✗ ✗(需额外组件) ✓(原生)
加密隧道 WireGuard后端 WireGuard WireGuard/IPsec
可观测性 ✗ 有限 Hubble(强大)
多集群 ✗ Federation ClusterMesh
IPAM 简单 BGP/Host-local 多种IPAM
kube-proxy替代 ✗ ✗ ✓

3.4 加密通信方案对比

容器网络加密方案保障Pod间通信的机密性:

加密方案 实现方式 性能损耗 适用场景
Calico WireGuard WireGuard隧道加密 5-15% 跨可用区加密
Calico IPsec IKEv2/IPsec隧道 10-20% 合规要求加密
Cilium WireGuard WireGuard隧道加密 5-15% 跨集群加密
Flannel WireGuard WireGuard隧道加密 5-15% 简单加密需求
硬件加密(NIC) 网卡TLS卸载 <1% 高性能加密

Calico WireGuard加密配置:

apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  calicoNetwork:
    ipPools:
    - cidr: 192.168.0.0/16
      encapsulation: WireGuard  # 启用WireGuard加密
      natOutgoing: Enabled
    wireguard: Enabled

3.5 大规模集群性能基准测试

基于100节点集群的标准化测试数据:

测试场景 Flannel VXLAN Calico BGP Cilium eBPF
同节点Pod PTP延迟 0.5μs 0.5μs 0.5μs
跨节点Pod PTP延迟 12μs 8μs 5μs
10万Pod IOPS(4K随机读) 850K 1.2M 1.8M
Pod创建时间(P95) 2.1s 1.8s 1.5s
Service DNAT延迟 15μs(ipt) 15μs(ipt) 3μs(eBPF)
NetworkPolicy规则数(1000条) N/A 500μs匹配 5μs匹配
CPU占用(空闲) 2% 1.5% 0.8%
内存占用(每节点) 128MB 256MB 384MB

3.6 CNI 升级与迁移策略

迁移场景 迁移方案 风险等级 停机时间
同CNI版本升级 滚动升级DaemonSet 低 零停机
Flannel→Calico 双CNI并行,逐步切换 中 短停机
Calico→Cilium 双CNI并行,数据面切换 高 需维护窗口
Iptables→eBPF Calico内模式切换 低 短停机

Flannel到Calico迁移步骤:

# 1. 部署Calico(与Flannel并存)
kubectl apply -f calico.yaml

# 2. 验证Calico网络正常
kubectl run test-pod --image=busybox --restart=Never --rm -it -- ping <calico-pod-ip>

# 3. 逐步迁移工作负载
# 将关键业务的Pod Spec中重新调度, 使其使用Calico网络

# 4. 验证全部流量走Calico
# 检查节点路由表, 确认Pod路由由Calico管理

# 5. 删除Flannel
kubectl delete -f kube-flannel.yaml

# 6. 清理Flannel残留(清理vxlan接口等)
ip link delete flannel.1

四、实战配置/案例分析

4.1 Flannel 部署

# Flannel 部署配置
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: flannel
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "name": "flannel",
      "type": "flannel",
      "delegate": {
        "isDefaultGateway": true
      }
    }
---
# kube-flannel DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel
  namespace: kube-system
spec:
  template:
    spec:
      containers:
      - name: kube-flannel
        image: flannelcni/flannel:v0.23.0
        args:
        - --ip-masq
        - --kube-subnet-mgr
        env:
        - name: FLANNEL_NETWORK
          value: "10.244.0.0/16"
        - name: FLANNEL_BACKEND
          value: "vxlan"

4.2 Calico 部署

# Calico 部署配置
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  calicoNetwork:
    ipPools:
    - blockSize: 26
      cidr: 192.168.0.0/16
      encapsulation: IPIP  # 或 CrossSubnet, None
      natOutgoing: Enabled
    nodeAddressAutodetectionV4:
      firstFound: true
    bgpConfig:
      asNumber: 64512
---
# NetworkPolicy 示例
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-web-traffic
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 80

4.3 Cilium 部署

# Cilium 部署配置(Helm values)
# helm install cilium cilium/cilium --namespace kube-system \
#   --set cluster.name=cluster1 \
#   --set ipam.mode=kubernetes \
#   --set tunnel=disabled \
#   --set routingMode=native

# CiliumNetworkPolicy (L7策略)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: l7-http-policy
spec:
  endpointSelector:
    matchLabels:
      app: api-server
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: frontend
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
      rules:
        http:
        - method: GET
          path: "/api/.*"
          headers:
          - key: Authorization
            operator: Exists

4.4 故障案例:Calico BGP会话频繁闪断

现象:Kubernetes集群中Calico的BGP会话频繁断开重连,导致Pod间网络间歇性中断。

排查过程:

# 1. 检查BGP会话状态
kubectl exec -n calico-system calico-node-xxx -- calicoctl node status

# 发现BGP Peer状态频繁在Established和Idle之间切换

# 2. 检查BGP日志
kubectl logs -n calico-system calico-node-xxx -c bird
# BGP Keepalive超时, 对端未响应

# 3. 检查网络连通性
# 节点间网络延迟正常, 但偶尔出现丢包

# 4. 检查安全组/ACL
# 云平台安全组未放行BGP端口(TCP 179)和IPIP协议(协议号4)

根因:云平台的安全组规则未放行BGP协议(TCP 179)和IPIP封装(协议号4),导致BGP Keepalive报文偶尔被安全组丢弃,BGP会话超时断开。

解决: 1. 在云平台安全组中放行TCP 179端口(BGP) 2. 放行IPIP协议(协议号4)或改用VXLAN封装 3. 增大BGP Keepalive超时时间作为临时缓解

五、总结

方案 适用场景 优势 劣势
Flannel 简单环境, 开发测试 配置简单, 开箱即用 功能有限, 无NetworkPolicy
Calico 生产环境, 安全要求高 BGP路由, 强NetworkPolicy 配置复杂度中
Cilium 高性能, 微服务, 可观测性 eBPF高性能, L7策略, Hubble 配置复杂, 学习曲线陡
选型建议 说明
小规模/测试 Flannel(VXLAN/Host-GW)
中大型生产 Calico(BGP+Iptables)
高性能/微服务 Cilium(eBPF)
混合云/多云 Calico Federation/Cilium ClusterMesh
合规加密 Calico WireGuard/Cilium WireGuard
网络可观测 Cilium Hubble

思考

  1. Flannel的VXLAN后端和Calico的IPIP后端都使用了隧道封装,为什么Calico还推荐使用BGP路由而非隧道?
  2. Cilium可以替代kube-proxy,这是如何实现的呢?替代后有什么优势?
  3. 在云环境中部署Kubernetes时,CNI方案与云平台的VPC网络如何协调?是否会产生冲突?
  4. 容器网络加密(WireGuard/IPsec)带来的性能损耗在什么场景下可以接受?如何降低加密开销?
  5. 从Flannel迁移到Calico时,如何确保迁移过程中业务不中断?

下篇预告:第277篇:Cilium eBPF 数据面与网络性能