裸Linux手工搭建VxLAN:MTU、FDB与多租户隔离

发布时间:2026/10/26 5:23:09
裸Linux手工搭建VxLAN:MTU、FDB与多租户隔离 同一个机房里两台机器要二层互通中间隔了台三层设备业务又改不动地址这种场景我在几个项目里都遇到过。最早的解决办法是把线拉过去后来是打 VLAN 标签跨设备透传再后来机架一多、租户一多4094 个标签根本不够分跨机房更是不可能。这时候多数人会想到 VxLAN但一搜资料全是某某控制器一键下发某某编排平台自动组网仿佛不装一套管理平面就没法做事。实际上Linux 内核从 3.7 起就自带 VxLAN 支持iproute2一条ip link add type vxlan就能把隧道立起来三台机器以内、拓扑相对稳定的场景纯手工配置完全够用而且能把底层发生了什么看得一清二楚。这篇就把我在裸 Linux 主机上手动搭 VxLAN 的全过程拆开讲封装原理、参数含义、MTU 怎么算、FDB 怎么填、多租户怎么隔离、踩过的坑怎么排。适合手里有几台机器、需要跨网段打通二层、又不想引入重型方案的人参考也适合想搞明白 VxLAN 到底干了什么的人从零复现。1. 先把 VxLAN 的账算明白它到底替你省掉了什么1.1 从 VLAN 的 4094 个标签说起二层隔离这件事传统做法是 VLAN。协议里 VID 字段 12 位除掉 0 和 4095 两个保留值理论上 4094 个可用标签。单机房单业务的时候绰绰有余问题出在两个方向一是多租户环境下每个租户要占几个 VLAN几百个租户就把池子吃干净了二是 VLAN 标签必须在整条路径的每一台交换设备上都配置中间任何一跳没放行包就断在那儿跨机房基本没法玩。VxLAN 的思路很直接既然二层标签不够用、又必须全网设备配合那就把整个二层帧当成货物打个包裹走三层网络送过去。VNI 是 24 位理论上 1600 万个隔离域而中间网络只需要支持普通 IP 路由转发不需要认识 VxLAN也不需要知道里面装的是什么。对中间设备来说这只是一堆源端口 4789 的 UDP 包。这个转变的意义在于隔离域的数量级和跨域能力同时被解锁。以前两个机房之间要做二层延伸得协调运营商拉专线、配透传现在只要两边主机三层可达隧道就通了。代价当然也有后面会算。1.2 VxLAN 封装长什么样50 字节的代价要理解后面所有的 MTU 问题先得把封装结构记在脑子里。一个内层以太帧从本机 vxlan 接口发出去经过网卡之前会被加上这么几层层次长度内容外层以太头14 字节源/目的 Underlay MAC外层 IP 头20 字节源/目的 Underlay IP无选项UDP 头8 字节源端口随机目的端口默认 4789VxLAN 头8 字节Flags VNI 保留字段内层以太帧变长原始二层帧含内层 MAC 和载荷加起来固定开销 50 字节。VxLAN 头本身的结构是 1 字节 Flags其中 I 位置 1 表示 VNI 有效值为 0x08、3 字节保留、4 字节的 VNI 字段——实际 VNI 只占 24 位剩下 8 位保留。也就是说 VNI 最大 16777215日常规划用几百几千完全够了。记住 50 这个数字第二章算 MTU 全靠它。另外注意外层 UDP 的源端口是按内层帧的哈希算出来的这是为了让中间网络能做 ECMP 负载均衡——同一条流始终落到同一条路径上避免乱序。这个设计细节在后面调性能的时候会提到。1.3 手动搭 vs 上控制器什么规模适合自己动手我不否认控制器方案的价值几百台节点、租户频繁增删的环境手工维护 FDB 表项会疯掉。但判断标准其实很清晰节点数在 10 台以内、拓扑变更不频繁手工配置完全可行写个脚本批量下发成本远低于搭一套管理平面。需要精细控制、出了问题要能一眼看到底层手工方式的排错链路是透明的ip -d link、bridge fdb show、tcpdump三板斧下去问题基本就定位了。节点数上百、FDB 需要动态学习或需要跨集群这时候手工维护静态表项开始变成负担多播模式又受限于底层网络是否放行组播该考虑自动化方案了。还有一类特殊场景适合手工临时打通、故障演练、验证某个网络行为。建一个 vxlan 接口只要一条命令删掉也只要一条比申请配置变更快得多。我自己在做跨机房故障复现的时候经常用这种方式在几台机器上快速搭出一个隔离环境。2. 动手前必须确认的四件事内核、MTU、Underlay 与地址规划2.1 内核支持与 iproute2 版本差异第一件事是确认内核带了 vxlan 模块。绝大多数发行版默认内核都编译了但要确认modprobe vxlan lsmod | grep vxlan如果没有输出说明模块没加载成功可能是内核裁剪过。检查CONFIG_VXLAN是否等于m或ygrep CONFIG_VXLAN /boot/config-$(uname -r)第二件事是iproute2的版本。这个坑我踩过不止一次不同版本的ip命令对 vxlan 参数写法要求不一样。老版本认nolearning新版本要用no learning或者干脆换成learning off写成前者会直接报Error: unknown command。我的做法是统一用最保守的写法创建接口时只用最基础的参数剩下的属性后续用bridge link set单独调整ip -V ip link add vxlan100 type vxlan id 100 dev eth0 dstport 4789 bridge link set dev vxlan100 learning off这样写兼容性好ip -V输出类似ip utility, iproute2-6.1.0这种版本信息5.x 以上基本都能跑。另外建议安装bridge命令所属的包通常和iproute2一起后面查 FDB 表全靠它。2.2 MTU 这笔账为什么 1450 是关键数字Underlay 网卡是标准 1500 的话内层可用 MTU 就是1500 - 50 1450所以 vxlan 接口的 MTU 要设成 1450接 vxlan 的网桥也要设成 1450挂在网桥上的业务接口同样得是 1450。如果业务侧还是 1500发出去的包在 vxlan 接口上会被分片或者直接丢弃取决于是否允许分片表现就是小包能通、大包死活不通。如果 Underlay 支持巨型帧比如 9000那内层可以用到 8950这时候就不用纠结了。但现实是很多环境里中间路径的 MTU 并不统一你以为链路是 9000中间某台设备只有 1500照样出问题。我一般保守按 1500 算除非确认整条路径都放行了巨型帧。配置方式ip link set dev vxlan100 mtu 1450 ip link set dev br100 mtu 1450这里有个细节值得说网桥的 MTU 取的是所有从属接口里的最小值但 vxlan 接口创建时默认 MTU 还是 1500所以顺序很重要——先把 vxlan 接口 MTU 改成 1450再挂进网桥否则网桥的 MTU 会被拉高。更稳妥的做法是每次都显式设置一遍不要依赖自动继承。2.3 Underlay 连通性与地址规划表上 vxlan 之前先确认两台机器的 Underlay 地址能直接 ping 通。VxLAN 隧道不负责底层连通性它只是把二层帧塞进 UDP 里UDP 走不通什么都没用。ping -c 3 192.168.1.2顺手确认一下 4789 端口没被占默认的 VxLAN 目的端口是 4789老的 IANA 分配是 8472某些方案还在用。如果机器上装了其他隧道组件可能已经占用了这个端口那就换个dstport两端必须一致。地址规划我习惯列个表尤其是节点超过两台的时候不写下来一定会乱主机Underlay IPVNIOverlay IPvxlan 接口名主机A192.168.1.110010.10.100.1/24vxlan100主机B192.168.1.210010.10.100.2/24vxlan100主机C192.168.1.310010.10.100.3/24vxlan100Overlay 网段和 Underlay 网段千万别重叠这是新手最常见的错误之一。如果 Underlay 是 10.0.0.0/8Overlay 就别用 10.x换成 172.16.x 或者 192.168.x 里的小段。重叠之后路由表会认错方向表现为明明配了地址就是不通而且极难排查。3. 两台主机点对点打通从建接口到 ping 通3.1 建 vxlan 接口的完整命令与参数逐个拆解先看最简形式的点对点配置。在主机A上ip link add vxlan100 type vxlan \ id 100 \ remote 192.168.1.2 \ local 192.168.1.1 \ dev eth0 \ dstport 4789 \ learning off每个参数都得说清楚因为漏一个就出问题id 100VNI 编号两端必须一致。不一致的话包能到对端但对端内核发现 VNI 不匹配会直接丢掉抓包能看到包进来但接口上什么都没有。remote 192.168.1.2对端的 Underlay 地址。点对点模式下所有出向包都发给这个地址。local 192.168.1.1本机的 Underlay 源地址。这个参数在多网卡机器上必须显式指定否则内核可能选错出接口和源地址导致对端回包回不来。dev eth0出接口。配合local一起确认路径。dstport 4789目的端口两端一致。learning off关闭自学习。手动模式下必须关否则内核会尝试自己学习对端 MAC反而产生不可控的表项。建好之后看一眼详情确认参数生效ip -d link show vxlan100输出里会带一行vxlan id 100 remote 192.168.1.2 local 192.168.1.1 dev eth0 srcport 0 0 dstport 4789 ...之类的内容重点核对 id、remote、local、dstport 四个值。这一步别省我遇到过参数被静默忽略的情况老版本对某些参数组合不生效只看命令没报错不算数。接着把接口拉起来ip link set dev vxlan100 up3.2 网桥怎么挂vxlan 口和业务口的关系只建 vxlan 接口是没用的它得和业务流量接上。有两种接法第一种直接把 Overlay IP 配在 vxlan 接口上。适合只需要主机间三层互通的场景配置最简单ip addr add 10.10.100.1/24 dev vxlan100第二种建一个网桥把 vxlan 接口和业务网卡都挂进去。适合需要二层延伸的场景——比如虚拟机、容器要认为自己在一个二层网络里或者业务侧要跑 ARP、DHCP 这类依赖广播的协议ip link add br100 type bridge ip link set dev br100 mtu 1450 ip link set dev vxlan100 master br100 ip link set dev eth1 master br100 ip link set dev br100 up这里eth1是业务侧的物理或虚拟网卡。注意挂了同一个网桥的接口之间会互相转发如果 eth1 又接到了一台干活儿的交换机很容易形成环路。所以业务侧的接口最好是独立的不要和主网卡混在一个网桥里。还有个容易被忽略的点vxlan 接口进网桥之前要把它的 MAC 固定下来。ip link set dev vxlan100 address 00:11:22:33:44:55默认情况下内核会给 vxlan 接口生成一个随机 MAC主机重启后会变。在点对点场景影响不大但在多节点场景里如果对端的静态 FDB 表项里写的是老 MAC重连就断了。固定 MAC 是省事的好习惯同主机多个 vxlan 接口要注意 MAC 不能重复。3.3 静态 FDB 表项的写法与验证learning off之后转发靠的是 FDB 表。需要给 vxlan 接口加一条泛洪表项告诉内核所有未知的单播、广播、多播帧都往这个目的地址送。bridge fdb append 00:00:00:00:00:00 dev vxlan100 dst 192.168.1.200:00:00:00:00:00这个全零 MAC 是约定俗成的未知目标占位符加了这个表项BUMBroadcast、Unknown unicast、Multicast流量就会发往192.168.1.2。如果想让某个具体 MAC 走指定隧道加具体表项bridge fdb append aa:bb:cc:dd:ee:01 dev vxlan100 dst 192.168.1.2查一下确认写入成功bridge fdb show dev vxlan100正常应该看到类似这样的输出00:00:00:00:00:00 dst 192.168.1.2 self permanent 00:11:22:33:44:55 dev vxlan100 self permanent第二行是本接口自己的 MAC自动加的。self表示这条表项属于这个设备permanent表示不会老化。注意bridge fdb append是追加操作重复执行不会去重有些版本会去重有些不会。写自动化脚本的时候用replace更稳妥bridge fdb replace在表项存在时会覆盖。主机B上做对称配置只是remote换成 192.168.1.1Overlay IP 换成 10.10.100.2。两边都建好之后ping 一下 Overlay 地址ping -c 3 10.10.100.23.4 三层验证法从 FDB 到 tcpdumpping 不通的时候不要瞎猜按层往下查效率最高。我总结了一个三层验证顺序第一层查 FDB 表。bridge fdb show dev vxlan100里有没有那条全零表项没有的话包根本发不出去。如果有但dst地址写错了也是白搭。第二层查 Underlay 抓包。在主机A的 eth0 上tcpdump -i eth0 -nn udp port 4789 -c 10如果一条都抓不到说明出向根本没走到物理网卡——可能是路由问题或者local/dev参数指错了接口。如果抓得到包但看不到回包问题在对端去主机B上抓。第三层查内层抓包。在 vxlan 接口上抓tcpdump -i vxlan100 -nn icmp这一层能看到的话说明解封装是成功的问题在接口之后的转发比如网桥、路由表。看不到就是封装/解封装阶段出了问题。这三层走一遍问题基本能锁死在某一环比漫无目的地改配置快得多。我一般还会加一个 ARP 表检查ip neigh show dev vxlan100如果 ARP 一直是INCOMPLETE状态说明广播包没送到对端直接回去查第一层的 FDB 表。4. 从两台到多台FDB 规模、多播组与多租户 VNI4.1 静态 FDB 的规模边界与批量写入三台以上的全互联拓扑需要给每台主机的 vxlan 接口加上到其他所有节点的表项。节点数为 N 时每台机器需要 N-1 条表项。五台机器就是每台四条手工敲还能忍二十台就是每台十九条人工维护开始变得痛苦五十台以上基本不可能靠手工跟上变更。批量写入用脚本很简单把节点列表存成一个文件#!/bin/bash # nodes.txt 每行一个 Underlay IP DEVvxlan100 while read -r ip; do [ -z $ip ] continue bridge fdb replace 00:00:00:00:00:00 dev $DEV dst $ip done nodes.txt用replace而不是append重复执行不会产生重复表项可以放心放进幂等脚本里。这里有个规模上的经验值单接口 FDB 表项在几百条以内性能没有明显变化因为内核用的是哈希表。真正的问题不是性能而是变更管理——增加一个节点要在所有存量节点上补一条删除节点要回收所有相关表项漏一个就会出现部分节点通、部分节点不通这种最难查的故障。所以我在节点数超过 10 台之后基本都会把这份配置写进一个中心的配置源由脚本统一渲染下发而不是手工改。4.2 多播组模式能省事但有两个硬限制VxLAN 标准里定义了多播模式不再逐条指定remote而是加入一个组播组BUM 流量由底层网络的多播转发给所有成员。ip link add vxlan100 type vxlan \ id 100 \ group 239.1.1.1 \ dev eth0 \ dstport 4789 \ learning off这样只写一条命令所有加入 239.1.1.1 组的主机自动能收到广播。听起来很美但实际有两个硬限制限制一Underlay 必须完整支持组播。包括主机所在的接入交换机、中间所有路由设备、目的主机的接入设备都要配置 PIM 之类的组播路由。很多环境出于安全或运维复杂度考虑默认是把组播关掉的一关就全断了。限制二组播是广播域的延伸规模一大就是灾难。一个组播组里的主机越多BUM 流量的复制份数越多每一份都要占用带宽。几十台以内还能接受上百台之后一个 ARP 请求就要复制上百份网络直接被自己的控制流量压垮。所以多播模式我只在小规模、且确认底层网络放行组播的场景下用。跨机房的基本别想公网更不可能。绝大多数实际部署还是走静态 FDB 或者由控制平面下发 FDB 的模式。另外补充一点还有一种external模式接口创建时指定external表示 FDB 完全由外部程序比如桥接插件管理内核不自动学习也不自动添加表项。这个模式适合有自研控制平面的场景纯手工用不上但看到别人配置里出现external时知道是什么意思就行。4.3 同主机多 VNI网桥、MAC 与命名规范一台主机上跑多个租户的时候需要多个 vxlan 接口每个对应一个 VNI。典型配置是这样# 租户一 ip link add vxlan100 type vxlan id 100 remote 192.168.1.2 local 192.168.1.1 dev eth0 dstport 4789 learning off ip link add br100 type bridge ip link set dev vxlan100 master br100 ip link set br100 up # 租户二 ip link add vxlan200 type vxlan id 200 remote 192.168.1.2 local 192.168.1.1 dev eth0 dstport 4789 learning off ip link add br200 type bridge ip link set dev vxlan200 master br200 ip link set br200 up关键点有几个网桥必须分开。同一个网桥里的接口属于同一个广播域把 vxlan100 和 vxlan200 挂进同一个网桥等于把两个 VNI 的流量在本地桥接了隔离直接失效。MAC 必须唯一。同主机上每个 vxlan 接口都要固定一个不同的 MAC而且不能和网桥里其他接口冲突。我习惯按 VNI 编号生成比如 VNI 100 对应00:11:22:00:01:00一眼能看出归属。命名要有规范。接口名vxlan{VNI}、网桥名br{VNI}这样ip link show一眼扫过去就知道有哪些租户在跑出问题定位也快。Linux 接口名最长 15 个字符vxlan16777215正好卡在边界上实际规划 VNI 的时候留点余量。还要提一个容易忽略的点多个 vxlan 接口共用同一个 Underlay 出口时源端口是各自独立算的所以不会互相干扰。但如果 Underlay 出口带宽有限多租户同时大流量传输会互相抢带宽这时候需要在 Underlay 上做 QoS而不是在 overlay 层想办法。5. 五个真实踩过的坑现象、排查链路与修复5.1 接口全 up、FDB 也有就是 ping 不通这是最让人抓狂的一类问题。所有状态看起来都对ip link显示state UNKNOWNvxlan 接口正常状态就是 UNKNOWN不是 UP这点要知道别误判FDB 表项在Underlay 能 ping 通就是 overlay 不通。排查链路我一般这么走第一步在对端抓 Underlay 的 UDP 包tcpdump -i eth0 -nn udp port 4789 -c 5如果对端收不到问题在本端出向。回到本端确认ip -d link show vxlan100里的local地址是不是真的属于dev指定的那块网卡ip addr show eth0这一步我遇到过两次都是机器有多块网卡local填了一个在另一块网卡上的地址结果包从错误的接口发出去对端收到后回包的路由对不上。第二步如果对端能收到包但不回检查 VNI 是否一致。VNI 不一致时内核会静默丢弃抓包能看到包进来但没有任何错误日志。ip -d link show两边的输出对一遍一分钟就能确认。第三步检查防火墙。很多发行版默认开着 firewalld 或 nftables4789/UDP 被挡住是很常见的。临时关掉验证一下iptables -L -n | grep 4789 nft list ruleset | grep 4789确认是防火墙问题的话加放行规则而不是直接关服务iptables -I INPUT -p udp --dport 4789 -j ACCEPT5.2 小包通大包不通分片与 MTU 的连锁反应这个坑的典型表现是ping -c 3通ping -s 1400不通SSH 能连上但传文件卡死HTTP 小请求正常大响应超时。本质就是 MTU 没对齐。验证方法很直接用-M do禁止分片一点点加 payload 找出临界值ping -M do -s 1422 10.10.100.2为什么是 1422因为1422 8ICMP 头 20IP 头 1450正好是内层 MTU。如果这个通说明内层 MTU 是 1450如果 1423 不通而 1422 通就确认了。找到临界值之后回头检查三处 MTUip link show dev vxlan100 | grep mtu ip link show dev br100 | grep mtu ip link show dev eth1 | grep mtu三处都应该是 1450或者更小。改的时候按顺序来先改 vxlan再改网桥最后改业务接口。改完不需要重启接口但已有的 TCP 连接不会自动重新协商 MSS需要断开重连或者依赖 PMTUD路径 MTU 发现慢慢收敛。有些环境里 ICMP 的fragmentation needed被防火墙挡了PMTUD 失效那就只能靠调小 MSS 来兜底iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu这条规则会把经过的 TCP SYN 包里的 MSS 改成路径 MTU 减 40相当于在链路上强制对齐。我在几个客户环境里用过比手工算 MSS 靠谱。5.3 learning off 之后 FDB 表项不再自增刚接触的时候我犯过一个错建接口时加了learning off然后以为 FDB 会自动填充等了半天表里还是空的ping 也不通。原因很简单learning off就是明确告诉内核不要自己学那 FDB 里就只有你手动加的那几条。这不是 bug是设计。手动模式下你必须保证两件事至少有一条00:00:00:00:00:00的泛洪表项指向远端。如果要做单播优化得把对端的 MAC 和 IP 对应关系也写进去。反过来如果用了learning on默认值FDB 会随流量自动增长。听起来方便但在手工维护拓扑的环境里反而危险——学到错误的表项之后流量会走错路径而且这些动态表项会在老化后消失导致行为不可预测。我现在的做法是一律learning off全部静态管理行为确定出问题好查。查看动态表项的残留bridge fdb show dev vxlan100 | grep -v permanent有输出说明还有动态表项可以考虑加bridge link set dev vxlan100 learning off再手动清一遍。5.4 重启后全部消失落地配置的三种做法ip link add建的接口、bridge fdb加的表项重启全没了。这是内存态配置必须做持久化。三种做法各有适用场景。做法一systemd-networkd 的 .netdev .network 文件。适合用 networkd 管理网络的机器。/etc/systemd/network/10-vxlan100.netdev[NetDev] Namevxlan100 Kindvxlan MTUBytes1450 [VXLAN] Id100 Local192.168.1.1 Remote192.168.1.2 DestinationPort4789再配一个10-br100.netdev定义网桥10-br100.network把接口挂进去。FDB 表项的持久化 networkd 支持得不太完整需要配合ExecStartPost或者一个 oneshot 服务来做所以我一般会在网桥起来之后跑一个脚本补 FDB。做法二NetworkManager 的 nmcli。适合桌面环境或使用 NM 的服务器nmcli con add type vxlan con-name vxlan100 ifname vxlan100 \ id 100 remote 192.168.1.2 local 192.168.1.1 dev eth0 \ dstport 4789 nmcli con modify vxlan100 vxlan.learning off nmcli con up vxlan100NM 的好处是所有配置都在一个地方nmcli con show一目了然坏处是 FDB 表项同样得靠脚本。做法三自己写一个 systemd service 跑初始化脚本。最灵活也最适合手工模式。脚本里把建接口、挂网桥、加 FDB 全部写全用TypeoneshotRemainAfterExityes挂在network-online.target之后。我在多节点环境里统一用这种方式因为可以把节点列表从一个配置文件读进来批量渲染 FDB。不管哪种做法都要验证一遍配置写完systemctl restart systemd-networkd或者 reboot 一次然后跑一遍完整的验证清单接口在、IP 在、FDB 在、能 ping 通。不做这一步等于没做持久化。5.5 校验和 offload 造成的假丢包这个坑最阴因为现象是抓包看到包了但对端应用收不到而且只在特定机器上出现。根因在网卡的校验和卸载。VxLAN 封装之后内层帧的校验和由硬件计算抓包工具在网卡层面抓到的包校验和字段是占位的无效值通常显示incorrect。更麻烦的是某些网卡驱动在 VxLAN 场景下的 offload 行为不一致包在发出时校验和没算对对端直接丢了而你在本机抓包看到的是完整的包完全看不出问题。排查方法是在对端抓包并用-vv看校验和tcpdump -i eth0 -nn -vv udp port 4789 -c 5如果看到bad udp cksum或者incorrect基本就是这个问题。验证性修复是关掉相关 offloadethtool -K eth0 tx off ethtool -K eth0 rx off或者只关校验和相关的ethtool -K eth0 tx-checksum-ip-generic off关了之后如果通了说明确实卡在 offload 上。但不要长期关着关掉之后校验和靠 CPU 算吞吐会明显下降。正确做法是升级网卡驱动或固件或者调整 VxLAN 接口的tx校验和设置ip link set dev vxlan100 tx checksum off具体哪个选项有效取决于网卡型号和驱动版本得实测。我在两台不同代的网卡上遇到过这个问题其中一台升级驱动就解决了另一台只能在内核启动参数里加网卡相关的 quirk。这类问题没有通用解只能一层层试。6. 把手动方案压到极致性能调优与基线测试6.1 GSO/GRO 与 tx-checksumming 的实际影响VxLAN 的性能瓶颈主要在封装和解封装上。每发一个包内核都要加 50 字节的头、算哈希决定源端口这些是纯 CPU 开销。现代网卡支持 VxLAN 相关的 offload可以把一部分工作交给硬件。先看当前状态ethtool -k eth0 | grep -E tx-checksum|generic-receive-offload|tcp-segmentation-offload|tx-udp-segmentation重点关注tx-udp-segmentationUDP 分段卸载VxLAN 场景下非常关键和tx-checksum-ip-generic。这两个开着的话大包的封装和校验和都由硬件处理CPU 占用能降一大截。如果没有硬件支持可以退而求其次调整 vxlan 接口的 GSO 参数ip link set dev vxlan100 gso_max_size 65536 ip link set dev vxlan100 gro_max_size 65536这两个参数控制的是单个 skb 能聚合的最大尺寸调大之后可以减少包数量降低 per-packet 开销。实测在纯软件路径下调到 64K 能提升 15%~30% 的吞吐具体幅度看 CPU 和包大小。还有txqueuelen。vxlan 接口默认队列长度不大高吞吐场景下容易丢包ip link set dev vxlan100 txqueuelen 5000这个值不是越大越好太大反而增加延迟。我的经验是先调到 5000 观察如果ip -s link show vxlan100里还有 dropped再往上加。6.2 用 iperf3 和 ping -M do 建基线调优之前先建基线不然改了什么都不知道有没有效果。两个工具就够了。第一个是ping -M do确认 MTU 边界前面说过不再重复。第二个是iperf3测吞吐。在对端起服务端iperf3 -s本端跑测试iperf3 -c 10.10.100.2 -t 30 -P 4-P 4起 4 条并行流单流容易被 TCP 窗口限制测不出真实带宽。记录下初始的 Gbits/sec然后依次开启 offload、调整 GSO、调 txqueuelen每改一项测一次做成表格对比。我自己的实测数据两台同代服务器、万兆网卡、1500 MTU配置吞吐CPU 单核占用默认2.1 Gbps85%开 tx-udp-segmentation6.8 Gbps45%再加 gso_max_size655367.4 Gbps38%再加 txqueuelen50007.5 Gbps36%可以看到最大的一跳是 UDP 分段卸载开了之后提升三倍多。这也是为什么我一直强调先看ethtool -k的输出硬件能力决定了上限。还有一点测试要用大包。iperf3默认的缓冲区大小在小包场景下测不出封装开销的影响。加-l 1400或者-M 1400用接近 MTU 的包长更贴近真实业务。6.3 手动维护的成本曲线什么时候该换方案最后说说我的判断标准。手动方案的成本不是线性的它在某个点上会突然变陡1~5 台手工配置半小时搞定改一次五分钟完全没问题。6~15 台需要脚本辅助FDB 批量下发配置纳入版本管理。运维成本每周几十分钟量级。16~50 台需要配置中心渲染变更要有人审核故障排查需要拓扑图辅助。开始出现改了 A 忘了 B的事故。50 台以上静态 FDB 的维护成本超过收益该上控制平面了。这时候的问题不是技术难度是人脑记不住这么多状态。还有一个隐藏成本故障定位。手工方案的好处是每一层都看得见坏处是没有统一视图出问题要一台台机器登上去看。节点少的时候这是优势节点多了就变成负担。我在 20 台左右的环境里就开始用脚本定期采集所有节点的ip -d link show、bridge fdb show、ip neigh show存成快照出问题时对比前后差异比一台台登上去快得多。另外一个容易忽略的点是变更窗口。手工改配置没有事务性改到一半失败了网络就处于半通状态。我的做法是把每一步都写成幂等的脚本先在新节点上完整跑一遍确认没问题再推到存量节点出问题可以立即回滚——回滚也是跑一遍脚本只是参数换回旧值。我在几个小规模环境里用纯手工 VxLAN 跑了两年多中间经历过节点增删、VNI 扩容、底层网络换设备总体还算稳。真正让我觉得难受的不是配置本身而是排查跨节点问题时那种要一台台去看的无力感。后来我们加了定时快照采集才把这块补上。如果你也打算手工搭建议一开始就把节点清单和配置模板管起来别等到十几台的时候再回头补那时候补的成本是刚开始的好几倍。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询