k8s网络原理

K8S中,
node节点的网络 本来就是互通的(比如都是10.x.x.x网段)
而pod的ip是虚拟出来的,比如node1上的pod的网段都是192.168.1.x,node2上的pod的网段都是192.168.2.x

那么,node1中的pod1(192.168.1.1)和node2中的pod2(192.168.2.2)是如何通讯的?

以Flannel网络为例,其实就是Flannel在node1中创建了flannel.1这个vxlan类型的虚拟网卡。

同时在node1的路由表中增加了一条记录,记录的内容为(发往192.168.2.x网段的报文,都走flannel.1,发给192.168.2.0这个网关)

这样报文就被转发到flannel.1网卡上,又因为这个网卡的类型是vxlan,linux内核就会给报文套一层vxlan的二层壳。

问题是 linux内容如何知道vxlan的目标IP呢?这就就涉及到vxlan的FBD表了。

首先内核通过arp表,可以查到网关192.168.2.0的MAC地址。

然后在FBD表中,根据MAC地址查找到vxlan隧道目标IP地址(比如10.2.2.3),这样就可以用vxlan报文把pod报文封装起来了。

下面贴一下通义千问给出的回答

问题1、创建vxlan接口flannel.1后,当pod1向pod2发报文时,linux如何知道pod2所在node的IP地址?

通义千问:

这是一个关于 Kubernetes 网络中 Flannel VXLAN 模式如何工作的核心问题。关键在于 FDB(Forwarding Database,转发数据库)表ARP 表 的配合。

当创建 flannel.1 VXLAN 接口后,Linux 内核本身并不直接知道 Pod2 所在 Node 的 IP 地址。这个信息是由 Flannel Daemon (flanneld) 维护并动态注入到内核网络栈中的。

以下是详细过程:


1. Flannel 的控制平面:维护网络状态

Flannel 的核心组件 flanneld 运行在每个节点上,它从 Kubernetes API Server 或 etcd 中读取集群的网络配置和所有节点的子网分配信息。例如:

  • Node A: 10.244.1.0/24
  • Node B: 10.244.2.0/24
  • Node C: 10.244.3.0/24

flanneld 知道哪个 Pod CIDR 段属于哪个物理节点(Node IP)。


2. 数据平面:内核如何转发

当 Pod1 (假设 IP 为 10.244.1.10, 在 Node A) 向 Pod2 (假设 IP 为 10.244.2.20, 在 Node B) 发送数据包时,流程如下:

a. 路由查找 (Routing)

Pod1 发出的数据包目标是 10.244.2.20

Node A 上的路由表会有一条由 Flannel 创建的规则,类似于:

bash 复制代码
$ ip route
...
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink

这条路由的意思是:"所有发往 10.244.2.0/24 网段的流量,都交给 flannel.1 这个接口处理"。注意这里的 via 10.244.2.0 并不是一个真实的下一跳 IP,而是一个特殊的、用于触发 FDB 查找的指示器

b. ARP 查找 (Address Resolution Protocol)

内核需要知道 10.244.2.0 这个"下一跳"的 MAC 地址才能在二层发送帧。

于是内核查询 flannel.1 接口关联的 ARP 表

bash 复制代码
$ ip neigh show dev flannel.1
10.244.2.0 lladdr ba:7c:8c:ea:bf:be PERMANENT

这里的关键点是:Flannel 预先在这个 ARP 表里添加了一条静态条目 。它将目标子网的"网关"IP (10.244.2.0) 映射到一个虚构的、但唯一的 MAC 地址 (ba:7c:8c:ea:bf:be)。这个 MAC 地址是由 Flannel 根据目标节点的 VTEP IP 计算出来的(通常是取 VTEP IP 的后几个字节)。

c. FDB 查找 (Forwarding Database)

现在内核知道了"下一跳"的 MAC 地址是 ba:7c:8c:ea:bf:be,它需要知道把这个二层帧从 flannel.1 接口发往哪个物理主机(Underlay IP)

这时,内核查询 flannel.1 接口的 FDB 表

bash 复制代码
$ bridge fdb show dev flannel.1
ba:7c:8c:ea:bf:be dst 192.168.1.102 self permanent

这就是答案的核心!

FDB 表明确告诉内核:"MAC 地址为 ba:7c:8c:ea:bf:be 的设备,位于物理 IP 地址 192.168.1.102 (即 Node B 的 Underlay IP) 上"。

