最硬核k8s网络插件详解(flannel)

1、介绍

Flannel 是一个轻量级、易于配置的网络插件,旨在简化 Kubernetes 集群中 Pod 网络的管理。Flannel 的核心功能是提供一个虚拟的网络,允许每个 Pod 获取一个独立的 IP 地址,并实现不同节点间的 Pod 之间的通信

2、原理

2.1 基本概念

CNI (Container Network Interface): CNI 是一种标准接口,允许不同的网络插件与容器运行时进行交互。Flannel 就是一个实现了 CNI 规范的网络插件。

Backend: Flannel 支持多种后端实现方式,包括 VXLAN、host-gw(直接路由)、UDP 等等

2.2 原理

Flannel 首先从给定的更大地址池中为集群中的每个节点分配一个小的子网。然后,它会负责维护这些子网和对应节点之间的映射关系。当数据包需要从一个节点传输到另一个节点时,Flannel 根据其配置的 backend 来决定如何转发这些数据包。

2.3 flannel CNI工作流程

总结flannel-cni的工作流程如下:

  1. Pod创建与网络命名空间准备:当Kubernetes的kubelet创建一个Pod时,首先会创建一个pause容器,并使用该容器的网络命名空间作为参数(例如通过/var/run/docker/netns/xxxx获取)。这个命名空间将被用于后续CNI插件的调用。

  2. CNI配置文件:在/etc/cni/net.d/目录下存在名为10-flannel.conflist的配置文件,该文件由kube-flannel组件启动时生成。它定义了CNI插件链,首先是flannel类型,其次是portmap,用于支持端口映射功能。

  3. Flannel插件执行:根据配置,kubelet调用/opt/cni/bin/flannel执行。Flannel首先读取/run/flannel/subnet.env文件以获取当前节点的子网信息(如网络范围、MTU等),这些信息也是由kube-flannel在启动时写入的。

  4. 动态配置生成:基于从subnet.env中读取的信息,Flannel生成符合CNI标准的配置文件,其中包含了bridge类型的网络配置以及host-local IP地址管理器的设置。

  5. Bridge插件调用:接着,Flannel按照上述配置调用/opt/cni/bin/bridge插件。此过程涉及:

    • 创建Linux bridge cni0并绑定子网的第一个IP地址作为默认网关。
    • 在主机上添加路由规则,确保节点到本节点所有Pod的流量都通过cni0
    • 为新Pod创建veth对,并将其一端连接到Pod的网络命名空间,另一端连接到cni0
    • 为Pod内的veth接口分配IP地址,并设置默认网关。
  6. 跨节点通信:尽管flannel-cni主要负责同一节点上的Pod间通信,跨节点的Pod通信则由kube-flannel组件处理,包括设置适当的MTU值和选择合适的跨节点通信方案(如vxlan或host-gw)。

  7. IP地址管理host-local插件负责管理IP地址的分配情况,通过在本地文件系统中记录已分配的IP及其对应的容器ID来避免IP冲突。这通常发生在/var/lib/cni/network/host-local/目录下。

这样,通过一系列的步骤和组件协作,flannel-cni成功地为每个Pod设置了网络环境,实现了在同一节点上的Pod间通信。

3、网络模式

  • vxlan(默认):基于 VXLAN(Virtual Extensible LAN)隧道协议,通过隧道将不同主机上的 Pod 网络连接起来。适合大部分场景,特别是在跨节点的环境下。

  • host-gw:这种模式依赖于主机间的路由表,而不需要额外的隧道。它适合于节点之间有直通路由的环境,例如同一数据中心内的节点。

特性vxlan(默认)host-gw
原理基于 VXLAN 隧道协议,将 Pod 流量封装在 VXLAN 数据包内,跨节点传输数据利用节点的路由表,通过主机间的直接路由进行通信
优点1、支持跨数据中心部署。 2、 网络封装灵活1、性能高,无需额外开销 2、维护简单
缺点1、性能开销较大,特别是对于大规模集群 2、配置和故障排查较复杂不适用于复杂网络环境或跨数据中心部署
适用场景跨数据中心或不同网络环境的集群,适用于没有直接路由的网络。节点间网络有直接路由的环境(例如同一数据中心内)

3、原理详细

3.1 vxlan

同节点pod之间通讯

假设有两个 Pod(Pod A 和 Pod B)运行在同一节点上,IP 分别为 10.244.1.2 和 10.244.1.3,子网由 Flannel 分配为 10.244.1.0/24。

  • Pod A 发起通信:
    Pod A 需要向 Pod B 发送数据包(目标 IP 为 10.244.1.3)。
    数据包从 Pod A 的虚拟网络接口(veth pair)发出,进入其网络命名空间。
  • 进入宿主机网络:
    Pod A 的 veth pair 的一端连接到宿主机的网桥(通常是 Flannel 创建的 cni0 网桥)。
    数据包通过 veth pair 传递到 cni0 网桥。
  • 网桥转发:
    cni0 网桥是一个二层设备,会根据目标 MAC 地址进行转发。
    因为 Pod B 的 IP(10.244.1.3)也在同一子网内,网桥通过 ARP 解析获取 Pod B 的 MAC 地址。
    网桥发现 Pod B 的 veth pair 也连接到自己,因此直接将数据包转发到 Pod B 的 veth pair。
  • Pod B 接收数据:
    数据包通过 Pod B 的 veth pair 进入其网络命名空间。
    Pod B 的网络栈处理数据包,最终到达目标应用程序。
跨节点pod之间通讯

在这里插入图片描述
发送端:pod A的数据包会通过虚拟网卡转发到(cni0)容器虚拟网桥上,然后交由 flannel.1 设备处理,进行VXLAN封包解包,然后从 eth0 发送。

接收端:Node2收到报文后,发现是一个VXLAN类型报文,交由 flannel.1 进行解包。根据解包后得到的原始报文中的目的IP,将原始报文经由 cni0 网桥发送给目标Pod。

3.2 host-gw

在这里插入图片描述

  • 发送端(Pod A,节点 1):
    1、Pod A(10.244.1.2)发出数据包到 Pod B(10.244.2.3),从 veth pair 送到节点 1 的 cni0 网桥。
    2、cni0 查路由表,发现目标是 10.244.2.0/24,转给 flannel.1。
    3、flannel.1 把数据包封装成 VXLAN(外层 IP: 192.168.1.10 → 192.168.1.11),通过 eth0 发送到节点 2。
  • 接收端(Pod B,节点 2):
    1、节点 2 的 eth0 收到 VXLAN 数据包,转给 flannel.1。
    2、flannel.1 解封装,恢复原始数据包(10.244.1.2 → 10.244.2.3)。
    3、数据包送到 cni0 网桥,用 ARP 找到 Pod B 的 MAC,转给 Pod B 的 veth pair。
    4、Pod B 收到数据,交给应用处理
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值