[K8S小白问题集] - Flannel是K8S默认CNI吗?怎么实现的Overlay网络?

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 启动时:

  1. 从 K8s API 读取或向 etcd 注册:Node1 -> 10.244.1.0/24,Node2 -> 10.244.2.0/24。
  2. 在节点上创建 flannel.1 设备(类型为 vxlan,VNI 默认为 1,UDP 目的端口 4789)。
  3. flannel.1 是 VTEP(VXLAN Tunnel End Point),拥有独立的 MAC 地址(如 f2:xx:xx:xx:xx:01)和 IP(如 10.244.1.0/32,子网网关地址)。
  4. 创建 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 的解封装过程:

  1. eth0 收到 UDP 4789 报文,内核 VXLAN 驱动识别 VNI=1 且目的 IP 匹配本机 VTEP IP,执行解封装。
  2. 取出内层以太网帧,目的 MAC 是 flannel.1 的 MAC,交给 flannel.1 设备。
  3. 内核查路由表:10.244.2.3 属于本地直连子网,通过 cni0 网桥转发。
  4. 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 可作为过渡或轻量分支行场景保留。
相关推荐
Harvy_没救了1 小时前
【虚拟容器-docker】docker核心“铁三角“--网络、存储、镜像管理
网络·docker·容器
BS_Li1 小时前
【Linux网络编程】应用层自定义协议与序列化
linux·服务器·网络
容器魔方1 小时前
云原生 Agent 托管的高效范式:Agent Harness Infra 体系化设计
云原生·容器·开源·云计算
SPC的存折1 小时前
12、Ingress-Nginx 全局超时配置及生效方式
运维·nginx·云原生·kubernetes
密瓜智能1 小时前
国产 GPU 如何丝滑融入 K8s?燧原科技的全栈云原生实践
云原生·kubernetes·ai算力
深邃-1 小时前
【Web安全】-计算机网络协议(2):请求方法,头部字段,DNS协议详解
linux·网络·网络协议·计算机网络·安全·web安全·网络安全
Mr.H01271 小时前
C语言MQTT学习系列(3篇):第一篇:从零开始学MQTT(C语言版):入门必看,跑通最简Demo
c语言·网络·学习
DandelionR1 小时前
DolphinScheduler 3.4.1 Docker 部署安装 Skill
运维·docker·容器
上海云盾-小余10 小时前
域名解析被劫持怎么办?DNS 安全防护与异常修复全教程
网络·安全·ddos