Flannel 不是 Kubernetes 的"官方默认" CNI ,但在早期社区和简单环境中,它因"开箱即用"被大量教程和一键安装工具(如旧版 Rancher、某些 kubeadm 脚本)作为事实上的默认选择 。严格来说,kubeadm init 本身并不安装任何 CNI,集群在 CNI 就绪前会处于 NotReady 状态。
一、Flannel 架构与核心组件
Flannel 的设计哲学是"最小可用"------它只做一件事:为每个节点分配一个 Pod 子网段,并确保跨节点的 Pod IP 可路由。
┌─────────────────────────────────────────┐
│ Kubernetes API / etcd │
│ (存储 Node -> Subnet 映射关系) │
└─────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
Node 1 Node 2 Node 3
┌─────────┐ ┌─────────┐ ┌─────────┐
│flanneld │ │flanneld │ │flanneld │
│(daemon) │ │(daemon)│ │(daemon) │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
▼ ▼ ▼
flannel.1 flannel.1 flannel.1
(VTEP设备) (VTEP设备) (VTEP设备)
│ │ │
└─────────────┴──────────────┘
底层物理网络
(Underlay/L3网络)
|--------------------|---------------------------------------------------------------------------|
| 组件 | 作用 |
| flanneld | 每个节点上的守护进程,监听 etcd/K8s API 获取集群子网分配,配置本地路由、ARP、FDB、VXLAN 设备 |
| flannel CNI 插件 | 真正的 CNI 二进制(/opt/cni/bin/flannel),在 Pod 创建时调用,负责配置 veth pair、IPAM、将容器接入网桥 |
| Subnet Manager | 子网分配器,通过 etcd 或 K8s API(kube-subnet-mgr)维护 Node.Spec.PodCIDR |
| Backend | 数据面实现:VXLAN、UDP、host-gw、AWS VPC、GCE 路由等 |
二、VXLAN Overlay 的底层实现(深度技术拆解)
Overlay 的本质是"在现有三层网络上虚构出一个二层连通域"。Flannel 的 VXLAN 模式并非简单"加个隧道",而是依赖 Linux 内核的 VXLAN 虚拟设备 与 网桥/路由协同 完成。
2.1 子网分配与节点初始化
当 flanneld 启动时:
- 从 K8s API 读取或向 etcd 注册:Node1 -> 10.244.1.0/24,Node2 -> 10.244.2.0/24。
- 在节点上创建 flannel.1 设备(类型为 vxlan,VNI 默认为 1,UDP 目的端口 4789)。
- flannel.1 是 VTEP(VXLAN Tunnel End Point),拥有独立的 MAC 地址(如 f2:xx:xx:xx:xx:01)和 IP(如 10.244.1.0/32,子网网关地址)。
- 创建 cni0 网桥(或复用已有网桥),Pod 的 veth 对端接入此网桥。
2.2 跨节点 Pod 通信的完整包转发流程
假设 Pod A (10.244.1.2) 在 Node 1 上,要访问 Pod B (10.244.2.3) 在 Node 2 上:
Pod A eth0
│
▼ (veth pair)
vethxxxx\] ──► \[cni0 网桥
│
▼ (路由决策)
查路由表:10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink
│
▼ (L2 封装)
需要 10.244.2.0 的 MAC 地址
查 ARP 表:10.244.2.0 → f2:xx:xx:xx:xx:02 (Node2 flannel.1 的 MAC)
│
▼ (VXLAN 封装)
帧目的 MAC = f2:xx:xx:xx:xx:02
交给 flannel.1 设备
│
▼ (内核 VXLAN 模块)
查 FDB (Forwarding Database):
f2:xx:xx:xx:xx:02 → VTEP IP = Node2_Physical_IP (如 192.168.1.12)
│
▼ (UDP 封装)
外层 UDP 包:
Src IP: Node1_Physical_IP (192.168.1.11)
Dst IP: Node2_Physical_IP (192.168.1.12)
Src Port: 随机高位端口
Dst Port: 4789 (VXLAN)
VNI: 1
内层原始以太网帧(完整保留):
Src MAC: f2:xx:xx:xx:xx:01
Dst MAC: f2:xx:xx:xx:xx:02
IP 头: 10.244.1.2 → 10.244.2.3
│
▼ (底层 Underlay)
通过节点物理网卡 eth0 发出,经底层 IP 网络到达 Node 2
Node 2 的解封装过程:
- eth0 收到 UDP 4789 报文,内核 VXLAN 驱动识别 VNI=1 且目的 IP 匹配本机 VTEP IP,执行解封装。
- 取出内层以太网帧,目的 MAC 是 flannel.1 的 MAC,交给 flannel.1 设备。
- 内核查路由表:10.244.2.3 属于本地直连子网,通过 cni0 网桥转发。
- cni0 根据 MAC 地址或 fdb 将帧送到对应 Pod 的 veth 对端,最终到达 Pod B。
2.3 三张关键内核表项
Flannel 的 VXLAN 模式依赖 Linux 内核维护以下表项,而非用户态进程逐包处理:
|--------------------|-------------------------------------|-----------------------------------------------------------------------------------|
| 表项 | 作用 | 查看命令 |
| 路由表 | 决定哪个目的子网走 flannel.1 | ip route show → 10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink |
| ARP 表(L3 代理模式) | 将远端子网网关 IP 解析为远端 VTEP MAC | ip neigh show dev flannel.1 → 10.244.2.0 lladdr f2:xx:xx:xx:xx:02 PERMANENT |
| FDB(转发数据库) | 将 VTEP MAC 映射到远端物理节点 IP(VXLAN 隧道对端) | bridge fdb show dev flannel.1 → f2:xx:xx:xx:xx:02 dst 192.168.1.12 self permanent |
关键 :onlink 和 PERMANENT 标志意味着这些表项是 flanneld 静态注入的 ,而非动态学习。这避免了大规模集群中的 ARP 广播风暴。
三、没有 Overlay(如 host-gw 模式)会怎样?
Flannel 的 host-gw 模式是纯三层 Underlay 方案,不封装 VXLAN,直接通过路由表将 Pod 子网指向节点物理 IP。
路由表(Node 1):
10.244.2.0/24 via 192.168.1.12 dev eth0
10.244.3.0/24 via 192.168.1.13 dev eth0
3.1 没有 Overlay 的前提条件
host-gw 能工作的硬性要求:
- 所有节点必须在同一个二层网络(或底层路由器已配置到各节点 Pod CIDR 的静态路由)。
- 节点之间可以直接通过物理 IP 互通,无需 NAT。
- 底层网络(交换机/路由器)必须能够处理目的 IP 为 Pod CIDR 的流量,或者节点作为网关代理 ARP。
3.2 没有 Overlay 会发生的问题
|--------------|-----------------|--------------------------------------------------------------------|
| 场景 | 问题 | 根因 |
| 跨云/跨 VPC | Pod 完全无法跨节点通信 | 云厂商 VPC 路由表默认不认识 10.244.x.x,且节点物理 IP 跨 VPC 不通 |
| 云厂商路由表限制 | 大规模集群路由条目爆炸 | AWS VPC 路由表默认上限 100 条(可扩展但收费),Flannel host-gw 每节点占一条。1000 节点集群直接触顶 |
| 节点不在同一子网 | 跨子网 Pod 不通 | 路由器没有 Pod CIDR 路由,且节点不会为 Pod IP 做代理 ARP(除非开启,但大规模 ARP 广播危险) |
| 安全组/防火墙 | 底层网络策略阻断 Pod 流量 | Pod IP 不在安全组白名单内,被云厂商 ACL 直接丢弃 |
| L2 广播域过大 | 潜在 ARP 广播风暴 | 若强行将大量节点放入同一二层域,广播流量可能冲击核心交换机 |
3.3 Overlay 的价值总结
Overlay(VXLAN)解决的核心问题是"在底层网络不可控或不可扩展的情况下,虚构出一张可控的虚拟网络":
- 解耦:Pod IP 规划与底层网络完全解耦,无需向网络部门申请静态路由。
- 穿透:只要节点间 UDP 4789 可达(哪怕跨 NAT、跨 VPC peering),Pod 就能互通。
- 隔离:VNI 提供多租户隔离基础(虽然 Flannel 本身只用一个 VNI)。
- 代价 :MTU 减少 50 字节(VXLAN 头开销),CPU 增加封装/解封装开销(通常 5-15%),排查故障需抓两层包(flannel.1 + eth0)。
四、Flannel 的局限与银行场景考量
|---------------------|---------------------------------------------------------|-----------------------------------|
| 局限 | 技术细节 | 银行影响 |
| 无 NetworkPolicy | Flannel 本身不提供 L3/L4 网络策略,需配合 Calico(Canal 方案)或独立 Cilium | 金融级零信任要求默认拒绝,Flannel 单独使用不满足等保微隔离 |
| 性能天花板 | VXLAN 用户态无 DPDK/eBPF 加速,纯内核转发 | 核心交易高吞吐场景,延迟敏感 |
| 无多集群互联 | Flannel 无内置 Cluster Mesh | 两地三中心场景需额外 Submariner/Cilium |
| etcd 压力(旧版本) | 早期 Flannel 依赖 etcd 存子网,大规模集群有瓶颈 | 现代版本已改用 K8s API,但仍有性能上限 |
银行选型建议:
- 测试/开发/边缘节点:Flannel VXLAN 足够,简单稳定。
- 生产核心系统 :建议迁移至 Cilium(eBPF) 或 Calico BGP,前者提供 L7 可观测与策略,后者对接金融专网 BGP 更平滑。Flannel 可作为过渡或轻量分支行场景保留。