1. 先把思路理清:为什么 CentOS7 虚拟机的 IP 值得单独配一次
1.1 三种网络模式决定了你的 IP 该怎么写
在动配置文件之前,得先搞清楚你的 CentOS7 虚拟机在 VMware 里挂的是哪种网络。这一步跳过去,后面改多少次 ifcfg 文件都是白搭,因为网段根本对不上。
VMware 常见的三种模式,对应的写法完全不一样:
- NAT 模式:默认走 VMnet8 这张虚拟网卡,虚拟机和宿主机共享一个出口。网关一般是 xxx.xxx.xxx.2,比如
192.168.100.2。这种模式虚拟机之间、虚拟机到宿主机都能通,宿主机想反向访问虚拟机,直接 ping 它的 IP 就行。大多数做实验的人都用这个。 - 仅主机模式:走 VMnet1,网关通常是 xxx.xxx.xxx.1。虚拟机只能和宿主机通信,出不了外网。适合做隔离实验,比如搭一套内网服务。
- 桥接模式:虚拟机直接借用宿主机所在的物理网段,网关就是你家里或公司路由器那个地址,比如
192.168.1.1。IP 要在物理局域网里挑一个没被占用的,风险是容易和公司网络里其他设备撞车。
我个人的建议是:做日常实验用 NAT,需要模拟真实内网环境再切桥接。选好模式之后,网段就固定了,剩下的配置全在这个网段里打转。
1.2 DHCP 省事,但它会给你制造三种麻烦
默认安装完 CentOS7,网卡一般是BOOTPROTO=dhcp,开机自动拿地址。平时登进去敲两条命令没问题,但只要你想干点正事,它就开始使绊子。
第一种麻烦是地址会变。VMware 的 DHCP 租约到期或者虚拟机重启之后,分到的 IP 可能从192.168.100.128跳到192.168.100.131。你昨天在宿主机上配好的 SSH 连接、数据库连接串、甚至浏览器书签,全都失效。用 Xshell 存了一堆会话的人应该深有体会。
第二种麻烦是端口转发和域名映射做不了。想在宿主机的 hosts 文件里写一条dev.local -> 虚拟机IP,IP 一变就废。想在 VMware 里配 NAT 端口映射,把宿主机的 8080 转到虚拟机的 80,也得先有个固定地址。
第三种麻烦是集群实验直接玩不转。你要是想用两三台虚拟机搭一套主从、集群、分布式环境,每台机器的 IP 都得写进配置文件里互相引用。DHCP 分配的地址今天一个样明天一个样,配置文件里写死的那堆 IP 第二天全部报错。所以只要涉及多机通信,静态 IP 是绕不过去的一道坎。
配静态 IP 这件事本身不难,难的是配完之后各种服务、防火墙、DNS 的行为要一次性理顺。下面按我的实际操作顺序一步步来。
2. 动手前必须拿到的四组信息
2.1 确认虚拟机网络模式与对应网段
打开 VMware,选中你的 CentOS7 虚拟机,右键“设置”,找到“网络适配器”。这里会显示当前用的是 NAT、桥接还是仅主机。记下来。
接着在 VMware 菜单栏点“编辑” -> “虚拟网络编辑器”,点右下角的“更改设置”拿到管理员权限(这一步很多人卡住,按钮是灰的就是没提权)。然后你会在列表里看到 VMnet0、VMnet1、VMnet8 这几张虚拟网卡。
- 用 NAT 就盯住VMnet8那一行,看它的“子网 IP”和“子网掩码”,比如
192.168.100.0 / 255.255.255.0。 - 用仅主机就盯住VMnet1。
- 桥接模式直接看宿主机的物理网卡地址。
网段一旦确定,你的静态 IP 前三位就必须和它一致,只有最后一位可以自己挑。这是新手最常犯的错:网段写错了,网关都 ping 不通,还以为是自己配置文件写错了。
2.2 找出网关地址、可用地址池与 DNS 来源
在刚才那个“虚拟网络编辑器”里,选中 VMnet8,点“NAT 设置”,你会看到网关 IP,通常是192.168.100.2。再点“DHCP 设置”,能看到地址池的起止范围,比如192.168.100.128到192.168.100.254。
这两个信息决定了你能挑哪个 IP:
- 网关地址绝对不能占用。
- 宿主机上 VMnet8 这张虚拟网卡占用的地址也不能用。在 Windows 上开个 cmd 敲
ipconfig,找到“VMware Network Adapter VMnet8”那一项,它的 IPv4 地址就是宿主机在这张网里的身份,一般是192.168.100.1。 - DHCP 池子里的地址虽然理论上能抢,但不建议。最稳妥的是在
192.168.100.10到192.168.100.99之间挑,比如我习惯用192.168.100.20。
DNS 这块,如果虚拟机要上外网,就得填一个可用的 DNS。你可以直接填网关地址(NAT 模式下网关会转发 DNS 请求),也可以填公共 DNS。还有人干脆填宿主机能用的那个运营商 DNS,实测也行,但换网络环境之后容易失效,不如用固定的。
2.3 记下网卡名和 MAC,后面每一步都要用
CentOS7 的网卡命名规则和 CentOS6 不一样,不再是eth0,而是ens33、ens160、enp0s3这种基于硬件位置生成的名字。这个信息只能登进系统里看。
在网络还没配通的情况下,可以用 VMware 的控制台(不是 SSH)先进去,敲:
ip addr或者老一点的命令:
ifconfig -a输出里那段ens33: <BROADCAST,MULTICAST,UP,LOWER_UP>就是网卡名。同时把link/ether后面那串 MAC 地址也抄下来,等会儿核对配置文件里的HWADDR用得上。顺手把宿主机上的ipconfig /all也跑一遍,看 VMnet8 的 MAC 和虚拟机的对不对得上,能提前发现网络适配器挂错的问题。
3. 改配置文件:CentOS7 静态 IP 的标准做法
3.1 定位 /etc/sysconfig/network-scripts/ 下的网卡文件
CentOS7 的网络配置文件都放在这个目录下:
cd /etc/sysconfig/network-scripts/ ls ifcfg-*正常会看到ifcfg-ens33、ifcfg-lo,可能还有个ifcfg-Wired_connection_1之类的东西。认准和网卡名完全一致的那个文件,ifcfg-ens33对应ens33,别改错了。
改之前先备份,这个习惯能省你很多事:
cp ifcfg-ens33 ifcfg-ens33.bak然后开编辑:
vi ifcfg-ens333.2 ifcfg-ens33 逐行拆解:哪些必须改,哪些千万别动
装完系统之后,这个文件大致长这样:
TYPE=Ethernet BOOTPROTO=dhcp DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no NAME=ens33 UUID=8f4a2b1c-3d5e-4f6a-9b8c-7d6e5f4a3b2c DEVICE=ens33 ONBOOT=no逐行说明我实际会怎么改:
| 参数 | 改前 | 改后 | 说明 |
|---|---|---|---|
| BOOTPROTO | dhcp | static | 关键项。也可以写none,效果一样,都是不用 DHCP |
| ONBOOT | no | yes | 不改这个,重启之后网卡根本不启动,最常见的"改了没用"元凶 |
| IPADDR | 无 | 192.168.100.20 | 自己挑的可用地址 |
| PREFIX | 无 | 24 | 等价于 NETMASK=255.255.255.0,二选一,别两个都写 |
| GATEWAY | 无 | 192.168.100.2 | NAT 模式的网关,写错就上不了外网 |
| DNS1 | 无 | 192.168.100.2 | 主 DNS |
| DNS2 | 无 | 114.114.114.114 | 备用 DNS,主挂了能顶上 |
| PEERDNS | 无 | no | 防止 DNS 被覆盖,下面细说 |
| IPV6INIT | yes | no | 纯 IPv4 环境建议关掉,少一堆日志噪音 |
有几行不要动:TYPE=Ethernet、NAME、DEVICE、UUID。UUID 是网卡的唯一标识,删了系统会重新生成一个,有时候会导致 NetworkManager 里出现重复连接项。HWADDR如果本来有,也别删,写了就核对一下是不是和ip addr里看到的一致。
改完之后完整的样子:
TYPE=Ethernet BOOTPROTO=static DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=no NAME=ens33 UUID=8f4a2b1c-3d5e-4f6a-9b8c-7d6e5f4a3b2c DEVICE=ens33 ONBOOT=yes IPADDR=192.168.100.20 PREFIX=24 GATEWAY=192.168.100.2 DNS1=192.168.100.2 DNS2=114.114.114.114 PEERDNS=no注意:
PREFIX和NETMASK同时写的时候,有些版本会以后者为准,有些会报冲突警告。挑一个写就行,我一般用 PREFIX,写起来短。
3.3 重启网络服务与三条验证命令
保存退出(:wq)之后,重启网络服务:
systemctl restart network如果这一步卡住不动或者报Job for network.service failed,先看 3.4 节。没报错的话,敲第一条验证命令:
ip addr show ens33正常应该看到inet 192.168.100.20/24挂在下面。第二条看路由:
ip route输出里应该有这么一行:
default via 192.168.100.2 dev ens33 proto static metric 100有这行说明默认网关生效了。第三条验证连通性:
ping -c 4 192.168.100.2 ping -c 4 114.114.114.114 ping -c 4 www.baidu.com第一条通说明网关可达,第二条通说明外网出得去,第三条通说明 DNS 解析正常。三条全绿,静态 IP 就立住了。
3.4 network 与 NetworkManager 打架时怎么收场
CentOS7 里同时存在network和NetworkManager两套网络管理服务。默认情况下 NetworkManager 是主控,它读的也是同一批 ifcfg 文件,所以两者一般能和平共处。但如果你之前的实验里手动停过其中一个,就会出现"改了配置重启服务没反应"的怪现象。
先看两个服务的状态:
systemctl status network systemctl status NetworkManager我的建议是保留 NetworkManager 开启,用systemctl restart network去触发重载,因为network服务在 CentOS7 里实际上是个兼容层,它会去调用 NetworkManager 的接口。如果两个都开着还是没用,试试这两条:
nmcli connection reload nmcli connection up ens33还不行的话,把 NetworkManager 停掉,只用 network 服务,等配置稳定了再开回来:
systemctl stop NetworkManager systemctl restart network但要记住,一旦停掉 NetworkManager,后面nmcli那些命令就不能用了。这是个取舍问题,单体虚拟机用 network 完全够,做自动化脚本的话还是老实用 NetworkManager。
4. 换一种姿势:用 nmcli 三行命令改静态 IP
4.1 nmcli 改静态 IP 的完整命令与参数说明
如果你懒得开 vi,或者想把这个过程写进自动化脚本,nmcli是更顺手的选择。先看当前有哪些连接:
nmcli connection show输出里会列出NAME、UUID、TYPE、DEVICE几列。找到DEVICE是ens33的那一行,记下它的NAME,比如就叫ens33。
然后一条命令改完地址、网关和 DNS:
nmcli connection modify ens33 \ ipv4.addresses 192.168.100.20/24 \ ipv4.gateway 192.168.100.2 \ ipv4.dns "192.168.100.2 114.114.114.114" \ ipv4.method manual参数对应关系很清楚:ipv4.addresses就是 IPADDR 加 PREFIX,ipv4.gateway就是 GATEWAY,ipv4.dns里多个地址用空格分隔,ipv4.method manual等于BOOTPROTO=static。最后激活一下:
nmcli connection up ens33三行命令搞定,比手动改文件快。而且你回头看ifcfg-ens33,会发现文件已经被同步改好了——因为 NetworkManager 就是把它当成存储后端在维护。
4.2 nmcli 和 ifcfg 文件到底是什么关系
很多人搞不清这两者。简单说,ifcfg-ens33是磁盘上的配置文件,nmcli是操作它的一个前端。你用 nmcli 改,文件会变;你直接改文件再用 nmcli reload,内存里的配置也会跟着变。它们不是两套东西。
但有一个细节要注意:如果你手动在文件里加了一些 nmcli 不认识的键值,nmcli 保存时可能会丢掉它们。所以要么全程用 nmcli,要么全程用 vi,别混着来。我自己的习惯是——单机调试用 vi,看着直观;要批量给十几台机器配 IP 就写个脚本调 nmcli,速度快还不容易手滑。
另外,用 nmcli 改完记得看一眼有没有生成多余的连接项:
nmcli connection show --active有时候系统里会残留一个Wired connection 1,它和ens33抢同一个设备,导致你改的配置不生效。直接删掉多余的那个:
nmcli connection delete "Wired connection 1"5. 踩坑实录:静态 IP 配完之后常见的七个问题
5.1 重启之后 IP 又变回自动获取
这是被问得最多的一条。现象是:改完配置文件当时生效了,reboot之后一查,ip addr显示的还是 DHCP 那个地址。
原因通常有三个:
第一,ONBOOT=no没改。网卡开机不自动起来,系统走的是 NetworkManager 的默认策略,重新分配了一个 DHCP 地址。
第二,BOOTPROTO拼错了。写成staitc、STATIC、Static都不行,必须是小写static或者none。这个坑隐蔽在于服务重启不会报错,只是当作没配置处理,静默回到 DHCP。
第三,存在第二个配置文件。比如你之前用图形界面配过一次,系统里多了个ifcfg-Wired_connection_1,它和ifcfg-ens33同时作用于同一张网卡,最后谁生效看加载顺序。解决办法是ls ifcfg-*全看一遍,把多余的删掉或者改名加个.bak后缀。
排查顺序我一般是这样:先看ONBOOT,再看BOOTPROTO,最后翻目录里有没有多余的 ifcfg 文件。三步能解决九成情况。
5.2 IP 能 ping 通,域名解析却失败
ping 114.114.114.114通,ping www.baidu.com报unknown host,这就是纯 DNS 问题。先看当前用的 DNS:
cat /etc/resolv.conf如果里面的nameserver不是你配的,或者干脆是空的,问题就出在PEERDNS上。这个参数默认是yes,含义是"允许 DHCP 服务器下发的 DNS 覆盖本地配置"。哪怕你设了静态 IP,只要PEERDNS=yes,重启网络之后系统还是可能按旧规则把/etc/resolv.conf重写一遍。
所以静态 IP 场景下,PEERDNS=no一定要加上。加上之后/etc/resolv.conf里的内容就会以你在 ifcfg 里写的DNS1、DNS2为准,不会被覆盖。
还有一种情况是/etc/resolv.conf被别的服务接管了,比如装了某些网络管理工具。可以用ls -l /etc/resolv.conf看看它是不是个软链接,指向别处。真是软链接的话,就得去改那个源文件。
5.3 主机 ping 不通虚拟机,或虚拟机连不上外网
这两个方向的问题,原因不同,分开排查。
宿主机 ping 不通虚拟机:先在虚拟机里ping宿主机的 VMnet8 地址(比如192.168.100.1)。通说明网络层没问题,是宿主机侧的防火墙拦了 ICMP。Windows 防火墙默认会拦入站 ICMP,去高级防火墙里放行"文件和打印机共享(回显请求)"那条规则就行。不通的话,回头检查 VMware 的网络适配器是不是被设成了"仅主机"而你以为在 NAT。
虚拟机连不上外网:ping网关通不通?通的话,ping一个公网 IP(比如114.114.114.114)。这一步通说明路由和 NAT 都正常,问题在 DNS,回到 5.2。这一步不通,说明 NAT 转发没工作,去虚拟网络编辑器里把 VMnet8 的"NAT 设置"重新确认一遍,特别是"将主机虚拟适配器连接到此网络"那个勾有没有被打掉。
5.4 克隆虚拟机后网络直接起不来
克隆出来的虚拟机,MAC 地址变了,但配置文件里的HWADDR和UUID还是原来那台的。系统启动时发现硬件对不上,网卡就起不来,报Device ens33 does not seem to be present。
处理办法是:把克隆机的ifcfg-ens33里的HWADDR那一行删掉(或者改成新 MAC),UUID也删掉让它重新生成。然后清一下 udev 的网络规则文件:
rm -f /etc/udev/rules.d/70-persistent-net.rulesCentOS7 里这个文件可能不存在,不存在就不用管。重启网络服务,一般就恢复了。
另外提醒一句,克隆之后新机器的静态 IP 必须改。两台机器同一个 IP 在同一个网段里,会出现时通时不通的诡异现象,比完全不通更难排查。我习惯给每台虚拟机在命名上做个编号,centos-node1、centos-node2,IP 尾号也跟着 21、22 走,一眼就能看出有没有撞车。
5.5 网卡名和配置文件名对不上
有时候你会看到ip addr显示网卡叫ens33,但/etc/sysconfig/network-scripts/里只有ifcfg-eth0。这种情况多半是系统装的时候用了不同的网卡命名策略,或者你手动改过 grub 参数。
最简单的做法是按网卡名重新建一个配置文件:
cp ifcfg-eth0 ifcfg-ens33 vi ifcfg-ens33 # 把 DEVICE 和 NAME 都改成 ens33 nmcli connection reload systemctl restart network不建议反过来去改网卡名,那需要动 udev 规则和 grub 的net.ifnames=0参数,改动面太大,容易引出别的问题。顺着系统来,成本最低。
为了方便对照,我把上面这些坑整理成一张速查表:
| 现象 | 高概率原因 | 快速处理 |
|---|---|---|
| 重启后 IP 变回 DHCP | ONBOOT=no / BOOTPROTO 拼错 / 多余配置文件 | 逐项核对,删冗余 ifcfg |
| IP 通但域名不通 | PEERDNS=yes 覆盖了 resolv.conf | 加 PEERDNS=no,手写 DNS |
| 宿主机 ping 不通虚拟机 | 宿主机防火墙拦 ICMP | 放行回显请求规则 |
| 虚拟机上不了外网 | 网关写错 / NAT 未启用 | 核对网关,检查 NAT 设置 |
| 服务重启失败 | network 与 NetworkManager 冲突 | nmcli reload 或停用其一 |
| 克隆后网卡起不来 | HWADDR、UUID 未更新 | 删掉这两行,清 udev 规则 |
| 时通时不通 | IP 地址冲突 | 全段扫描,改用未占用地址 |
6. 让这套配置更耐用的几个习惯
6.1 给虚拟机做一份"网络信息台账"
配一次静态 IP 不难,难的是三个月后你自己都记不清哪台机器用了哪个地址。我现在的做法是在宿主机上放一个 Markdown 小文件,每加一台虚拟机就记一行:机器名、网卡模式、IP、网关、用途、创建日期。
centos-node1 | NAT/VMnet8 | 192.168.100.21 | 192.168.100.2 | 实验主节点 | 2024-03-05 centos-node2 | NAT/VMnet8 | 192.168.100.22 | 192.168.100.2 | 从节点 | 2024-03-05 centos-db | NAT/VMnet8 | 192.168.100.30 | 192.168.100.2 | 数据库实验 | 2024-03-07看起来多余,但当你手上同时跑着七八台虚拟机的时候,这份台账能让你省下大量"这台到底是几号"的翻找时间。IP 冲突也能一眼看出来。
6.2 防火墙与 SELinux:主机访问虚拟机网站的最后一公里
很多人的静态 IP 配得完全正确,ping也通,但宿主机浏览器就是打不开虚拟机上跑的服务。这时候问题已经不在 IP 层了,在防火墙。
CentOS7 默认开着firewalld。想放行 80 端口:
firewall-cmd --permanent --add-port=80/tcp firewall-cmd --reload firewall-cmd --list-portsSELinux 也可能插一脚。用getenforce看状态,如果是Enforcing而你又不想花时间写策略,可以临时切到Permissive验证一下是不是它的问题:
setenforce 0确认是 SELinux 拦的,再去研究对应的布尔值或者上下文规则,别一上来就永久关闭,那样虽然省事但把安全底座拆了。
6.3 从 CentOS7 迁移到 Rocky Linux / openEuler 时的差异点
CentOS7 已经停止维护了,新项目我基本都往 Rocky Linux 或者 openEuler 上迁。好消息是网络配置的思路几乎没变,ifcfg文件那套写法在 Rocky Linux 8/9 上照样能用,只是默认主控全面转向了 NetworkManager,systemctl restart network这条命令在 Rocky 9 上已经不存在了,得改用:
nmcli connection reload nmcli connection up ens33openEuler 的情况类似,同样是 NetworkManager 主导,配置文件路径和键名基本兼容。所以你现在花时间把nmcli这套命令练熟,将来换发行版的时候几乎零成本。反过来,如果只依赖 vi 改 ifcfg 再systemctl restart network,迁移的时候就会卡在"服务不存在"这一步上。
我个人在实际操作中的体会是,静态 IP 这件事真正花时间的从来不是改那几行配置,而是搞明白你的虚拟机到底挂在哪个网段、网关是谁、DNS 走哪儿。这三件事在动手之前用五分钟确认清楚,后面五分钟就能配完;省了这五分钟,后面可能要在"为什么上不了网"这个问题上耗掉一整个下午。另外一个小技巧是,第一次配的时候把ifcfg-ens33的备份文件留好,万一手抖改错了,cp ifcfg-ens33.bak ifcfg-ens33加上nmcli connection reload,十秒钟就能回到能上网的状态,比一点点往回改快得多。