虚拟机里的CentOS最让人抓狂的事情之一就是IP地址总是不打招呼就换。上午还在Xshell里跑得好好的午休回来随手一连对话框直接弹超时把虚拟机窗口拉出来一看原来的192.168.188.128已经悄悄变成了192.168.188.139。这种场景我见过太多次尤其刚接触Linux的同学十有八九会被这个“薛定谔的IP”弄到怀疑人生。问题本身不复杂。虚拟机的默认网络配置走DHCP也就是说网卡每次启动都会向虚拟交换机申请一个地址租约有长有短、池子里有别的机器占了地址就会跳来跳去。要根治就得给网卡改静态IP。这篇文章就把我这些年配固定IP的经验整理出来从网络模式判断、网卡信息采集到nmtui、ifcfg、nmcli三套实操方案再到重启验证和典型故障排查争取让一台虚拟CentOS从“开机就变IP”变成“一次配置长期稳定”。不管你是刚装完虚拟机想连SSH的新手还是部署环境需要地址稳定的运维这篇都适用。1. 为什么虚拟机里的CentOS非配固定IP不可1.1 DHCP模式下的“薛定谔的IP”DHCP的设计初衷是方便自动分配网络参数。物理机也好、虚拟机也好只要网卡以DHCP方式启动就会往广播域发一个Discover请求由DHCP服务器分配一个可用IP并附带网关、子网掩码、DNS等参数。好处是零配置插上就能上网坏处也明显——地址不是终身固定的。虚拟机里这个问题会被放大。宿主机可能同时跑着好几台虚拟机VMware的VMnet8或者VirtualBox的NAT网络各自维护着一个DHCP池谁先开机谁先拿地址池子里的地址被占满后后启动的机器就会被分配到另一个网段或从池尾补位。再加上某些环境里DHCP租期短、宿主机休眠唤醒后虚拟网络重置IP“跳号”就成了家常便饭。这里有个生活化类比DHCP分配地址就像公司前台临时给访客安排工位你来一天给一个位置第二天再来又给你换一个固定IP就像有自己的工位牌不管你来不来那个工位永远给你留着。做开发、搭服务、连SSH的人要的就是那张固定工位牌。1.2 固定IP能解掉的典型问题具体来说固定IP解决的场景包括SSH远程连接。Xshell、MobaXterm、FinalShell这些工具里保存的会话默认以IP为准。IP一变所有会话全部失效密码输得再对也没用。自建服务访问。比如在虚拟机里跑MySQL、Redis、Nginx、Zabbix宿主机要访问这些服务通常直接在IP后面接端口。地址一换客户端配置全要跟着改。集群与节点通信。做了多台虚拟机组成的集群、主从库、K8s节点节点之间互相通过IP通信。只要有一台地址变了整个集群的拓扑就乱了。抓包、流量分析、端口映射。wireshark里要按IP过滤固定主机的流量或者宿主机要反向映射虚拟机的端口固定IP能把整个过程简化很多。域名解析与hosts映射。很多开发环境会在/etc/hosts或Windows的hosts文件里手动绑定虚拟机IP和主机名固定IP之后这个映射关系才可靠。可以说只要你不是“开一次虚拟机玩两分钟就关”的轻度用户配置固定IP就是迟早要做的事。1.3 三种虚拟网络模式下“固定”的含义不同在VMware里虚拟机默认有三种网络连接方式固定IP的配置逻辑完全不一样动手前必须先分清。NAT模式VMnet8虚拟机通过宿主机的虚拟网卡共享上网虚拟机之间可以互通但虚拟机群里是一个独立的私有网段比如192.168.188.0/24。宿主机通常能通过这个网段的地址访问虚拟机但物理局域网里的其他电脑不一定能直接访问。固定IP要写在VMnet8对应的网段里网关一般是192.168.188.2这种由VMware指定的地址。桥接模式虚拟机直接“插”到物理网络的交换机上相当于局域网里的一台独立新机器会从路由器拿到和宿主机同一网段的IP。固定IP时必须选择一个真实局域网里空闲的地址不能和宿主机、打印机、手机等等任何设备冲突网关就是路由器地址。仅主机模式VMnet1虚拟机和宿主机组成一个封闭网络没有外部网络出口。这种模式下固定IP主要用于虚拟机之间的内部通信或者宿主机和虚拟机的双向访问。三者的选择没有绝对的对错主要看需求。我在本地测试环境里默认都用NAT需要被局域网其他电脑直接访问、或者模拟真实生产网络时才用桥接。记住一句话网络模式决定你“在哪个网段里固定”网段选错后面配什么地址都是白搭。我在配置前一定会先打开VMware的“编辑 - 虚拟网络编辑器”看一眼VMnet8的子网和NAT网关是多少这个信息是后面填GATEWAY的依据。虚拟机软件版本不同默认网段也不同不能想当然。2. 动手前先做一轮环境侦察2.1 确认CentOS版本和网卡命名配置固定IP看起来只是改一个IP地址实际上牵涉到操作系统网络栈的手感。不同CentOS版本之间网络配置文件的位置、服务管理方式有差异建议先确认三件事系统大版本。CentOS 7、CentOS 8 Stream、更老的6.x网络配置方式不完全一样。执行 cat /etc/redhat-release 可以一眼看清。有没有NetworkManager。CentOS 7之后默认带有NetworkManager很多网络配置都经过它来生效。如果不确定systemctl status NetworkManager 看一眼。网卡名称。新版本里网卡名通常是 ens33、ens160、ens192 这类老版本里叫 eth0。用 ip link 或者 ip addr 查看。这些不确认清楚就照着网上的教程抄最容易踩坑。比如有人拿CentOS 6 的配置方法去改CentOS 7的机器配置文件路径都对不上有人改完了发现nmcli看不到配置因为系统的脚本路径被占用了。先花一分钟把环境摸清楚比折腾半小时要省心得多。2.2 把当前IP、网关、DNS信息全部记下来配置静态IP不是凭空捏一个地址出来而是要基于当前环境信息来定。我的习惯是在动配置文件之前先开一个终端把下面这些信息完整抄下来当前IPip addr show主要看网卡下的inet字段。当前网关ip route show | grep defaultNAT模式下一般是192.168.x.2这种。DNScat /etc/resolv.conf看看系统现在用的DNS是什么。如果这个文件是空的或只有一行search那就手动指定可靠DNS。网卡MACip link show 里看到的 link/ether 字段后面排查克隆UUID问题时会用到。把这些信息写在纸上或者记录在笔记软件里后面填配置文件时照着抄就不会错。尤其是网关NAT模式下千万不要去抄宿主机物理网卡的网关那是完全不通的。你填的网关必须是“虚拟机所属虚拟网络”的网关。2.3 用虚拟网络编辑器确认NAT网段与网关这一步很多人会漏掉但它决定全局。在VMware主界面打开“编辑 - 虚拟网络编辑器”找到VMnet8NAT模式对应的虚拟网络重点看两个参数子网IP、子网掩码。比如子网是192.168.188.0掩码255.255.255.0那说明这个虚拟网络的可用地址范围就是192.168.188.1到192.168.188.254。再点“NAT设置”里面有网关地址。默认通常是192.168.188.2其中.1由VMnet8虚拟网卡自己占用.2给NAT网管用。你给虚拟机配固定IP时IP地址可以在.3到.254之间挑一个但网关一定要填虚拟机软件指定的那个值也就是192.168.188.2而不是想当然填.1。VirtualBox的环境逻辑也类似只是NAT网络默认网段通常是10.0.2.0/24网关10.0.2.2。不同虚拟化平台细节有差别但“先看虚拟网络的子网和网关再定IP”这套逻辑是通用的。3. 把IP固定下来的三套实操方案3.1 nmtui文本界面不碰文件也能配固定IP如果不想背配置文件字段最简单的办法是用nmtui。它是NetworkManager自带的文本图形配置工具在终端里输入nmtui回车会弹出一个蓝底的伪图形界面。操作逻辑和配置Windows网卡差不多选择“Edit a connection”回车进入网卡列表。选中要改的网卡通常选ens33或eth0点“Edit”。把“IPv4 CONFIGURATION”从Automatic改成Manual。在Addresses里填IP和掩码格式可以写成192.168.188.128/24也可以单独填IP、掩码两列。Gateway填虚拟网络的网关DNS Servers填一个或多个。勾选“Automatically connect”和“Available to all users”确保开机自动启用。保存退出然后输入 nmcli connection reload nmcli connection up ens33 让改动生效。nmtui最大的好处是自动把配置值“翻译”成系统能认的格式不用手动编辑一堆字段对新手友好而且不容易出现大小写、空格错误。老手也可以用特别是去客户现场处理问题时nmtui比打开vi改文件更快看到全貌。3.2 直接改ifcfg配置文件最经典也最可控如果你习惯直接看配置文件或者系统里没有NetworkManager比如精简安装的CentOS 7不支持nmtui那就用最经典的ifcfg方案。前提确认网卡名称后打开对应的配置文件vi /etc/sysconfig/network-scripts/ifcfg-ens33注意ens33要替换成你自己的网卡名。文件里原本可能是这样的TYPEEthernet BOOTPROTOdhcp NAMEens33 DEVICEens33 ONBOOTyes不用管其它字段重点改这么几项BOOTPROTOstatic ONBOOTyes IPADDR192.168.188.128 NETMASK255.255.255.0 GATEWAY192.168.188.2 DNS18.8.8.8 DNS2223.5.5.5如果掩码想用CIDR写法也可以加上一行 PREFIX24IPADDR写成192.168.188.128/24两者选一种不要同时混用导致歧义。DNS建议至少填两个一个国内一个国外比如8.8.8.8和223.5.5.5避免单点DNS故障。改完后执行systemctl restart network如果系统提示找不到network服务就执行systemctl restart NetworkManager nmcli connection reload然后输入 ip addr show 检查网卡是否拿到了192.168.188.128。我对这套原理解释一下BOOTPROTOstatic告诉系统“网卡不向DHCP申请地址全听配置的”ONBOOTyes保证开机自动加载网卡配置IPADDR、NETMASK、GATEWAY就是你要固定的网络参数DNS1和DNS2写入后系统会同步到/etc/resolv.conf供域名解析使用。少了任一项都可能出现“IP配上了但上不了网”或者“重启又变回DHCP”的问题。另外补充一点CentOS 8之后默认已经不带network服务了直接敲 systemctl restart network 会提示找不到服务这是正常现象切到NetworkManager链路就好。3.3 用nmcli命令行适合批量运维和脚本化大部分服务器没有图形界面nmtui虽然方便但没法放进脚本里。如果有多台虚拟机要同时配置固定IP我更推荐直接用nmcli命令行一条条敲速度快也方便记录到操作文档里。以ens33网卡为例固定IP为192.168.188.128、网关192.168.188.2、DNS为8.8.8.8和223.5.5.5命令是这样nmcli connection modify ens33 ipv4.addresses 192.168.188.128/24 nmcli connection modify ens33 ipv4.gateway 192.168.188.2 nmcli connection modify ens33 ipv4.dns 8.8.8.8 223.5.5.5 nmcli connection modify ens33 ipv4.method manual nmcli connection up ens33执行后用 nmcli connection show ens33 可以看到这些参数已经写入NetworkManager的配置里。这种做法等价于手工编辑ifcfg文件但避免了手动排版错误也更容易配合循环脚本批量修改。不过注意一点如果系统里同时存在network服务脚本和NetworkManager管理改完了最好统一用 NetworkManager 这条线来重启。我遇到过CentOS 7里用systemctl restart network生效、过两天又被NetworkManager把配置覆盖回去的情况根因就是两套管理工具在抢网卡配置。遇到这种问题我建议要么明确只用NetworkManager要么干脆停掉NetworkManager、只保留network服务不要两个都开。4. 配置生效与验证三步走4.1 重启网络服务的正确姿势配置写完后最怕的是“看起来改了实际没生效”。所以重启网络服务时要保持清醒你用的是哪条服务管理链路就用哪条重启。CentOS 7里常见三条命令systemctl restart network对应传统的network服务改完ifcfg后用它最常见。systemctl restart NetworkManager对应NetworkManager守护进程如果用nmcli或nmtui改了配置走这里更稳。nmcli connection reload nmcli connection up ens33重新加载并激活连接不整个重启网络服务影响面更小。优先建议如果你用ifcfg手工编辑先执行 systemctl restart network如果系统提示该服务不存在或没有单位文件再切到NetworkManager链路。NetworkManager的抵用逻辑其实更像“适配器”它读取ifcfg目录里的配置并管理连接状态所以有时只 restart network 不够彻底可以两个都执行一遍反正幂等不会把配置改乱。重启之后不要急着高兴因为IP配置还有一个隐藏杀手cloud-init。如果你用的是官方云镜像或者某些定制镜像装的CentOS系统启动时会有cloud-init这个初始化进程把网络配置“重置”成模板里的默认值。判断办法是看 /etc/cloud/cloud.cfg 是否存在。存在的话要么在配置里禁用cloud-init的网络管理要么在 /etc/cloud/cloud.cfg 里设置 network: {config: disabled}。这一步不做你辛辛苦苦配的固定IP下次开机可能又回到解放前。4.2 链路、解析、远程登录逐项验证固定IP配好了不能只看网卡界面显示有地址就完事要按链路顺序一层一层验证。我习惯按这个顺序来本机IP确认ip addr show看ens33下面的inet是否变成你设置的固定地址且没有多余的第二IP。网关连通性ping -c 4 192.168.188.2能通说明虚拟机到虚拟网络出口这一段没问题。外部网络连通ping -c 4 8.8.8.8能通说明NAT出口正常不通则排查网关和防火墙。DNS解析ping -c 4 www.baidu.com能通说明DNS生效不通但8.8.8.8能通说明DNS配置有问题。远程登录验证回到宿主机用Xshell或SSH命令行重连固定IP确认端口22可达且能登录。局域网访问测试如果用的是桥接模式从另一台物理机器ping这台虚拟机的固定IP确认局域网内可达。我把上面的验证项整理成一张速查表验证项命令期望结果本地IPip addr show ens33inet为固定IP网关ping -c 4 网关IP0% packet loss外网连通ping -c 4 8.8.8.80% packet lossDNS解析ping -c 4 www.baidu.com能解析出IP并能ping通SSH连接ssh 用户名固定IP登录成功局域网访问另一台机器ping固定IP通任何一个环节断了都回去看对应配置不要整个推翻重来。4.3 彻底重启确认固定IP不丢失这是很多人会偷懒跳过的一步。我见过太多人配完固定IP在当前会话里能ping通就以为成功了结果过了一天虚拟机重启地址又变了。所以配置完成、基本验证通过之后务必做一次彻底的虚拟机重启验证。执行 reboot等系统起来登录后再次 ip addr show。如果地址还是固定IP网络自动启用那才算真正收工。如果重启后IP丢了回溯排查的顺序通常是ONBOOT没有设为yes、NetworkManager和network服务冲突、cloud-init覆盖、配置文件里有两份相同网卡的配置互相矛盾。这步做完固定IP这件事才算闭环。后面再遇到地址漂移、服务连不上的问题就可以理直气壮地往别的方向排查了。5. 固定IP后常见的五个坑与排查记录5.1 IP地址冲突或网段写错桥接模式下最容易遇到IP冲突。你手动挑了一个地址其实已经被路由器分配给手机或同事的电脑了于是虚拟机要么网络时断时续要么完全不通。判断办法配置前用另一台机器 ping -c 4 你准备配置的IP通了说明已被占用换一个更准确的做法是用 arping -I eth0 192.168.x.x -c 3 探测冲突。同时提醒一下固定IP的网段必须严格落在虚拟网络的子网内NAT里填成192.168.1.x而虚拟网络是192.168.188.0/24那就什么都通不了。5.2 网关填错外网时通时不通NAT模式下网关必须是虚拟网络编辑器里看到的那个值通常是192.168.188.2。很多人习惯性填成192.168.188.1因为觉得.1更像网关结果虚拟机只能和宿主机通信出不了外网。桥接模式下则要用你真实局域网路由器的网关通常也是192.168.1.1或192.168.3.1。判断网关对不对的最快方法ip route show 看default路由和GATEWAY的值是否一致不一致就改回来并重启网络。5.3 克隆出来的系统必现怪问题从模板虚拟机克隆新的CentOS再配置固定IP时经常出现一个怪现象配置保存好了也重启网络了IP就是不动或者干脆网卡变成“未托管”unmanaged状态。绝大多数原因就是ifcfg配置文件里的UUID和模板机重复。NetworkManager依靠UUID识别连接克隆机里有两份一模一样的UUID它不知道选哪个干脆不生效。解决办法编辑ifcfg文件把UUID那一行删掉或改成新值然后用 uuidgen 生成一个新的UUID填进去再 systemctl restart NetworkManager。这个问题尤其在“克隆虚拟机、快速部署测试环境”这个场景里高频出现值得先记下来。5.4 DNS配置被NetworkManager覆盖CentOS 7之后的默认DNS行为很特殊/etc/resolv.conf经常是一个软链接内容由NetworkManager动态生成。如果你手动改resolv.conf可能在网络服务重启之后被覆盖DNS又变回去。正确做法是在ifcfg文件里写DNS1和DNS2然后通过NetworkManager读取生效或者用 nmcli connection modify 网卡 ipv4.dns 8.8.8.8 223.5.5.5 写入。改完后重启NetworkManager再 cat /etc/resolv.conf 确认内容。5.5 常见问题速查表问题现象可能原因解决办法重启后IP又变回DHCPONBOOTno / cloud-init覆盖 / NM两套管理冲突ifcfg里ONBOOTyes禁用cloud-init网管统一用一套网络管理SSH连不上防火墙未放行22 / IP不在同网段 / sshd未启动systemctl status sshdfirewall-cmd放行22端口确认客户端和目标IP同网段网关ping不通网段写错 / NAT网关注错ip route看default路由打开虚拟网络编辑器确认NAT网关外网ping不通网关不通 / DNS失效 / 网络模式选错逐层ping网关、8.8.8.8、域名定位断点网卡名不对centos版本/虚拟网卡型号不同ip link确认实际网卡名配置文件以此为准克隆机改IP不生效UUID重复删除UUID行或uuidgen生成新UUID第六条是我额外加的因为“配置固定IP”这个操作里网卡名不对是最容易忽视的先决问题。看到网上教程是ens33自己机器是ens160照着改必然无效。别怕ip link一眼就能确认。最后分享一个小经验。我每配一台虚拟机的固定IP都会顺手做两件事一是把《IP规划表》写进虚拟机备注里内容包括虚拟机名、固定IP、网关、DNS、所属虚拟网络这样过半年再回来不用对着配置文件猜当时为什么填这个地址二是在/etc/hosts里给这台机器加一条绑定记录比如 192.168.188.128 centos-dev后续访问直接用主机名省得每次敲IP。踩过的坑多了之后我最大的体会是固定IP本身不难难的是先理解“虚拟网络”这个中间层。NAT模式下的网关、网段、网络模式每一项都是虚拟机软件虚拟出来的逻辑不能套物理网络的直觉。只要把虚拟网络编辑器里的子网和网关看清楚再按文中的路径配置、重启、验证CentOS的固定IP基本能做到一次成功。如果还是有问题回头把环境信息对照速查表排查多半能在五分钟内找到答案。