Linux排障日记:为什么 /etc/hosts 写了解析却不生效?

在docker容器化平台安装过程中,我们遇到一个典型问题:容器启动过程中,访问镜像仓库服务失败,重试40次依然无果。

部署同学在节点上手工测试时发现报错

复制
curl http://registry.local.net:5000 curl: (6) Could not resolve host: registry.local.net1.2.

对网络熟悉的同学都知道主机上dns解析会优先匹配/etc/hosts中配置的本地解析,如果没有配置在再去/etc/resolv.conf中通过dns服务器解析。

1️⃣ 排查过程

仓库服务在部署的时候会在所有节点会配置本地解析,先通过curl或者ping命令测试解析

节点手工访问同样解析失败
复制
curl http://registry.local.net:5000 curl: (6) Could not resolve host: registry.local.net1.2.
/etc/hosts 确实配置了本地地址解析
复制
10.x.16.x registry.local.net1.

明明在/etc/hosts里已经写了解析,为什么主机还是提示无法解析域名?

使用strace命令检查下解析调用过程

复制
[root@localhost ~]# strace -e trace=open,openat -f ping -c 1 registry.local.net ..... openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 5 openat(AT_FDCWD, "/etc/host.conf", O_RDONLY|O_CLOEXEC) = 5 openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 5 openat(AT_FDCWD, "/dev/cur_gl", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 5 openat(AT_FDCWD, "/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 5 openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC) = 5 openat(AT_FDCWD, "/usr/lib64/charset.alias", O_RDONLY|O_NOFOLLOW) = -1 ENOENT (没有那个文件或目录) PING registry.local.net (10.xx.16.xx) 56(84) bytes of data. openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC) = 5 64 bytes from registry.local.net (10.xx.16.xx): icmp_seq=1 ttl=64 time=0.402 ms --- registry.local.net ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.402/0.402/0.402/0.000 ms +++ exited with 0 +++1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.

从调用过程上看调用了linux的 /etc/nsswitch.conf 配置文件

排查发现,该文件中相关配置被注释掉

复制
#hosts: files dns myhostname1.
解释:files首先查本地文件 /etc/hosts,如果匹配成功,直接返回 IP。dns如果本地文件没找到,再去 /etc/resolv.conf 中的 DNS 服务器查询。myhostname解析当前主机自己的主机名(hostnamectl 设置的名字)。

也就是说,Linux 会严格按照 

files → dns → myhostname 的顺序来解析域名。如果顺序被改了,或者干脆被注释掉,就会出现类似 “明明写在 /etc/hosts,却不生效” 的现象。

那么问题原因就显而易见了,由于此配置被注释,linux系统默认走到了dns服务器查询ip,但是此域名没有在dns注册过,解析不出来符合预期。

2️⃣ 解决方案

修改/etc/nsswitch.conf文件,将注释去掉,恢复为

复制
hosts: files dns myhostname1.

保存后立即生效,再次访问:

复制
[root@localhost ~]# curlregistry.local.net:5000 -I HTTP/1.1 200 OK Cache-Control: no-cache Date: Mon, 29 Sep 2025 06:45:45 GMT1.2.3.4.

返回正常了,问题解决

3️⃣ 总结与启示

1. 不要忽略基础文件很多看似复杂的安装失败问题,最终原因可能是最基础的系统配置。

2. 熟悉主机名解析顺序/etc/nsswitch.conf 决定了解析优先级,平时容易被忽视。

3. 排查要有层次先确认本地hosts解析,再确认 DNS,最后再检查系统配置文件,才能快速定位。

THE END