在K8S中,flannel的作用?

Flannel 是 Kubernetes 中最经典、最广泛使用的 CNI(Container Network Interface)网络插件之一。它的核心作用是为 Kubernetes 集群提供一个简单、可靠的 Overlay 网络(覆盖网络),确保集群中所有 Pod 能够跨节点相互通信,无论这些 Pod 被调度到哪个节点上。这是 Kubernetes 网络模型的基本要求之一。

以下是 Flannel 的主要作用、工作原理和关键特性:

核心作用

  1. 提供 Pod 跨节点网络互通:

    • 这是 Flannel 最根本的任务。它确保:
      • 每个 Pod 获得一个唯一的、集群范围内有效的 IP 地址。
      • 一个节点上的 Pod 可以直接通过 IP 地址访问另一个节点上的 Pod,无需进行 NAT(网络地址转换)。
    • 解决了 Kubernetes 集群节点间 Pod 通信的基础需求。
  2. 实现 Kubernetes 网络模型:

    • Kubernetes 要求:
      • 所有 Pod 都可以在不使用 NAT 的情况下与其他所有 Pod 通信。
      • 所有节点都可以在不使用 NAT 的情况下与所有 Pod 通信。
      • Pod 自身看到的 IP 地址就是其他 Pod/节点看到的 IP 地址(IP-per-Pod)。
    • Flannel 的设计目标就是满足这些要求。

