问题概述
在CentOS 8.2系统中,管理员经常遇到这样的困扰:手动修改/etc/resolv.conf文件配置DNS服务器后,一旦重启NetworkManager服务,配置就被覆盖回原样。更令人困惑的是,在多IP地址配置场景下(如ifcfg-br10中同时配置IPADDR和IPADDR1),DNS设置似乎与特定IP的网关地址相关联。本文将深入剖析这一现象背后的机制,并提供多种解决方案。
一、NetworkManager在CentOS 8中的角色演变
1.1 历史背景
在CentOS 7及早期版本中,网络配置主要由/etc/sysconfig/network-scripts/目录下的ifcfg-*文件管理。然而,从CentOS 8/RHEL 8开始,虽然仍支持传统的ifcfg格式,但NetworkManager已成为默认且推荐的网络管理工具。
1.2 NetworkManager的工作模式
bash
# 查看NetworkManager状态
systemctl status NetworkManager
# NetworkManager主要管理以下配置:
# 1. /etc/NetworkManager/NetworkManager.conf
# 2. /etc/NetworkManager/system-connections/
# 3. /etc/sysconfig/network-scripts/ifcfg-*(兼容模式)
二、问题根因分析
2.1 /etc/resolv.conf的生成机制
当NetworkManager启动或重启时,它会:
- 扫描所有活跃的网络连接
- 收集DNS配置信息
- 根据优先级合并配置
- 重新生成
/etc/resolv.conf
bash
# 查看NetworkManager如何管理resolv.conf
cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.119.1
关键机制 :resolv.conf是一个动态生成的文件,而非静态配置文件。
2.2 多IP地址配置的特殊情况
以/etc/sysconfig/network-scripts/ifcfg-br10为例:
ini
DEVICE="br10"
ONBOOT="yes"
TYPE="Bridge"
IPADDR=192.168.1.100 # 主IP地址
PREFIX=24
GATEWAY=192.168.1.1 # 主网关
DNS1=8.8.8.8 # 主DNS
IPADDR1=10.0.0.100 # 次要IP地址
PREFIX1=24
GATEWAY1=10.0.0.1 # 次要网关
DNS2=1.1.1.1 # 次要DNS
问题根源分析:
- DNS优先级混乱:当配置多个IP地址时,NetworkManager可能会根据某种策略(通常是最后激活或特定顺序)选择DNS服务器
- 网关与DNS的关联:在某些情况下,NetworkManager可能会使用某个IP地址对应的网关作为DNS服务器
- 配置合并逻辑:多个IP配置的DNS设置可能会以非预期的方式合并
2.3 具体触发场景
bash
# 重启NetworkManager后检查配置
systemctl restart NetworkManager
# 检查DNS解析过程
cat /etc/resolv.conf
# 可能出现的异常情况:
# 1. DNS指向了IPADDR1的网关地址(10.0.0.1)
# 2. DNS配置被完全重置
# 3. 只保留了一个DNS服务器
# 验证DNS来源
nmcli device show br10 | grep -i dns
三、NetworkManager的DNS决策流程
3.1 配置源优先级
NetworkManager按以下优先级决定使用哪个DNS配置(从高到低):
- 手动通过nmcli配置的DNS
- DHCP服务器提供的DNS(如果使用DHCP)
- ifcfg文件中的DNS设置
- 系统默认DNS
3.2 多连接DNS合并规则
当系统有多个网络连接时:
是
否
是
否
多个网络连接
是否有活跃VPN?
优先使用VPN的DNS
是否有多个物理连接?
按连接优先级合并DNS
使用唯一连接的DNS
生成最终的resolv.conf
3.3 多IP地址配置的DNS选择
对于单个连接配置多个IP地址的情况:
ifcfg-br10配置:
- IPADDR: 192.168.1.100, DNS1=8.8.8.8
- IPADDR1: 10.0.0.100, GATEWAY1=10.0.0.1
问题现象:
重启NetworkManager后,DNS可能变为10.0.0.1
原因分析:
NetworkManager可能错误地将IPADDR1的网关识别为首选DNS源
四、解决方案对比
4.1 方案一:使用nmcli统一管理(推荐)
这是最规范、最可靠的解决方案。
bash
# 1. 查看当前连接
nmcli connection show
# 2. 为br10连接设置DNS(永久生效)
nmcli connection modify br10 ipv4.dns "8.8.8.8 1.1.1.1"
nmcli connection modify br10 ipv4.ignore-auto-dns yes
# 3. 应用配置
nmcli connection up br10
# 4. 验证配置
nmcli connection show br10 | grep -i dns
优势:
- 配置集中管理
- 重启后配置持久化
- 避免配置文件冲突
4.2 方案二:禁用NetworkManager的DNS管理
如果确实需要手动管理/etc/resolv.conf:
bash
# 1. 编辑NetworkManager主配置
vim /etc/NetworkManager/NetworkManager.conf
# 2. 添加或修改以下内容
[main]
dns=none
rc-manager=unmanaged
# 3. 重启NetworkManager
systemctl restart NetworkManager
# 4. 手动配置resolv.conf
echo "nameserver 8.8.8.8" > /etc/resolv.conf
echo "nameserver 1.1.1.1" >> /etc/resolv.conf
4.3 方案三:修复ifcfg多IP配置
对于传统ifcfg配置方式,确保正确设置:
ini
# /etc/sysconfig/network-scripts/ifcfg-br10
DEVICE="br10"
TYPE="Bridge"
BOOTPROTO="none"
ONBOOT="yes"
# 主IP配置
IPADDR=192.168.1.100
PREFIX=24
GATEWAY=192.168.1.1
# 次要IP配置
IPADDR1=10.0.0.100
PREFIX1=24
GATEWAY1=10.0.0.1
# DNS配置(关键)
DNS1=8.8.8.8 # 明确指定DNS1
DNS2=1.1.1.1 # 明确指定DNS2
PEERDNS=no # 防止DHCP覆盖
4.4 方案四:使用NetworkManager配置目录
创建专门的配置文件:
bash
# 1. 创建DNS配置文件
cat > /etc/NetworkManager/conf.d/dns-settings.conf << EOF
[main]
dns=default
systemd-resolved=false
[global-dns]
searches=example.com
[global-dns-domain-*]
servers=8.8.8.8,1.1.1.1
EOF
# 2. 重启NetworkManager
systemctl restart NetworkManager
五、诊断与调试技巧
5.1 查看NetworkManager内部状态
bash
# 查看DNS配置来源
nmcli device show br10 | grep -A5 -B5 DNS
# 查看NetworkManager日志
journalctl -u NetworkManager --no-pager -f
# 调试模式查看详细信息
NM_LOG_LEVEL=debug /usr/sbin/NetworkManager --no-daemon
5.2 检查配置优先级
bash
# 查看所有配置源
nmcli connection show br10 | grep -E "(dns|ipv4\.dns|ipv4\.ignore-auto-dns)"
# 检查resolv.conf的符号链接
ls -la /etc/resolv.conf
# 查看NetworkManager管理的连接
ls -la /etc/NetworkManager/system-connections/
5.3 验证配置持久性
bash
# 测试重启后配置是否保留
systemctl restart NetworkManager
systemctl status NetworkManager
cat /etc/resolv.conf
ping -c 2 google.com
六、最佳实践建议
6.1 生产环境推荐方案
- 统一使用nmcli:避免混合使用传统ifcfg和nmcli命令
- 明确DNS配置:在每个连接中明确指定DNS服务器
- 禁用自动DNS :设置
ignore-auto-dns=yes防止意外覆盖
6.2 配置示例
bash
# 完整配置示例
nmcli connection add type bridge ifname br10 con-name br10 \
ip4 192.168.1.100/24 gw4 192.168.1.1 \
ip4 10.0.0.100/24 \
ipv4.dns "8.8.8.8 1.1.1.1" \
ipv4.dns-search "example.com" \
ipv4.ignore-auto-dns yes \
ipv4.method manual
6.3 故障排查清单
- 检查NetworkManager是否正在运行
- 验证nmcli配置是否正确应用
- 查看
/etc/resolv.conf是否被正确生成 - 确认没有其他服务(如systemd-resolved)干扰
- 检查防火墙是否允许DNS查询
七、总结
在CentOS 8系统中,NetworkManager作为默认网络管理工具,其动态管理/etc/resolv.conf的特性虽然提供了灵活性,但也带来了配置被意外覆盖的风险。特别是在多IP地址配置场景下,不明确的DNS配置可能导致服务重启后DNS设置指向非预期的网关地址。
理解NetworkManager的配置优先级和决策流程是解决问题的关键。推荐在生产环境中统一使用nmcli命令进行网络配置,避免混合使用不同的配置方法。对于需要精细控制DNS的场景,可以适当调整NetworkManager的管理行为或完全接管DNS配置。
通过本文提供的解决方案和最佳实践,您可以有效地管理CentOS 8系统的DNS配置,确保网络服务的稳定性和可靠性。
扩展阅读: