最近在本地VMware Workstation上运行Ubuntu 22.04虚拟机时,频繁遇到一个恼人的问题:每次挂起或重启虚拟机后,原本配置好的静态IP就会莫名其妙丢失,网卡恢复成DHCP模式。这不仅打断了我的开发环境,还导致需要频繁重新配置服务地址。经过多次实践和排查,终于找到了稳定可靠的解决方案。
这个问题通常发生在以下场景:
根本原因在于Ubuntu的Netplan配置与虚拟化平台网络管理的交互问题。传统解决方案往往只临时生效,下次启动问题依旧。下面分享我验证过的永久解决方案。
从Ubuntu 17.10开始,系统默认使用Netplan作为网络配置抽象层。Netplan作为中间件,会将YAML格式的配置文件转换为后端网络服务(NetworkManager或systemd-networkd)所需的配置。这种设计虽然提高了灵活性,但也增加了配置复杂度。
关键配置文件位置:
code复制/etc/netplan/*.yaml
虚拟机网络通常有三种模式:
在桥接模式下,虚拟网卡容易在恢复时被重新初始化,导致配置丢失。这是因为:
首先查看网卡信息:
bash复制ip a
典型输出示例:
code复制2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:3a:5b:7c brd ff:ff:ff:ff:ff:ff
inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic ens33
valid_lft 86388sec preferred_lft 86388sec
记录关键信息:
备份原始配置:
bash复制sudo cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.bak
编辑配置文件:
bash复制sudo nano /etc/netplan/00-installer-config.yaml
完整配置示例(桥接模式静态IP):
yaml复制network:
version: 2
renderer: networkd
ethernets:
ens33:
dhcp4: no
addresses: [192.168.1.100/24]
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
match:
macaddress: 00:0c:29:3a:5b:7c
set-name: ens33
关键参数说明:
match.macaddress: 绑定物理MAC地址set-name: 固定接口名称dhcp4: no: 禁用DHCP应用新配置:
bash复制sudo netplan apply
验证配置:
bash复制ip a show ens33
预期应显示配置的静态IP地址。同时测试网络连通性:
bash复制ping -c 4 google.com
当存在多个网络接口时,需要为每个接口单独配置。示例:
yaml复制network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
addresses: [192.168.1.100/24]
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8]
eth1:
dhcp4: yes
配置未生效:
sudo netplan --debug apply查看详细错误网络接口名称变化:
match.macaddress精确匹配DNS解析失败:
/etc/resolv.conf(重启会重置)对于VMware Workstation:
对于VirtualBox:
对于服务器版Ubuntu,建议完全禁用NetworkManager:
bash复制sudo systemctl stop NetworkManager
sudo systemctl disable NetworkManager
创建配置备份脚本:
bash复制#!/bin/bash
BACKUP_DIR="/var/backups/netplan"
mkdir -p $BACKUP_DIR
cp /etc/netplan/*.yaml $BACKUP_DIR
find $BACKUP_DIR -type f -mtime +30 -delete
添加到cron每周执行:
bash复制sudo crontab -e
添加:
code复制0 3 * * 0 /path/to/backup_script.sh
创建IP检测脚本:
bash复制#!/bin/bash
EXPECTED_IP="192.168.1.100"
CURRENT_IP=$(ip -4 addr show ens33 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
if [ "$CURRENT_IP" != "$EXPECTED_IP" ]; then
logger "Detected IP change, reapplying netplan"
sudo netplan apply
fi
设置每分钟检查:
bash复制sudo crontab -e
添加:
code复制* * * * * /path/to/check_ip.sh
虽然不推荐,但可作为备选:
bash复制sudo apt install ifupdown
/etc/network/interfaces:code复制auto ens33
iface ens33 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1
bash复制sudo systemctl stop systemd-networkd
适合桌面用户:
bash复制sudo nmcli con add type ethernet con-name "static-ens33" ifname ens33 ipv4.method manual ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.dns "8.8.8.8"
sudo nmcli con up "static-ens33"
快照管理:
模板虚拟机:
网络模式选择:
性能调优:
bash复制sudo ethtool -K ens33 tx off rx off sg off tso off gso off
经过以上配置,我的Ubuntu虚拟机已经稳定运行3个月未出现IP丢失问题。关键点在于: