在异地 PVE 集群(通过 VPN 连接)中,MTU(最大传输单元) 设置不当是导致集群连接不稳定、Web 界面卡顿甚至 QDevice 频繁离线的“隐形杀手”。
由于 VPN 隧道会在原始数据包外包装一层额外的 Header,如果不调整 MTU,数据包就会在路由器或 VPN 网关处被分片(Fragmentation),从而引发 Corosync 心跳丢失。
1. 常见 VPN 的 MTU 推荐值
假设您的物理网卡(以太网)默认 MTU 为 1500:
| VPN 类型 | 额外开销 (Header) | 推荐 MTU 设置 | 原因 |
|---|---|---|---|
| WireGuard | 60 - 80 bytes | 1420 或 1280 | 1420 是标准值;1280 是 IPv6/异地跨公网最稳的值。 |
| Tailscale | - | 1280 | Tailscale 内部自动处理,但手动限制 1280 能解决 99% 的兼容性。 |
| ZeroTier | 40+ bytes | 1280 | 跨公网节点建议统一降至 1280。 |
| OpenVPN (UDP) | ~68 bytes | 1300 | UDP 封装开销较大。 |
黄金法则: 在跨地域公网环境下,将 VPN 虚拟网卡的 MTU 统一设置为 1280 是最稳妥的选择,因为这是 IPv6 要求的最小 MTU,几乎能通过所有复杂的公网路由。
2. 如何实测“最完美”的 MTU 值?
不需要猜测,您可以使用 ping 命令通过测试包的大小来探测物理路径允许的最大 MTU(不产生分片):
在 PVE 节点运行以下命令(假设目标是另一个节点的 VPN IP):
# -M do 表示禁止分片,-s 指定包大小
# 注意:1472 (数据) + 8 (ICMP) + 20 (IP Header) = 1500
ping -c 3 -M do -s 1472 <对端VPN_IP>- 如果显示
Frag needed and DF set: 说明包太大了。请不断减小-s后的数值(如 1400, 1350...)。 - 直到能 Ping 通: 记下该数值 $S$。
- 最终 MTU = $S + 28$。
3. 配置建议:针对 WireGuard
如果您使用 WireGuard 连接 PVE 节点,请在配置文件的 [Interface] 部分手动指定:
[Interface]
PrivateKey = <YOUR_KEY>
Address = 10.0.0.1/24
MTU = 1280 # <--- 强制设置为 1280
...修改后重启接口:
wg-quick down wg0
wg-quick up wg04. PVE 网络接口同步调整
为了确保 PVE 的 Corosync 流量完全契合 VPN 的 MTU,建议在 /etc/network/interfaces 中也检查一下。
如果您的 Corosync 是运行在 VPN 虚拟网卡上的,通常不需要额外修改 vmbr0 的 MTU,但必须确保 VPN 隧道内传输的包不会超过您刚才设置的 1280。
5. 一个关键的内核参数优化
为了进一步缓解由于 MTU 或网络抖动引起的重传问题,建议在所有 PVE 节点执行以下内核优化(特别是针对异地 VPS):
# 开启 TCP 窗口缩放和优化重传机制
cat <<EOF >> /etc/sysctl.conf
net.ipv4.tcp_mtu_probing = 1
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
EOF
sysctl -ptcp_mtu_probing = 1:允许内核自动探测路径上的 MTU,在发生 MTU 不匹配时自动调小包大小。