【技术分享】解决飞牛VM(PVE环境)网络间歇性断连/手机无法访问的“自愈”方案
【问题描述】
最近在 PVE 里跑飞牛 OS ,网卡设置为virtio模式:
- 飞牛 VM 运行一切正常,PVE 控制台能进,公网访问也正常。
- 局域网经常莫名其妙“拒绝连接”。
- 手动执行
systemctl restart NetworkManager 后,有时候电脑恢复了,手机还是进不去;有时候手机电脑都进不去。
- 必须重启整个虚拟机才能彻底恢复,坚持不了多久,几个小时就over。
【原因分析】
Linux 内核网络状态与 NetworkManager (NM) 出现了“失步”。在虚拟化环境下,网卡微小的震荡会导致 NM 的路由和 ARP 邻居表卡在旧状态。手机连不上是因为它命中了旧的 IP-MAC 映射,而 NM 没有强制刷新内核的 ARP 缓存。
【解决思路】
单纯重启 NM 是不够的,必须在重启 NM 后立即强制刷新邻居表(ARP 缓存)。为了不折腾,我们做一个“自动监控”,只有网不通时才触发修复。
【操作步骤】
第一步:创建自愈脚本
在终端执行以下命令(注意:把 GW 后面的 IP 改成你自己的网关,通常是路由器 IP):
sudo tee /usr/local/bin/net-selfheal.sh <<'EOF'
#!/bin/bash
# 1. 填入你的网关IP
GW="192.168.0.1"
# 2. 检查网络,仅在连续 ping 不通网关时介入
if ! ping -c 1 -W 1 "$GW" >/dev/null 2>&1; then
echo "$(date) 检测到网络异常,启动自愈程序..."
# 重启网络管理服务
systemctl restart NetworkManager
# 关键:等待3秒让网卡稳定
sleep 3
# 核心步骤:强制清空所有邻居表记录(ARP缓存)
ip neigh flush all
echo "$(date) 自愈完成。"
fi
EOF
# 赋予执行权限
sudo chmod +x /usr/local/bin/net-selfheal.sh
第二步:配置系统自动巡检
我们利用 systemd 建立一个定时器,每 2 分钟检查一次。
# 1. 创建服务项
sudo tee /etc/systemd/system/net-selfheal.service <<'EOF'
[Unit]
Description=Network self-heal for Feiniu VM
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/net-selfheal.sh
EOF
# 2. 创建定时器(每2分钟运行一次)
sudo tee /etc/systemd/system/net-selfheal.timer <<'EOF'
[Unit]
Description=Run network self-heal every 2 mins
[Timer]
OnBootSec=2min
OnUnitActiveSec=2min
AccuracySec=30s
[Install]
WantedBy=timers.target
EOF
# 3. 启动定时器
sudo systemctl daemon-reload
sudo systemctl enable --now net-selfheal.timer
如果你也遇到了这种“半死不活”的网络问题,建议部署这个小工具,希望对你有帮助。🎶