d. VXLAN 封装与发送

内核获取到目标 VTEP IP (192.168.1.102) 后,就可以进行 VXLAN 封装:

  1. 将原始的 Pod-to-Pod 数据包(源IP 10.244.1.10, 目标IP 10.244.2.20)作为内层载荷
  2. 添加 VXLAN 头部(包含 VNI, 例如 1)。
  3. 添加外层 UDP/IP 头部(源IP 是 Node A 的物理IP 192.168.1.101, 目标IP 是 Node B 的物理IP 192.168.1.102, 目标端口 8472)。
  4. 通过宿主机的物理网卡(如 eth0)将封装后的报文发送给 Node B。

总结:谁负责告诉 Linux 内核?

Flannel Daemon (flanneld)

在启动时或检测到网络变化时,flanneld 会执行以下操作:

  1. 读取集群网络状态,获知 <Pod Subnet> <-> <Node IP> 的映射关系。
  2. 为每个远程子网,在本地节点的 flannel.1 接口上动态添加或更新两条关键记录
    • ARP 表条目: 将子网"网关"IP 映射到一个计算出的唯一 MAC 地址。
    • FDB 表条目: 将该 MAC 地址映射到对应 Node 的物理 IP (VTEP IP)。

因此,Linux 内核是通过查询由 Flannel 预先配置好的 FDB 表 来得知 "某个 Pod 子网对应的远端 Node 的物理 IP 地址" 的。这是一个典型的控制平面(Flannel)与数据平面(Linux Kernel)分离的设计。

问题2、关于FDB表的历史详细讲一下,这个表是linux vxlan本身的机制吧

通义千问:

非常好的问题!你触及到了 Linux 网络虚拟化底层的核心机制。

是的,FDB(Forwarding Database)表是 Linux VXLAN 本身内核实现的一部分,并非 Flannel 发明的。

Flannel 只是"利用"了这个现成的、标准的内核机制来实现其网络功能。


🧬 一、FDB 表的本质:二层转发的"电话簿"

FDB 全称 Forwarding Database ,中文叫"转发数据库"。它本质上是一个 MAC 地址 → 出口/下一跳位置 的映射表。

在传统物理交换机中,FDB 表用于记录哪个 MAC 地址连接在哪个端口上,从而决定数据帧从哪个端口转发出去。

在 Linux Bridge 和 VXLAN 中,这个概念被继承并扩展:

  • Linux Bridge 中:bridge fdb show 显示的是哪个 MAC 地址在哪个物理/虚拟端口(如 eth0, vethXXX)上。
  • VXLAN 中:由于 VXLAN 是 Overlay 网络,"端口"的概念变成了"远端 VTEP IP",所以 FDB 表就变成了: "某个 MAC 地址的数据,应该封装后发往哪个 Underlay IP(即远端 VTEP)"

📜 二、FDB 表的历史演进与标准化

1. 起源:传统以太网交换机

FDB 概念最早源于 IEEE 802.1D 标准定义的透明网桥(Transparent Bridge),用于学习和转发 MAC 帧。这是所有现代交换机的基础。

2. Linux Bridge 引入 FDB(约 2000 年代初)

Linux 内核在实现软件交换机(bridge 模块)时,完全遵循了这一标准,引入了 FDB 表用于本地 MAC 学习。命令 bridge fdb show 最初就是为 Linux Bridge 设计的。

3. VXLAN 加入内核(Linux 3.7+,2012年底)

VXLAN(Virtual eXtensible Local Area Network)作为一种 Overlay 网络隧道技术,由 VMware、Cisco 等公司在 2011-2012 年提出,目的是解决 VLAN 数量限制和跨三层网络的大二层扩展。

Linux 社区在 2012 年 12 月发布的 3.7 内核版本 中正式加入了原生 VXLAN 支持(由 Stephen Hemminger 等人主导开发)。

🔗 相关提交:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=64244a35b3a9

在这个实现中,为了支持分布式 VXLAN 隧道端点(VTEP)之间的通信,复用并扩展了已有的 FDB 机制

  • 当 VXLAN 接口收到一个数据帧时,它需要知道目标 MAC 对应的远端 VTEP IP。
  • 当发送一个数据帧到某个 MAC 时,也需要知道该封装到哪个 UDP 目标 IP。
  • 这个映射关系自然就放在 FDB 表里 ------ 因为这本质上就是一个"二层地址到转发位置"的映射!

