搞 Linux 运维这些年,网络配置大概是新手最容易翻车、老手也偶尔头疼的一块。最常见的两个操作方式,一个是敲 nmcli 命令让 NetworkManager 干活,另一个是直接编辑 /etc/sysconfig/network-scripts/ 下面的 ifcfg-* 网卡配置文件。两条路都能实现静态 IP、DNS、网关这些基础配置,但如果搞不清它们之间的关联和边界,就会出现“配置文件改了不生效”“nmcli 一执行又把手动配置覆盖了”这种连锁问题。这篇文章就用一台接入了业务网段的服务器当例子,把 nmcli 常用命令和 ifcfg-* 配置文件的每个参数都拆开讲清楚,最后附上一套我实际在用的配置脚本,供你直接参考或改成自己的工具。适合刚接触 Linux 网络配置的同学,也适合需要批量初始化服务器的运维老手。
1. 开局先搞清楚:nmcli 和 ifcfg-* 到底负责什么
1.1 NetworkManager 的定位
现代 Linux 发行版基本都会默认装 NetworkManager,你可以把它理解成系统的“网络管家”。它常驻后台,负责监听网卡热插拔、扫描无线网络、维护连接配置、按优先级自动连接,还能处理多块物理网卡和虚拟网桥这类复杂拓扑。nmcli 就是这个管家对外提供的命令行对讲机,所有管理动作都可以通过它下发,而且支持 Tab 补全,远程 SSH 操作也比开图形界面方便得多。
很多新手分不清 NetworkManager 和 systemd-networkd 或者 netplan 这套体系。我先把适用边界说清楚:本文讲的是用 NetworkManager 托管网络的方式,它在 RHEL/CentOS 这类基于 RPM 的发行版里完全是默认主力,在 Debian/Ubuntu 上也常见,只是配置文件路径会不同。Debian 系没有 ifcfg-* 这套东西,用的是 /etc/network/interfaces 或 netplan 的 yaml。这篇文章的配置示例全部围绕 ifcfg-* 展开,适用对象是 RHEL/CentOS 等保留传统网络脚本体系的发行版。
检查 NetworkManager 是否在跑,最简单的是 systemctl status NetworkManager。如果服务是 active (running),那么你用 nmcli 操作是顺理成章的;如果服务被停了、被 mask 了,那 nmcli 基本就是空壳,只能靠手改配置文件再配合传统 ifup/ifdown 来救急。
1.2 手动修改配置文件是怎么回事
手动修改网卡配置文件,改的是 /etc/sysconfig/network-scripts/ 目录下的 ifcfg-* 文件,每一块网卡对应一个文件,命名一般是 ifcfg-eth0、ifcfg-enp2s0 这样。用传统眼光看,这些文件就是系统网络的“账本”,写着这块网卡开机要不要自动起来、用 DHCP 还是固定 IP、网关和 DNS 是谁。
问题就出在 NetworkManager 也有自己的一份“账本”。NetworkManager 启动的时候会扫描 ifcfg-* 目录,把这些文件读进自己的连接配置库,之后如果你用 nmcli 改了配置,NetworkManager 也会把结果回写到对应文件。所以严格来说,ifcfg-* 文件是 NetworkManager 的后端存储之一,手改文件等于直接改数据库文件,但不等于数据库立即刷新。
这个机制解释了后面所有坑的来源:改了文件不通知 NetworkManager,它可能还拿缓存的老配置在跑;用 nmcli 改了连接,ifcfg 文件却有可能被回写成新格式,让你觉得自己改的东西“凭空消失”。
1.3 为什么两条路都要会
既然 nmcli 这么方便,为什么还要学手改文件?我自己的体会是:第一,不是所有服务器都跑着完好的 NetworkManager,系统启动早期、服务损坏、网络服务起不来的场景,命令行工具不响应时,你唯一能依靠的就是文件系统里那几个文件。第二,排查问题的时候,看文件往往比敲一串命令更直观,一个 ifcfg-* 文件里 IP、掩码、网关、DNS 一目了然,比你挨个 nmcli connection show 去翻字段要快得多。第三,存量系统里,很多人就是直接改文件的,如果不懂文件格式,看到别人留下的配置会非常被动。
所以正确姿势不是二选一,而是两手都熟:平时用 nmcli 做批量操作,出问题或者需要精确控制细节时,直接打开配置文件。
2. nmcli 实战:命令行把网络配置玩明白
2.1 先看家底:查询命令三件套
动手改之前,最重要的一步是看清现状。我每次登上一台新服务器,先跑三条命令:
# 查看 NetworkManager 全局状态 nmcli general status # 查看所有连接(connection,也就是已保存的配置) nmcli connection show # 查看物理网卡和激活状态 nmcli device statusnmcli general status 的输出有 STATE 和 CONNECTIVITY,STATE 是 connected 说明整体网络在管;CONNECTIVITY 是 full 说明网络可达性正常,显示 limited 说明有物理链路但可能没有拿到有效配置。
nmcli device status 是判断物理设备状态最快的方式,DEVICE 列是接口名,TYPE 能看到这块卡是 ethernet、bridge 还是 bond,STATE 是 connected 还是 disconnected,CONNECTION 列告诉你当前激活用的是哪一份配置。很多“网卡明明存在但死活不上网”的问题,在这一步就能定位:如果 STATE 是 unmanaged,说明 NetworkManager 压根没管理这块卡,后面所有 nmcli 操作对它都是无效的。
查看连接细节用nmcli connection show <连接名>,不加连接名就列出全部。连接名和接口名是两个概念,前者是 NetworkManager 内部配置的标识,后者是内核里的网卡名,可以不一样,后面新建连接的时候要注意别混淆。
2.2 新建一个静态 IP 连接:从命令到生效
给一块网卡配置固定 IP,用 nmcli 只需要一条命令。假设服务器上有一块叫 eth0 的网卡,要配成 192.168.10.100/24,网关 192.168.10.1,DNS 用公共解析服务:
nmcli connection add type ethernet con-name eth0-office ifname eth0 \ ipv4.addresses 192.168.10.100/24 \ ipv4.gateway 192.168.10.1 \ ipv4.dns "223.5.5.5 8.8.8.8" \ ipv4.method manual拆开看每个参数:
- type ethernet 表示这是一个以太网类型的连接。
- con-name 是连接名,自己起,带业务含义更好记,比如 eth0-office。
- ifname 是绑定到哪块物理网卡,这个必须和系统里的接口名一致。
- ipv4.addresses 是 IP 和掩码,写成“IP/前缀”形式,/24 就是 255.255.255.0,不用再单独给掩码。
- ipv4.gateway 是默认网关。注意如果服务器本身是多网卡多路由的,这个值要谨慎,加了它就是默认路由的下一跳。
- ipv4.dns 是 DNS 服务器,多个之间用空格隔开,整个值用引号包起来。
- ipv4.method manual 表示不用 DHCP,固定 IP。
命令执行成功后,系统里会多出一个连接,但没有立即生效,必须再激活一下:
nmcli connection up eth0-office这一步会让网络配置重新应用。如果服务器上这块网卡是当前 SSH 的通道,会有极短暂的断流,我后面会专门讲这个坑。激活后可以用ip addr show eth0确认地址是否生效。
注意:当这块网卡是当前远程会话的唯一通道时,执行 connection up 前最好确认自己还有带外管理入口,或者接受几秒的抖动,不要同时叠加多个 modify 操作,减少断流时间。
2.3 修改与删除连接:别怕,命令是可逆的
配错了不要慌,nmcli 修改是声明式的,执行一次就会覆盖旧值:
# 修改 IP nmcli connection modify eth0-office ipv4.addresses 192.168.10.101/24 # 修改网关 nmcli connection modify eth0-office ipv4.gateway 192.168.10.254 # 追加 DNS nmcli connection modify eth0-office ipv4.dns "223.5.5.5 8.8.8.8" # 修改后重新加载配置 nmcli connection up eth0-office有一点要特别提醒:modify 只是改“保存的配置”,不等于立刻生效到网卡上,必须 connection up 或 device reapply。另外,ipv4.addresses 支持多个地址,比如"192.168.10.100/24 10.0.0.5/16",适合一张网卡挂多个网段的场景,但默认网关始终只有一个,多 IP 场景下不要试图给每个 IP 都配网关。
删除连接更简单:
nmcli connection delete eth0-office删除后这块网卡如果还插着网线,NetworkManager 可能会自动为它创建一个 DHCP 连接,所以不要指望删了连接就“干净了”。要真正严格管控,需要配合 autoconnect 参数和连接的默认行为来控制。
2.4 让配置立即生效:up / reapply / reload 的区别
很多教程把这三个命令混着说,我实际上手后的理解是:
- nmcli connection up <连接名>:把某个连接激活。适合从一堆连接里切到指定连接,断连和重连的过程比较明确。
- nmcli device reapply <接口名>:让 NetworkManager 把当前配置重新应用给一块网卡,网络中断时间更短,适合只改了几个参数的热更新。
- nmcli connection reload:让 NetworkManager 重新扫描配置文件并刷新内部连接库。注意它只重读文件,不会重新激活任何连接,改完文件不跑这一步,NetworkManager 可能还在用旧的。
实际操作中,我最常用的组合是 modify 之后直接 connection up;改完 ifcfg 文件之后先 reload 再 up。reapply 偶尔用,因为它只看当前已激活的连接,多连接切换时容易产生误解。
还有 autoconnect 这个参数很容易被忽略。新建连接时默认 autoconnect yes,意味着开机后 NetworkManager 会自动激活它。如果同接口下存在多个连接,靠 autoconnect 优先级排序,优先级高的先启动。要避免“开机后 IP 和自己想的不一样”,最好把不用的连接删干净,或者显式设置高优先级连接。
2.5 我的 nmcli 使用习惯
经验上总结几条:
- 连接名一定要有语义。static-eth0、eth0-office 这种名字,半年后回来看还能一眼看懂,比默认生成的 Wired connection 1 强太多。
- 一个接口只留一个连接。多连接并存是绝大多数幽灵问题的来源,除非你刻意做故障切换,否则请保持“一接口一连接”。
- 改远程服务器前,先判断这块网卡是不是自己 SSH 所在的通道。如果是,优先用 connection up 配合超时窗口操作,或者干脆在带外管理口执行。
- 每次执行修改后,用 ip addr show 和 ip route 验证,不要相信“命令没报错就等于成功”。
3. 手动改配置文件:ifcfg-* 的完整拆解
3.1 配置文件在哪、怎么命名、怎么备份
ifcfg-* 文件默认都在 /etc/sysconfig/network-scripts/ 目录下。命名规律是 ifcfg- 加接口名,例如 ifcfg-eth0、ifcfg-enp2s0。有些发行版里网卡名是 eno1、ens33 这种,不要凭印象猜名字,用 ip link 或者 nmcli device status 确认后再找对应文件。
修改前第一件事永远是备份,这是我踩过无数次坑后养成的习惯:
cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0.bak.$(date +%F-%T)备份文件注意保留 .bak 后缀,NetworkManager 默认不加载 .bak 后缀文件,不会干扰正常配置。强烈不建议用 ifcfg-eth0.bak 之外的隐藏方式备份,比如放 /tmp 下,系统一重启就找不到,排障时非常被动。
权限方面,配置文件保持 root:root、644 即可,NetworkManager 以 root 身份读取,普通用户不需要也不应该能修改。
3.2 一个静态 IP 配置文件的逐行解读
拿一个最小但完整的静态配置做样本:
TYPE=Ethernet BOOTPROTO=none DEFROUTE=yes NAME=eth0-office DEVICE=eth0 ONBOOT=yes IPADDR=192.168.10.100 PREFIX=24 GATEWAY=192.168.10.1 DNS1=223.5.5.5 DNS2=8.8.8.8 PEERDNS=yes NM_CONTROLLED=yes USERCTL=no逐行拆:
- TYPE=Ethernet:接口类型,普通有线网卡写 Ethernet。
- BOOTPROTO=none:IP 获取方式,none 和 static 都表示静态,DHCP 场景写 dhcp。这是文件里最关键的字段之一。
- DEFROUTE=yes:是否把这条连接的路由作为默认路由。多网卡场景如果要固定默认出口,这里要留意。
- NAME 和 DEVICE:NAME 是 NetworkManager 里的连接名,DEVICE 是内核网卡名。NAME 可以自定义,DEVICE 必须和接口名一致。
- ONBOOT=yes:开机是否自动启用这块网卡。很多“配置了 IP 但重启后就没了”的问题,根源就是 ONBOOT=no。
- IPADDR、PREFIX、GATEWAY:固定 IP、前缀长度、网关。PREFIX=24 等价于 NETMASK=255.255.255.0,推荐用 PREFIX 写法,少一个字段更直观。
- DNS1/DNS2:主备 DNS。注意这里的写法是 DNS1=,不是 DNS=。
- PEERDNS=yes:是否允许 DHCP 下发的 DNS 覆盖 /etc/resolv.conf。静态配置场景一般保持 yes,这样 NetworkManager 会把 DNS1/DNS2 写入 resolv.conf。
- NM_CONTROLLED=yes:这块网卡是否接受 NetworkManager 管理。设成 no 等于告诉管家“这儿不用你管”,此时 nmcli 对它完全不生效。
- USERCTL=no:是否允许普通用户通过工具启停网卡,出于安全考虑一律 no。
除此之外,临时文件里还可能看到 UUID、HWADDR、IPV6ADDR 等字段。UUID 是 NetworkManager 自动生成的连接标识,手写也最好别乱编;HWADDR 绑定网卡 MAC,用于防止接口名漂移;IPV6ADDR 是 IPv6 地址,不需要时建议显式把 IPV6INIT=no 或者 ipv6.method disabled,避免解析过程被 IPv6 拖慢。
3.3 配置生效的三种方式:别只会 systemctl restart
手动改完文件后,让新配置生效有几种方式,效果和风险差别很大。
第一,重启整个 NetworkManager 服务:
systemctl restart NetworkManager这个方式最粗暴,它会重新扫描全部配置文件、断开所有由它管理的连接再重新连接,所以短暂断网无法避免。如果这块网卡是你远程登录服务器的唯一通道,强烈不建议在生产环境 remote 执行,很容易把自己踢下线。
第二,先刷新配置库再激活指定连接:
nmcli connection reload nmcli connection up eth0-officereload 让 NetworkManager 重新读一遍 ifcfg-* 文件,up 再激活目标连接。相比重启服务,这个方案只影响你指定的连接,对其他网卡和连接不会产生干扰,是我在远程维护时的首选。
第三,使用传统命令 ifup/ifdown:
ifdown eth0 ifup eth0在旧系统上这很常见,但 NetworkManager 完全接管后,ifup/ifdown 不一定按你预期工作。我建议把它当成“网络服务已不可用时的最后手段”,日常别依赖它。
3.4 手改文件与 nmcli 混用时的冲突与避坑
混用两种方式最典型的坑有三个。
第一个坑:改了文件不 reload。NetworkManager 启动后已经把配置缓存进自己的连接库,你手工改文件时它并不知道,必须 reload 或重启服务让它重新读。我见过同事改完 ifcfg-eth0 后直接 systemctl restart NetworkManager 才生效,其实是重启服务顺带做了 reload,并不是文件改动“即时生效”。
第二个坑:nmcli 修改后,ifcfg 文件被回写成新格式。NetworkManager 有自己的回写逻辑,你用 nmcli 修改连接后,它会把结果写回 ifcfg-* 文件,可能重新排序、补充 UUID、改写字段,这是正常现象。不要觉得“我没动文件,怎么文件变了”。
第三个坑:NM_CONTROLLED=no。这个值设成 no 后,NetworkManager 会认为该接口不归自己管,nmcli 查不到、也改不了。想恢复管理权,得手工把 NM_CONTROLLED 改回 yes,然后重启服务。所以正常情况下不要设 no,除非你已经确认要走纯手工管理路线。
提示:较新版本的 RHEL 系发行版已经在弱化 ifcfg 文件,NetworkManager 转向了 keyfile 格式,存放在 /etc/NetworkManager/system-connections/。ifcfg 这套体系还能用,但未来新系统上默认生成的可能是 keyfile。到那时候,手动改文件的目标目录就不是 network-scripts,而是 system-connections。
4. 方案选型与经验:什么时候用 nmcli,什么时候手改文件
4.1 静态 IP 还是 DHCP:先想清楚需求
在动手配置之前,先想明白这块网卡到底要什么形态。物理服务器通常需要固定 IP,因为业务方、监控系统、防火墙规则都基于 IP 做白名单,IP 一变等于地址漂移。虚拟机或者笔记本则更适合 DHCP,网络环境一变就能自动适配。
如果选静态,还需要确定掩码/前缀。这个别凭感觉写,先问网管要准确的网段规划。比如业务网段是 192.168.10.0/24,你配置 192.168.10.100/24 没问题;如果实际是 192.168.0.0/22 的一个部分,写成 /24 就可能导致跨网段访问异常。
多 IP 场景也要在阶段就定好。一张网卡配置多个 IP 是可以的,但务必想清楚默认路由从哪个 IP 走出去。我在实践中建议:业务需要几个网段的地址,尽量用独立的物理接口或做网络聚合拆分,不要把所有地址都堆在同一块网卡上,排障时不同业务的流量混在一起会非常难查。
4.2 什么场景优先用 nmcli,什么场景手改文件
我的选择逻辑很简单:
- 如果 NetworkManager 在正常运行,能用 nmcli 就用 nmcli。命令自带校验和回写逻辑,比手改文件安全得多,还方便批量执行和脚本化。
- 如果 NetworkManager 挂了、被禁用,或者你连不上命令行工具,手改文件是你唯一的选择。
- 如果是排障,优先看文件,因为文件是持久状态,命令输出是瞬时的,结合两者才能快速定位。
远程操作时,我特别推荐 nmcli。它允许你先 modify 保存配置,再选择合适时机 connection up,把断网窗口控制住。手改文件虽然也可以,但改完总要 reload/up,效果其实一样,反而多了一步文件格式风险。
4.3 IPv4/IPv6 双栈配置要点
现在很多系统默认 IPv4 和 IPv6 一起开,如果业务不需要 IPv6,建议明确关闭,或者至少配置成 ignore。否则系统会花时间做 IPv6 地址解析、邻居发现,偶尔会出现“DNS 解析很慢”的错觉。
用 nmcli 关闭 IPv6 很简单:
nmcli connection modify eth0-office ipv6.method disabled手改文件的话,在 ifcfg-* 里写 IPV6INIT=no。注意,这只是 NetworkManager 层面的配置,内核是否加载 IPv6 模块是另一个维度,不过对绝大多数服务器和物理机而言,关掉连接级 IPv6 就够用了。
如果需要配置静态 IPv6,nmcli 里对应 ipv6.addresses 和 ipv6.gateway,文件里则用 IPV6ADDR 和 IPV6_DEFAULTGW。IPv6 的参数较多,新手建议先按双栈默认走,让自动配置获取地址,等理解清楚再上静态。
5. 附:可以直接抄作业的网卡配置脚本(学习参考)
5.1 脚本设计思路
这部分是我实际工作中沉淀下来的一个小工具。设计目标有三个:
- 参数化:不写死任何接口名或 IP,执行时通过命令行参数传入,方便复用。
- 幂等:同一台机器可以反复执行,第二次执行会把旧连接清理掉再重建,不会越跑越乱。
- 可感知:所有关键操作都输出提示,执行前能知道它要删什么、建什么。
脚本核心依赖是 nmcli,所以它默认要求 NetworkManager 运行正常。特殊环境下需要手改文件的话,脚本里也保留了一个扩展思路,可以自行改造使用。
5.2 完整脚本
直接贴在下面,每段都有注释。这个脚本我建议你先在自己的测试虚拟机里跑一轮,再考虑是否上生产。
#!/usr/bin/env bash # config_net.sh # 功能:通过 nmcli 为物理网卡配置静态 IP # 用法:./config_net.sh -i <接口名> -a <IP/掩码> [-g <网关>] [-d <DNS1,DNS2>] [-n <连接名>] set -euo pipefail usage() { cat <<'EOF' 用法: ./config_net.sh -i eth0 -a 192.168.10.100/24 -g 192.168.10.1 -d 223.5.5.5,8.8.8.8 参数: -i 网卡接口名,必须存在 -a IP 地址和前缀,例如 192.168.10.100/24 -g 网关 IP -d DNS 服务器,多个用逗号分隔 -n 连接名,默认为 static-<接口名> EOF exit 1 } IFACE="" ADDR="" GATEWAY="" DNS="" CONNAME="" while getopts "i:a:g:d:n:" opt; do case "$opt" in i) IFACE="$OPTARG" ;; a) ADDR="$OPTARG" ;; g) GATEWAY="$OPTARG" ;; d) DNS="$OPTARG" ;; n) CONNAME="$OPTARG" ;; *) usage ;; esac done [ -z "$IFACE" ] && { echo "错误:缺少 -i 参数"; usage; } [ -z "$ADDR" ] && { echo "错误:缺少 -a 参数"; usage; } [ -z "$CONNAME" ] && CONNAME="static-${IFACE}" if [ "$(id -u)" -ne 0 ]; then echo "错误:请使用 root 执行本脚本" >&2 exit 1 fi if ! ip link show "$IFACE" >/dev/null 2>&1; then echo "错误:接口 $IFACE 不存在" >&2 exit 1 fi # 删除该接口上已有的 NetworkManager 连接,保证脚本可重复执行 OLD_CON="$(nmcli -t -f NAME,DEVICE connection show 2>/dev/null | awk -F: -v dev="$IFACE" '$2==dev {print $1; exit}')" if [ -n "$OLD_CON" ]; then echo "发现接口 $IFACE 下已有连接 $OLD_CON,先删除..." nmcli connection delete "$OLD_CON" fi ARGS=( connection add type ethernet con-name "$CONNAME" ifname "$IFACE" ipv4.addresses "$ADDR" ipv4.method manual ) if [ -n "$GATEWAY" ]; then ARGS+=(ipv4.gateway "$GATEWAY") fi if [ -n "$DNS" ]; then # 把逗号分隔转成空格分隔 ARGS+=(ipv4.dns "${DNS//,/ }") ARGS+=(ipv4.ignore-auto-dns yes) fi echo "创建连接 $CONNAME ..." nmcli "${ARGS[@]}" echo "激活连接 $CONNAME ..." nmcli connection up "$CONNAME" >/dev/null echo "配置完成,验证如下:" ip -4 addr show "$IFACE" ip route show5.3 脚本用法示例和关键点说明
执行前先确认参数格式:
./config_net.sh -i eth0 -a 192.168.10.100/24 -g 192.168.10.1 -d 223.5.5.5,8.8.8.8脚本会先打印发现旧连接并删除,然后创建 static-eth0,最后激活并打印 IP 和路由。如果脚本只是在测试环境跑,可以注释掉 nmcli connection delete 那段,观察一下效果再放开。
脚本里两个细节值得说明:第一,ARGS 用数组而不是 eval 拼接字符串,因为有些值里可能包含特殊字符,数组传参能避免 shell 二次解析出问题。第二,awk 按冒号分隔,前提是连接名不要带冒号,自己起名时避开这个字符。如果系统里已经有连接名带冒号,脚本会解析错误,手工处理一下就行。
还有一个补充思路:如果不想用 nmcli 而是直接写 ifcfg,脚本中间那段可以替换成 heredoc 写文件,格式参考第 3.2 节那个样本,写完再 nmcli connection reload。我之所以主推 nmcli,是因为它在回写、校验、多连接管理上更省心。
5.4 脚本的边界
这个脚本不是万能的。它只处理单块物理网卡、单静态 IP 的场景,不处理聚合链路、虚拟局域网、网桥这类虚拟接口,也不负责修改主机名和路由表。生产环境里网络拓扑往往复杂得多,用之前一定要结合自己的网段规划调整。
还有一点,执行脚本的过程中会删除旧连接,如果这块网卡是当前远程会话的通道,删除激活的瞬间可能断流。稳妥做法是在带外管理终端上执行,或者接受几秒的网络抖动,不要开着长任务在脚本执行期间跑。
6. 常见问题与排查实录
6.1 排查速查表
我把日常排障的高频问题整理成一张表,覆盖症状、可能原因和解决动作。
| 症状 | 可能原因 | 排查命令 | 解决动作 |
|---|---|---|---|
| 配置了 IP 但网卡没地址 | 连接未激活或 ONBOOT=no | nmcli device status | connection up / 检查 ONBOOT |
| 改完配置文件不生效 | 没有 reload,NetworkManager 还在用缓存 | nmcli connection show | reload 后 connection up |
| 重启后 IP 不是我想的 | 同接口存在多个连接,自动连接按优先级激活了错误配置 | nmcli -g NAME,DEVICE connection show | 删除多余连接,只保留一份 |
| 能 ping 通网关但解析不了域名 | DNS 配置缺失或 resolv.conf 被覆盖 | cat /etc/resolv.conf | 检查 ipv4.dns / DNS1/DNS2 |
| 网关 ping 不通 | 默认路由缺失或错误 | ip route show | 检查 GATEWAY / ipv4.gateway |
| nmcli 查不到某块网卡 | NM_CONTROLLED=no 或 NetworkManager 未运行 | systemctl status NetworkManager | 手工改回 yes 并重启服务 |
| 改了连接后,ifcfg 文件里内容丢了 | NetworkManager 回写覆盖,这是正常机制 | 对比备份 | 把关键参数重新补到连接里 |
这张表不是标准文档,是我在真实环境里撞过的问题汇总。遇到新问题时先跑查询命令收集事实,再动手改配置,能少走很多弯路。
6.2 我踩过的几个坑
第一个坑是远程重启 NetworkManager。有一次我在客户的服务器上改完静态路由,图省事直接 systemctl restart NetworkManager,结果 SSH 瞬间断开,我只能在机房控制台前收尾。从那以后,凡是远程操作,我只会用 nmcli connection up 或者 device reapply,绝不在生产远程机上重启网络服务。就算必须重启,也会先写一条完整的回滚命令,放在同一个终端里备着。
第二个坑是手改文件忘记 reload。有一台机器的 DNS 解析一直不对,我看配置文件里 DNS1 明明写好了,但 resolv.conf 里就是旧值。排查半天才发现,文件是我上周改的,但 NetworkManager 一直没重新加载,等于我一直在对着一个“没生效”的文件自嗨。那次之后,我给自己定了个规矩:每次手改配置文件,改完立刻 reload,并在命令后马上用 ip 或 resolvectl 验证结果。
第三个坑是多连接污染。某台服务器开机后总拿到一个陌生的 IP,后来用 nmcli connection show 一看,这块网卡下竟然有 4 个历史连接,自动连接优先级把旧配置激活了。清理过程很简单,把所有旧连接 delete 掉只保留最新的,问题立刻消失。我现在的习惯是:新配置服务器时,先清空该接口的既有连接,再造新的。
第四个坑是 NM_CONTROLLED=no 的隐形隔离。有次排查一块网卡为什么 nmcli 看不到,发现配置文件里不知何时被写上 NM_CONTROLLED=no,NetworkManager 直接把它当成“外部设备”不管了。改回 yes 并重启服务后一切正常。现在的教训是:别轻易写这个字段,除非你明确要走完全脱离 NetworkManager 的管理路线。
关于脚本和配置文件的组合使用,我最后再补充一个心得:无论你用哪种方式,配置完成后一定要做验证,而且要验证的是“当下生效值”,不是“配置文件里的值”。网络排障最忌讳的,就是通过一个早就失效的缓存去推断现状。先查、再改、最后验,这套流程走下来,大部分网络问题都能在几分钟内收敛。