前端项目连着虚拟机里的Redis和MySQL,改着改着突然连不上了。查半天不是代码问题,是虚拟机的IP又变了——上一秒还是192.168.187.129,重启一下变成192.168.187.132,再过会儿又跳到192.168.187.135。所有配置文件里写死的地址全部作废,这应该是不少人在跑点评类实战项目时都撞过的墙。虚拟机默认走DHCP动态拿地址,只要遇到重启、快照回滚、网卡重置,IP就可能漂走,手动改回来很快又会漂。这篇文章我会把“改成固定IP”这件事从头到尾捋清楚:为什么会漂、固定IP前要看哪几个参数、CentOS和Ubuntu分别怎么配、配完怎么验证,再把踩过的坑和排查思路一并写出来。内容不绕弯子,直接对着操作来就行。
1. 先搞明白IP为什么会“漂”,再动手改
很多人一上来就搜“如何设置静态IP”,搜到教程就照着改,改完确实固定了,但遇到复制虚拟机或点了某个重置按钮后,IP又变了。这时候不懂原理就会很懵。所以第一步不是改配置,而是把IP漂移的机制弄明白。
1.1 虚拟机的IP是从哪来的
在VMware里最常见的网络模式是NAT。它的逻辑可以这样理解:VMware在Windows宿主机上虚拟出一块网卡,相当于一个内部小交换机,虚拟机所有网卡都接在这台“小交换机”上。这个虚拟网络的网段默认是192.168.x.0,网关一般是192.168.x.2,宿主机对应一块192.168.x.1的虚拟网卡。
问题是虚拟机开机时自己并不知道该用哪个IP,它得向这个虚拟网络里的DHCP服务申请地址。VMware在安装时自带了一个轻量级DHCP服务,虚拟机网卡一启动就发广播:“给我个地址。”DHCP服务就从地址池里挑一个空闲IP分给它,同时附上租期。这个流程和公司办公室里的路由器分配IP没有任何区别,只是把设备从手机换成了虚拟机。
1.2 DHCP租约到期或重连,就是IP漂移的根源
DHCP分配的IP不是永久绑定的,它有一个“租约”概念。你可以把DHCP服务器想象成酒店前台,虚拟机每次入住登记,前台随机分配一个房间号并说明住多久。租期内续住没问题,但一旦退房再重新登记,或者前台觉得租约到期了要重新分配,房号就可能换。
具体到VMware场景,下面几种操作都会触发重新分配:
- 虚拟机重启,Linux里的DHCP客户端重新请求地址;
- 虚拟机挂起后再恢复,网络连接重建;
- 恢复快照或复制虚拟机,网卡状态回到历史节点,可能重新匹配;
- 在虚拟机设置里点了“重置”网卡,MAC地址都换了,DHCP自然按新设备分配;
- 虚拟网络编辑器里DHCP租期被人为调短,比如改成30分钟,那IP就会高频变动。
MAC地址是这里的关键。DHCP服务器分配IP时通常会按MAC记忆:同一个MAC来过,优先分配上次同一个地址。但如果MAC都变了,或者DHCP服务本身重启后缓存丢失,前台的“会员记忆”失效,IP就散了。
1.3 为什么有的机器IP一直没变过
很多人会有疑问:“我的虚拟机从来没改过,为什么IP一直稳定?”这是因为DHCP会优先尝试续租旧地址。虚拟机重启时,DHCP客户端会带着原IP去请求续租,只要地址池没冲突,服务器大概率会把同一个IP还给你。但这只是“大概率”,不是承诺。地址池被占用、快照回滚到不同网络状态、VMware服务重启等因素都会打破这种稳定。
所以正确心态是:在本地开发环境里,DHCP带来的“随机稳定性”不可靠,想要一劳永逸,要么在Linux端配置静态IP,要么在VMware层面对某台虚拟机做固定分配。后者配置入口藏得比较深,绝大多数场景下直接在Linux里写死IP是最高效的方案。
2. 固定IP前的关键准备:看清网段、网关和地址池
固定IP不是随便拿个数字填进去就行。填错了轻则虚拟机没网,重则和宿主机或其它设备冲突。改配置之前,有三项信息必须先查清楚:子网网段、网关IP、DHCP地址池范围。
2.1 在VMware里查NAT网段和网关
打开VMware Workstation,菜单栏点“编辑”->“虚拟网络编辑器”。在列表里找到VMnet8,注意它对应的网络模式要显示“NAT”。选中后右侧能看到“子网IP”和“子网掩码”,比如:
- 子网IP:192.168.187.0
- 子网掩码:255.255.255.0
记下这个网段,后面所有IP都必须在这个网段里。接着点右下角“NAT设置”,弹窗里会显示“网关IP”,常见是192.168.187.2。这个就是虚拟机出网的默认网关,配置静态IP时要和它保持一致。
2.2 查DHCP地址池,决定静态IP取值
在虚拟网络编辑器里点击“DHCP设置”,会看到起始IP和结束IP。VMware默认通常是从128开始到254结束。这一步很多人会忽略,直接填一个像192.168.187.200这样的地址。如果200正好落在DHCP池内,就可能和DHCP分配的地址冲突。虽然DHCP服务器一般情况下会先检查冲突,但本地测试环境里这种事情并不罕见,尤其在多个虚拟机同时开的时候。
正确的取法是:在网关与DHCP起始地址之间选一个空闲IP。例如网关是.2,DHCP池从.128开始,那静态IP可以取.100、.110、.120这种。这里给你一份对照参考:
| 项目 | 建议值 | 说明 |
|---|---|---|
| 子网掩码 | 255.255.255.0 | 与VMware虚拟网络一致 |
| 网关 | 192.168.x.2 | 在虚拟网络编辑器NAT设置里查看 |
| 静态IP | 192.168.x.100 | 避开DHCP池起始地址(如128) |
| DNS | 114.114.114.114 / 223.5.5.5 | 国内公共DNS或网关地址 |
注意:不要在虚拟网络编辑器里随意修改子网IP。改了之后整个网段变化,所有虚拟机的IP都要重新适配,而且宿主机相关配置也会乱,属于给自己挖坑。
2.3 改之前确认网络模式
还有一点基础但容易出错:虚拟机网络适配器必须选择“NAT模式”。右键虚拟机->设置->网络适配器,勾选“NAT”。如果你当前选的是“仅主机模式”,那么虚拟机只能和宿主机通信,不能访问外网;如果是“桥接模式”,IP会直接从路由器获取,这时去配置192.168.187.x反而可能不通。本文所有操作建立在NAT模式下。
3. 实操:CentOS和Ubuntu固定IP手把手配置
信息查完之后,进入正式配置。这里分别覆盖CentOS系和Ubuntu系的常见做法。不要只抄一种,根据自己的系统选择对应章节。
3.1 第一步:确认虚拟机里的网卡名和当前IP
在虚拟机终端执行:
ip addr输出里找到一个以ens、eth或enp开头的网卡,比如ens33、ens160,这就是你的物理网卡。同时记下当前IP,确认它在VMware虚拟网络编辑器查到的同一网段内。如果当前IP完全不在这个网段,说明网络模式可能选错了,先回到2.3检查。
3.2 CentOS 7/8/Stream 配置静态IP
CentOS配置网卡的经典路径是编辑/etc/sysconfig/network-scripts/下的ifcfg文件。文件名通常和网卡名对应,比如ifcfg-ens33。先备份再修改:
sudo cp /etc/sysconfig/network-scripts/ifcfg-ens33 /etc/sysconfig/network-scripts/ifcfg-ens33.bak sudo vi /etc/sysconfig/network-scripts/ifcfg-ens33核心要改动和新增的字段如下:
TYPE=Ethernet BOOTPROTO=static NAME=ens33 DEVICE=ens33 ONBOOT=yes IPADDR=192.168.187.100 NETMASK=255.255.255.0 GATEWAY=192.168.187.2 DNS1=114.114.114.114 DNS2=223.5.5.5字段含义逐一说清楚:
BOOTPROTO=static:把协议从dhcp改为static,这是最关键的一行;ONBOOT=yes:开机自动启用网卡,必须设置,否则重启后网卡不工作;IPADDR:你选定的静态IP;NETMASK:子网掩码,一般就是255.255.255.0;GATEWAY:虚拟网络的网关,要和VMware NAT设置里保持一致;DNS1/DNS2:建议填国内公共DNS,方便虚拟机访问外网。
有些机器ifcfg文件里还带着UUID=xxxx和HWADDR=xx:xx:xx:xx:xx:xx,保留原值即可,不要删。HWADDR对应的是网卡MAC,写错会导致网络起不来。
保存退出后重启网络。CentOS 7常用命令:
sudo systemctl restart networkCentOS 8或Stream版本里传统network服务可能已经被废弃,推荐用NetworkManager管理:
sudo nmcli connection reload sudo nmcli connection up ens33如果嫌编辑文件麻烦,CentOS完全可以不走ifcfg,直接用nmcli命令完成同样配置:
sudo nmcli connection modify ens33 ipv4.method manual ipv4.addresses 192.168.187.100/24 ipv4.gateway 192.168.187.2 ipv4.dns "114.114.114.114 223.5.5.5" sudo nmcli connection up ens33这种方式更不容易踩到NetworkManager接管网卡的坑,适合不想折腾文件细节的人。
3.3 Ubuntu 18.04+ 配置静态IP(netplan方案)
Ubuntu新版使用netplan管理网络,配置文件在/etc/netplan/目录下,常见文件名有00-installer-config.yaml、01-network-manager-all.yaml。先查看实际文件:
ls /etc/netplan/ sudo cat /etc/netplan/00-installer-config.yaml编辑前同样备份。以Ubuntu 20.04/22.04为例,将配置改成:
network: version: 2 ethernets: ens33: dhcp4: false addresses: - 192.168.187.100/24 routes: - to: default via: 192.168.187.2 nameservers: addresses: - 114.114.114.114 - 223.5.5.5务必注意:YAML对缩进极其敏感,不能用Tab键,必须用空格。不同网卡名称对应ethernets下的键名,比如是ens33就写ens33。routes里via是网关地址。如果没有routes这段,虚拟机可能配置完静态IP后能ping通内网但上不了外网。
保存后执行:
sudo netplan apply没有任何报错说明配置已生效。如果提示Invalid YAML,基本就是缩进问题,回到文件检查冒号后面是否有空格、层级是否对齐。
有时候Ubuntu桌面版会用NetworkManager接管网络,netplan apply后IP没有变化,可以再执行:
sudo systemctl restart NetworkManager3.4 修改后验证:不只ping,还要重启验证
配置改完,先看IP是否生效:
ip addr show ens33确认当前的IP已经变成192.168.187.100。接着依次验证网关和外网:
ping -c 4 192.168.187.2 ping -c 4 114.114.114.114第一跳通了说明静态IP和网关没问题;第二跳通了说明DNS和路由没问题。这里要特别提醒:不要只看IP显示就以为大功告成,必须重启一次虚拟机再确认IP没变。很多人的情况是systemctl restart network后IP正常,但一reboot又回到DHCP,原因通常是BOOTPROTO没改干净或者NetworkManager配置文件干扰。重启后再执行ip addr确认地址仍然是192.168.187.100,这才是完整闭环。
4. IP固定之后,点评类项目的连接方式再优化一步
IP固定只是第一步。真正项目中,每次IP变化要改的配置文件远比想象中多。把IP固定之后,我还建议顺手做一次连接方式的收尾,让开发体验更顺。
4.1 每次IP变化到底会牵动哪些文件
以典型的点评类项目为例,后端服务通常部署在Windows宿主机上,通过虚拟机里的Redis、MySQL、Nginx等服务做数据存储和反向代理。IP一变,至少下面几处要跟着改:
application.yml或application.properties里的Redis地址;- 同一文件里的MySQL数据库地址;
- 前端项目请求后端接口的BaseURL;
- Nginx反向代理配置里指向后端服务的地址;
- 如果用了Docker容器,容器内的环境变量也可能写死IP。
这些地方散落在不同项目、不同配置文件里,改漏一个,系统跑起来就是各种超时和连接拒绝。换成固定IP后,这个问题从源头消失,但为了以后部署到云服务器时省事,连接方式还可以更优雅一点。
4.2 用hosts把IP映射成域名,配置里不直接写IP
方法很简单:在Windows宿主机的C:\Windows\System32\drivers\etc\hosts文件末尾加一行:
192.168.187.100 vm-dev.local然后在项目配置文件里,凡是原本写192.168.187.100的地方,全部换成vm-dev.local。比如:
spring: redis: host: vm-dev.local port: 6379 datasource: url: jdbc:mysql://vm-dev.local:3306/dianping?useSSL=false这样做的好处显而易见:当虚拟机IP真的再次变化时,只需要改hosts里一行,项目代码完全不用动。以后部署到云服务器,也只需要把hosts指向换成云服务器IP,业务代码原封不动。这个习惯越早养成越省心。
需要注意的是,修改Windows hosts文件需要管理员权限。建议先用文本编辑器打开hosts,再以管理员身份运行编辑器保存,否则容易被系统拒绝写入。虚拟机内如果也要访问某个服务域名,同样可以修改/etc/hosts。
4.3 两个容易让固定IP前功尽弃的操作
IP改好之后,大部分人会很顺利,但有两个操作会让配置一夜回到解放前。
第一个是在VMware的“虚拟机设置 -> 网络适配器 -> 高级”里点“重置”。这个按钮会重新生成虚拟网卡的MAC地址,也就是说你的网卡对系统来说变成了一块新网卡。就算你在Linux里配置的是静态IP,新网卡对应的是新配置文件,原来的静态配置不会自动生效,系统会重新走一遍DHCP。我的建议是:除非明确知道自己在做什么,否则永远不要点这个重置。
第二个是复制虚拟机。直接复制一份虚拟机文件后打开,VMware通常会检测到这是副本,并提示“我已复制该虚拟机”。如果你选择了“复制”,VMware会重新生成MAC地址,新虚拟机又会变成一个DHCP新设备。复制前最好先把原虚拟机的网络改成静态IP,并提前给副本规划好一个不同IP;复制后进入副本系统,修改网卡配置IP为新值,再重启网络,这样两台机器才能同时在线且不冲突。
5. 实战中翻过车的排查思路与速查表
配置静态IP看起来简单,但真到动手的时候,每个人遇到的报错五花八门。这里把最常见的几类坑按场景整理出来,遇到问题可以直接对照着查。
5.1 重启网络服务失败,命令报错
- 现象:执行
systemctl restart network后提示Job for network.service failed,网络直接断掉。 - 原因1:CentOS 8以上版本已经移除了老旧的
network.service,改用NetworkManager。这种情况不要死磕network命令,直接用nmcli connection reload和nmcli connection up 网卡名。 - 原因2:ifcfg文件里IPADDR或GATEWAY填错,比如网关写成了192.168.187.1。记住VMware NAT模式下网关通常以.2结尾,不是.1。
- 原因3:UUID重复或者HWADDR被误改。备份过原文件的话,直接diff对比一下。
5.2 宿主机ping不通虚拟机
- 先确认虚拟机内部能ping通网关和外网,如果能ping通外部但宿主机ping不通,多半是Windows防火墙拦了ICMP,临时放行或检查防火墙规则即可,本地开发环境可适当放宽。
- 如果虚拟机内部连网关都ping不通,多半是VMware NAT服务没运行。Windows上打开服务管理器,找到“VMware NAT Service”,确认状态是“正在运行”。
- 检查虚拟机网络适配器是否还是NAT模式。有人配置过程中顺手改成了“仅主机模式”,表现形式就是内网通外网不通。
5.3 改完静态IP后自动变成169.254.x.x
这个地址是操作系统在没有拿到有效IP时自动生成的保留地址。看到169.254开头的IP,说明配置根本没生效。优先检查两件事:
ONBOOT=yes是否写上,没有的话网卡开机不启动;- 是否真的重启了网络服务,特别是Ubuntu执行
netplan apply后是否出现YAML报错。
5.4 常见问题速查表
| 问题 | 可能原因 | 排查方向 |
|---|---|---|
| IP没变,还是原来的动态地址 | BOOTPROTO没改成static,或NetworkManager配置覆盖 | 检查ifcfg文件,用nmcli命令重设 |
| 内网能通,外网不通 | 网关或路由缺失 | 检查GATEWAY,确认指向192.168.x.2 |
| 能ping通IP,ping不通域名 | DNS配置错误 | 检查DNS1/DNS2,改为公共DNS |
| Ubuntu执行netplan报错 | YAML缩进错误 | 检查空格、冒号、层级对齐 |
| 虚拟机复制后两台IP相同 | MAC重复或快照恢复 | 重置MAC后分别设置不同静态IP |
| Windows hosts配置无效 | hosts文件被缓存或权限不够 | 用管理员权限修改,执行ipconfig /flushdns |
配置完这些之后,我个人最深的体会是:固定IP本身不复杂,复杂的是一套环境里有太多变量。如果你正在跑的点评类项目已经连了好几个服务,建议把IP、网关、DNS这些信息单独存到一个说明文件里,放在项目目录下。以后换机器、换网络、重建虚拟机,照着说明就能快速恢复环境,不用再靠记忆到处翻配置。再讲究一点,就把hosts域名映射这个习惯一并用上,项目代码永远只写域名不写IP,网络环境怎么变都不慌。