于是,在 VXLAN 接口中,FDB 条目格式变为:

复制代码
<MAC地址> dst <远端VTEP IP> self permanent

例如:

bash 复制代码
ba:7c:8c:ea:bf:be dst 192.168.1.102 self permanent

这里的 dst 字段是 VXLAN 扩展的关键,表示"这个 MAC 应该通过 VXLAN 隧道发往这个 IP"。


⚙️ 三、FDB 在 VXLAN 中的工作模式

Linux VXLAN 支持两种 FDB 学习/填充方式:

1. 多播模式(Multicast Mode - 较少使用)

  • 所有 VTEP 加入同一个多播组(如 239.1.1.1)。
  • 未知目的 MAC 的帧会通过多播发送。
  • 收到回复后,内核自动学习并添加动态 FDB 条目(类似传统交换机 MAC 学习)。
  • 缺点:依赖多播网络,公有云通常不支持。

2. 单播模式 / "Head-end Replication"(主流,Flannel 使用的方式)

  • 不使用多播。
  • 必须预先配置静态 FDB 条目,告诉内核每个远程 MAC 对应哪个 VTEP IP。
  • 这就是为什么 Flannel、Calico、Cilium 等 CNI 插件都需要一个"控制平面"组件 ------ 它们负责监听节点变化,并调用 bridge fdb add ... 命令写入这些静态条目。
  • 条目通常是 permanent(永久)的,不会老化或被覆盖。

🛠 四、谁在管理 FDB?内核 vs 用户空间

组件 角色
Linux Kernel 提供 VXLAN 接口实现,维护 FDB 表结构,根据 FDB 执行封装/解封装逻辑。
用户空间程序(如 flanneld, calico, BGP Speaker) 负责动态计算并调用 netlink API 向内核注入/更新 FDB 条目。

Flannel 通过调用类似下面的命令来设置 FDB:

bash 复制代码
bridge fdb add $MAC_ADDRESS dev flannel.1 dst $NODE_IP self permanent

📈 五、FDB 表的重要性与性能

  • 查找效率高:FDB 表在内核中通常使用哈希表实现,O(1) 时间复杂度,适合高速转发。
  • 可编程性强:用户空间控制器可以精确控制转发路径,实现策略路由、安全隔离等。
  • 状态集中管理:避免了广播风暴,更适合大规模数据中心和 Kubernetes 集群。

✅ 总结

FDB 表不是 Flannel 的发明,而是 Linux 内核 VXLAN 实现的标准组成部分。它是 VXLAN 数据平面转发决策的核心依据。

Flannel、Calico、Cilium 等 CNI 插件只是作为"控制平面",负责动态地、智能地向这个内核表中填充正确的 <MAC> <-> <VTEP IP> 映射关系。

可以说:

没有 FDB 表,VXLAN 就不知道把包发给谁;没有 Flannel,FDB 表就不知道该填什么内容。

二者配合,才实现了 Pod 跨节点通信的魔法 🎩✨


如果你想深入源码,可以查看:

  • Linux 内核源码:drivers/net/vxlan.c
  • iproute2 工具源码:ip/iplink_vxlan.c, bridge/fdb.c

这是 Linux 网络虚拟化最精彩的设计之一。

相关推荐
wangjialelele4 小时前
Linux匿名管道和命名管道以及共享内存
linux·运维·网络
qinyia4 小时前
解锁服务器网络配置新姿势:Wisdom SSH 助力之旅
服务器·网络·ssh
我登哥MVP5 小时前
Java 网络编程学习笔记
java·网络·学习
名誉寒冰5 小时前
TCP, 三次握手, 四次挥手, 滑动窗口, 快速重传, 拥塞控制, 半连接队列, RST, SYN, ACK
网络·tcp/ip·php
塵觴葉5 小时前
Linux内核网络的连接跟踪conntrack简单分析
linux·网络·conntrack
嘿嘿-g6 小时前
华为IP(9)
网络·华为
半桔6 小时前
【Linux手册】管道通信:从内核底层原理到使用方法
java·linux·服务器·网络·c++
Darenm1117 小时前
计算机⽹络及TCP⽹络应⽤程序开发
网络·网络协议·tcp/ip
qq_3863226912 小时前
华为网路设备学习-32(BGP协议 七)路由反射器与联邦
网络·学习