工作原理 (以最常用的 VXLAN 后端为例)

  1. 网络规划:

    • Flannel 会从管理员配置的一个大的 CIDR 地址块(例如 10.244.0.0/16)中,为每个 Kubernetes 节点分配一个独立的、互不重叠的子网(例如 10.244.1.0/24 给 Node1, 10.244.2.0/24 给 Node2)。
    • 每个节点上的 Pod 的 IP 地址都从这个节点的子网中分配。例如,Node1 上的 Pod 地址可能是 10.244.1.2, 10.244.1.3 等。
  2. 本地网络 (节点内 Pod 通信):

    • 当一个 Pod 被创建时,Flannel 的 CNI 插件(通常与 containerdCRI-O 集成)会:
      • 在节点上创建一个 Linux 网桥(通常叫 cni0)。
      • 为 Pod 创建一对 veth pair:一端放在 Pod 的网络命名空间内(命名为 eth0),另一端连接到 cni0 网桥上。
      • 从分配给该节点的子网中为 Pod 的 eth0 分配一个 IP 地址,并设置 Pod 内的路由规则(默认网关指向 cni0 的 IP)。
    • 同一个节点上的 Pod 通信:数据包通过 eth0 -> veth pair -> cni0 网桥 -> 目标 Pod 的 veth pair -> 目标 Pod 的 eth0。这个过程在二层完成,不经过内核路由栈。
  3. 跨节点网络通信 (关键):

    • 当一个节点(Node1)上的 Pod(Pod A: 10.244.1.2)需要访问另一个节点(Node2)上的 Pod(Pod B: 10.244.2.3)时:
      1. 源节点 (Node1):
        • Pod A 发出目标地址为 10.244.2.3 的数据包。
        • 数据包到达 cni0 网桥。
        • Node1 的内核路由表知道目标地址 10.244.2.3 属于子网 10.244.2.0/24,而这个子网属于 Node2。
        • Flannel 守护进程 flanneld 会在每个节点上创建一个特殊的网络接口,通常是 flannel.1 (VXLAN 接口)
        • 路由表指示:去往 10.244.2.0/24 的数据包,下一跳是 flannel.1 接口(或更具体地说,需要通过 VXLAN 隧道发送到 Node2)。
      2. 封装 (VXLAN):
        • 内核的 VXLAN 模块将原始的 Pod-to-Pod 数据包(内层包:源 IP=10.244.1.2, 目标 IP=10.244.2.3封装在一个新的 UDP 数据包中(外层包)。
        • 外层 UDP 头: 源端口是动态的,目标端口是标准的 VXLAN 端口(通常是 8472)。
        • 外层 IP 头: 源 IP = Node1 的 IP 地址,目标 IP = Node2 的 IP 地址
        • VXLAN 头: 包含一个 VNI(VXLAN Network Identifier),用于标识不同的覆盖网络(Flannel 默认使用 VNI=1)。
      3. 传输:
        • 这个封装后的 UDP 数据包通过 Node1 的物理网络接口发送出去。
        • 底层网络(交换机、路由器)只看到 Node1 到 Node2 的普通 IP/UDP 流量,并根据它们的 IP 地址进行路由,将数据包送达 Node2。
      4. 解封装 (Node2):
        • Node2 的物理接口收到 UDP 数据包,发现目标端口是 8472(VXLAN),于是将其交给内核的 VXLAN 模块处理。
        • VXLAN 模块解封装数据包,剥离外层 UDP/IP 头,露出原始的 Pod-to-Pod 数据包(内层包:源 IP=10.244.1.2, 目标 IP=10.244.2.3)。
      5. 目标节点 (Node2) 内部转发:
        • 解封装后的原始数据包被送到 Node2 的 flannel.1 接口。
        • Node2 的内核路由表查询目标地址 10.244.2.3,发现它属于本机的 cni0 网桥管理的子网。
        • 数据包被转发到 cni0 网桥。
        • cni0 网桥根据 MAC 地址表将数据包转发到连接目标 Pod B 的 veth 接口。
        • 数据包最终到达 Pod B 的 eth0

关键特性与后端

  1. 多种后端 (Backend): Flannel 支持不同的封装/传输技术来实现跨节点通信,性能、复杂性和依赖不同:

    • vxlan (默认且最常用): 如上述原理所示。提供良好的兼容性,能穿越大多数网络。有封装开销(~50字节)。
    • host-gw (Host Gateway):
      • 性能最好(接近裸金属网络),无封装开销。
      • 原理:在路由表中为每个其他节点的 Pod 子网添加一条路由规则,指明下一跳就是目标节点的 IP 地址10.244.2.0/24 via <Node2_IP> dev eth0)。
      • 要求:节点间必须在同一个二层网络(L2 可达)。如果节点间需要经过路由器,路由器必须配置静态路由指向节点子网(不现实)。适合云环境或扁平数据中心。
    • udp (已弃用): 最早的、纯用户空间实现的后端。性能差,仅用于没有内核 VXLAN 支持的旧系统。强烈不建议使用
    • ipsec, wireguard 提供传输层加密,增强安全性。会引入额外的性能开销。
    • ali-vpc, gce, aws-vpc 利用云提供商特定的路由功能(如 AWS VPC 路由表、GCE 路由、阿里云 VPC 路由),通常类似 host-gw 但由云平台自动管理路由。性能好,依赖云平台。
    • alloc / ipvlan / portmap 主要用于特定场景(如 IPv6、多网络接口、端口映射)。
  2. 简单轻量:

    • 架构简单:一个在每个节点上运行的 DaemonSet (kube-flannel-ds)。
    • 配置简单:通常只需要一个 ConfigMap (kube-flannel-cfg) 定义网络 CIDR 和后端。
    • 资源消耗低。
  3. 成熟稳定: 作为最早的 CNI 插件之一,经过长期生产环境验证,非常稳定。

  4. 专注于连通性:

    • Flannel 不提供高级的网络策略功能(如防火墙规则、Pod 间 ACL)。它专注于解决最基础的 Pod 跨节点通信问题。
    • 如果需要网络策略,通常需要额外安装一个网络策略提供者(如 Calico 的 kube-controllerscalico/node 仅用于策略,或者 Cilium、Weave Net 等自带策略的插件)。

总结

Flannel 在 Kubernetes 中的核心作用是:为整个集群构建一个统一的 Overlay 虚拟网络,确保所有 Pod 无论部署在哪个节点上,都能通过唯一的 IP 地址直接相互通信。它通过简单的架构(通常是 VXLAN 封装)实现了 Kubernetes 网络模型的基本要求。

  • 优点: 简单易部署、轻量、成熟稳定、社区支持好。
  • 缺点: 默认 VXLAN 有封装开销(host-gw 性能好但有网络拓扑限制)、不提供内置网络策略功能。
  • 适用场景: 需要快速搭建基础网络的中小型集群、测试开发环境、对高级网络功能要求不高的场景。当需要高性能(且满足 host-gw 要求)或需要网络策略时,可能需要考虑其他方案或与策略组件结合。
posted @ 2025-08-16 20:00  天道酬勤zjh  阅读(10)  评论(0)    收藏  举报