命令在 VPN 命名空间内访问 10.8.0.5 毫无问题,可一旦改用主机名就立刻失败。命名空间有自己的接口、路由和套接字,却没有自己的解析器文件。除非有人在里面放一份,否则内侧进程读到的是主机的 /etc/resolv.conf,去问的服务器可能从这个网络栈根本不可达。

这是文件选择问题,而不是路由问题,数字地址之所以仍然可用,原因正在于此。

确认进程实际拿到的解析器视图

不要假定你用的 shell 与被调试的进程等价。图形应用、systemd 单元和容器都可能进入另一套挂载或网络上下文。请沿同一条启动路径发起查询,并从该上下文内部打印解析器文件。

对于用 ip netns add 创建的命名空间,只读检查很短:

ip netns exec vpn cat /etc/resolv.conf

留意结果给出的是可达地址、loopback 桩,还是指向可达性不同的位置的符号链接。

exec 辅助程序到底挂载了什么

ip-netns 工具在 /etc/netns/NAME/ 下记录了按命名空间的配置。启动进程时,辅助程序会创建挂载命名空间,把这些文件覆盖挂载到常规路径上,于是进程看到的就是该命名空间专属的副本。这是这个特定启动器的便利之处。若通过别的途径进入网络命名空间,例如 unshare 或容器运行时,这一行为不会自动复现。

这里的陷阱是 loopback 解析器:127.0.0.53 指的是命名空间自己的 loopback,而不是主机的桩。只在主机命名空间里监听的桩,不会在新命名空间里变成服务。

选择命名空间能够到达的解析器

无论文件里写的是哪台服务器,它仍然需要一条从该命名空间出发的路由。公共解析器能回答公共名字,却仍可能解析不了内部区域,因为私有服务只能经隧道到达。请把路由和地址放在一起检查,而不是等查询失败之后才回头看。

自带解析器的应用,例如使用 DNS over HTTPS 的应用,可能完全忽略这个文件。如果工具本身有 DNS 设置,改 resolv.conf 对它没有影响,命名空间从来就不是问题所在。

把文件写在正确的位置

在 /etc/netns/NAME/resolv.conf 下创建按命名空间使用的文件,让启动器把它呈现出来。保持精简:一两台可达服务器,加上任务需要的搜索域。不要为了修正某个进程组的视图去改主机生成的解析器文件,那会改变整台机器上的所有应用。如果主机使用解析器管理器,就通过那个管理器配置命名空间路径,而不是跟它硬碰。

把文件内容记录到运行手册里。否则下一个人会去测主机的解析器,看到能用的答案,就断定命名空间没有问题。

重新测试整条路径

在命名空间内分别用数字地址、内部名字和公共名字测试。这个顺序把可达性与解析分开,也把内部区域与公共区域分开。然后重建命名空间再重复一遍,因为只存在于运行实例里的文件会随实例一起消失。

确认收到文件的是进程而不是 shell。交互式 shell 里能用、从服务里却失败,这是关于挂载上下文的发现,值得在下次事故前写下来,而不是从头再发现一次。

相关文章