一、问题背景

在基于 PVE(Proxmox VE)的单节点虚拟化环境中,宿主机偶发网络异常,表现为:

  • 外网不可达(无法 ping 公网地址)
  • 宿主机通过重启网络服务可立即恢复
  • 虚拟机在宿主机网络恢复后 无法自动恢复网络
  • 虚拟机内部重启网络服务无效
  • 只有重启虚拟机才能 100% 恢复

该现象在家用硬件、非 HA、bridge 网络架构中具有一定普遍性。


二、初始假设与验证路径

1. 虚拟机网卡模型假设

最初怀疑为 VirtIO 在宿主机网络异常时放大问题,因此进行了如下验证:

  • 将虚拟机网卡模型由 VirtIO 切换为 Intel E1000E
  • 期望通过更接近真实硬件的模型获得更好的 link down / up 事件传播

2. 验证结果

  • 宿主机网络异常时,E1000E 不能阻止问题发生
  • 宿主机网络恢复后,虚拟机 仍存在网络假死
  • 虚拟机内:
    • 接口状态显示 UP
    • 无法访问外网
    • 重启网络服务无效
  • 虚拟机重启后网络必然恢复

结论:

问题不在虚拟机网卡模型层面


三、systemd + bridge + KVM 的一致性边界

在异常场景下,宿主机通常通过:

systemctl restart networking.service

恢复网络。

该操作在 systemd + bridge 环境中会导致:

  • bridge 被销毁并重建
  • tap 设备快速解绑 / 重新绑定
  • 虚拟机未必收到完整的 link down → up 事件
  • DHCP / ARP / route 状态可能进入不一致状态

此时虚拟机网络栈处于:

逻辑上未崩溃,但状态不可预测

这是虚拟化架构本身的边界问题,而非配置错误。


四、关键工程结论

经过多轮实测,可得出以下结论:

  1. 宿主机网络恢复 ≠ 虚拟机网络必然恢复
  2. 虚拟机内部自愈手段(ifdown/ifup、dhclient、重启网络服务)不可靠
  3. 虚拟机重启是唯一 100% 确定的恢复方式
  4. 在单节点、非 HA 环境中,追求“自动自愈”不如追求“确定性收敛”

最终结论:

当宿主机发生网络中断时,最可靠的策略是直接重启宿主机

因为宿主机重启可以同时完成:

  • 物理网卡重置
  • bridge 重建
  • tap 重新绑定
  • 虚拟机网络栈全状态重置

五、设计目标的转变

设计目标从:

“尽量让虚拟机自己恢复网络”

转变为:

“一旦检测到宿主机网络中断,直接重启宿主机,保证整体收敛”

这是典型的工程止损决策,而非妥协。


六、最终方案:宿主机网络监控 + 自动重启

方案原则

  • 定期检测外网连通性
  • 一旦判定为不可达:
    • 不再尝试复杂恢复
    • 直接重启宿主机
  • 引入冷却时间,防止重启风暴
  • 记录日志,便于事后分析

七、宿主机网络重启 Watchdog 脚本

功能特性

  • 每 5 分钟执行一次
  • 使用多个公网目标降低误判
  • 设置重启冷却时间
  • 仅在确认异常时触发 reboot

脚本示例(脱敏)

#!/bin/bash
set -u

TARGETS=("PUBLIC_IP_1" "PUBLIC_IP_2")
PING_COUNT=3
PING_TIMEOUT=2
COOLDOWN_SEC=600
LOGFILE="/var/log/net.log"
STATEFILE="/run/net.last"

ts() { date "+%Y-%m-%d %H:%M:%S"; }

log() {
  echo "$(ts) $*" >> "$LOGFILE"
}

can_reboot() {
  [[ -f "$STATEFILE" ]] || return 0
  last=$(cat "$STATEFILE" 2>/dev/null || echo 0)
  now=$(date +%s)
  (( now - last >= COOLDOWN_SEC ))
}

reachable=0
for ip in "${TARGETS[@]}"; do
  if ping -c "$PING_COUNT" -W "$PING_TIMEOUT" "$ip" >/dev/null 2>&1; then
    reachable=1
    break
  fi
done

if (( reachable == 1 )); then
  log "OK: network reachable"
  exit 0
fi

log "ERROR: network unreachable"

if ! can_reboot; then
  log "SKIP: cooldown active"
  exit 0
fi

date +%s > "$STATEFILE"
sync
log "ACTION: reboot host"
systemctl reboot

八、定时执行

*/5 * * * * /path/to/net_reboot_watchdog.sh

九、方案评价

该方案具有以下特点:

  • 确定性强:最终状态必然恢复
  • 实现简单:避免复杂链式修复
  • 适合单节点环境
  • 符合家用硬件现实条件

代价是:

  • 异常发生时会重启宿主机
  • 但相比长期网络假死,这是可接受且可预期的成本

十、总结

在 PVE 单节点环境中,面对宿主机网络异常:

接受虚拟化的一致性边界,选择确定性收敛方案,是更成熟的工程决策。

与其在虚拟机内反复尝试不可靠的网络自愈,不如在宿主机层面直接重启系统,换取整体稳定性。

Leave a Reply

Your email address will not be published. Required fields are marked *