1. 为什么需要Flannel?从Docker网络瓶颈说起

想象一下,你正在管理一个Kubernetes集群,节点分布在不同的服务器上。当Pod-A(10.244.1.2)尝试与Pod-B(10.244.2.3)通信时,却发现网络不通——因为Docker默认的桥接模式只能在单机内工作。此时,你需要一套跨主机的容器网络方案,而Flannel正是为解决此问题而生。

Flannel通过创建Overlay网络(叠加网络),将分布在不同物理机上的容器连接在同一个虚拟网络内。比如,节点1的Pod使用10.244.1.0/24子网,节点2的Pod使用10.244.2.0/24子网,Flannel负责在这些子网之间打通路由。


2. 实战:用kubeadm快速安装Flannel

(技术栈:Kubernetes v1.24 + Flannel v0.19)

以下示例基于Ubuntu 22.04 LTS,假设已通过kubeadm初始化集群(未安装网络插件):

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

# 查看Pod状态(所有节点应出现flannel-*前缀的Pod)
kubectl get pods -n kube-system -l app=flannel

# 预期输出示例(3节点集群):
# NAME                    READY   STATUS    RESTARTS
# flannel-abc12           1/1     Running   0
# flannel-xyz34           1/1     Running   0
# flannel-def56           1/1     Running   0

# 检查节点网络信息(每个节点的Pod CIDR应不同)
kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}'
# 10.244.0.0/24 10.244.1.0/24 10.244.2.0/24

注释说明
Flannel默认通过kube-subnet-mgr组件从Kubernetes API获取Pod子网分配,无需手动配置。安装完成后,集群内所有Pod已具备跨节点通信能力。


3. Overlay网络原理拆解:像快递员一样的Flannel数据包

3.1 VXLAN:藏在IP包里的"套娃"转发

当Pod-A(10.244.1.2)向Pod-B(10.244.2.3)发送数据时,Flannel通过以下步骤完成传输:

  1. 封装:在原始数据包外包裹一层VXLAN头+外层UDP头,目标地址为宿主机Node2的IP。
  2. 传输:经过底层网络将封装后的包送达Node2。
  3. 解封装:Node2的flanneld进程移除外层头,将原始数据包递交给Pod-B。
# 在Node1上执行tcpdump抓包示例(需root权限)
tcpdump -i flannel.1 -nn -v

# 发送ICMP请求测试(从Pod-A到Pod-B)
kubectl exec pod-a -- ping -c 1 10.244.2.3

# 输出结果片段:
# 22:30:15.123456 IP 10.244.1.2 > 10.244.2.3: ICMP echo request
# 22:30:15.123789 IP 192.168.0.1.48752 > 192.168.0.2.8472: VXLAN, flags [I], vni 1

注释说明
flannel.1是VXLAN虚拟接口,vni 1标识租户网络。8472是VXLAN标准端口,确保跨不同厂商设备兼容。

3.2 路由表与ARP缓存(关键运维技巧)

Flannel通过维护路由表和ARP缓存实现快速转发:

# 查看Node1的路由规则
ip route show dev flannel.1

# 示例输出:
# 10.244.2.0/24 via 10.244.2.0 
# 10.244.3.0/24 via 10.244.3.0 

# 检查ARP缓存(记录其他节点的VXLAN隧道端点)
ip neigh show dev flannel.1

# 输出示例:
# 10.244.2.0 lladdr 36:ef:2b:... PERMANENT

4. 进阶:Flannel后端的选型与比较

Flannel支持多种后端,可通过修改kube-flannel.ymlnet-conf.json切换:

# VXLAN模式(默认跨平台)
net-conf.json: |
  {
    "Network": "10.244.0.0/16",
    "Backend": {
      "Type": "vxlan"
    }
  }

# Host-GW模式(需二层互通,性能更高)
  "Backend": {
    "Type": "host-gw"
  }

# UDP模式(仅建议测试使用)
  "Backend": {
    "Type": "udp"
  }

性能对比表

后端类型 延迟 吞吐量 适用场景
host-gw 最低 最高 同机房二层网络
vxlan 中等 跨机房/云环境
udp 最高 仅用于测试

5. 应用场景分析

5.1 理想使用场景
  • 混合云部署:AWS与本地IDC的Pod互通
  • 开发测试环境:快速搭建多节点集群
  • 中小规模生产:业务Pod数量低于5000
5.2 不适用场景
  • 高性能计算:高频IO场景推荐Calico+BPF
  • 多租户隔离:需配合NetworkPolicy实现
  • 超大规模集群:超过100节点需定制优化

6. Flannel的优缺点与注意事项

6.1 优势亮点
  • 部署简单:单YAML文件搞定
  • 资源消耗低:每个节点约50MB内存
  • 跨平台兼容:支持物理机、VM、主流云厂商
6.2 已知缺陷
  • 网络策略缺失:需额外安装Calico或Cilium
  • MTU问题:VXLAN封装可能导致PMTUD问题
  • IPAM限制:不支持动态IP分配策略调整
6.3 避坑指南
  1. 内核版本:确保Linux内核≥3.7(推荐≥4.4)
  2. 防火墙规则:开放VXLAN端口8472/UDP
  3. 子网预留:避免与物理网络192.168.0.0/16冲突
  4. 升级策略:先升级Master节点,再逐个Worker滚动

7. 总结:什么情况下应该选择Flannel?

如果你需要一款开箱即用维护简单的CNI插件,特别是在混合云或对网络性能要求不极致的场景下,Flannel仍然是优秀的选择。但当集群规模超过100节点或需要细粒度网络控制时,建议考虑Calico/Cilium等进阶方案。