我在使用 docker 网络时遇到了一些问题(特别是自定义 DNS 代理设置),并且发现我的 resolv.conf 有点奇怪:
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
nameserver 172.17.0.1
nameserver 10.0.0.10
nameserver 127.0.0.53
因此,第三方自定义 DNS 代理基本上将第三个 IP 更改为如下内容:
#nameserver 127.0.0.53
nameserver [proxy-dns-entry-ip]
10.0.0.10
我对此 DNS 下的主机名的所有请求均在以下情况下中断nslookup
:
$ nslookup container1.hostname
;; Got recursion not available from 172.17.0.1, trying next server
Server: 10.0.0.10
Address: 10.0.0.10#53
** server can't find container1.hostname: NXDOMAIN
$ nslookup container1.hostname [proxy-dns-entry-ip]
Server: 192.168.144.3
Address: 192.168.144.3#53
Non-authoritative answer:
Name: container1.hostname
Address: 192.168.128.3
Name: container1.hostname
Address: 192.168.128.3
我已经编辑了该文件并且只注释掉了前两个 IP 地址,并且新的 DNS 运行正常,并且当这个代理被禁用并且唯一的条目是时127.0.0.53
,主机网络也运行正常(例如,我可以 ping 谷歌并使用我的浏览器),docker 和容器也在运行。
我对网络(尤其是 Linux)还不太熟悉。有人能向我解释一下这 3 个地址是怎么回事,以及它们如何与 ubuntu 的 DNS 服务器(我指的是我在 GUI 网络设置中定义的那些服务器)耦合吗?
答案1
我将不按顺序回答您的问题,因为它们都略有不同,而且一个问题的答案将帮助您理解另一个问题的答案,等等。
问题 #2 的答案:DNS 服务器如何在您的系统中工作,以及问题 #3 的部分答案:resolv.conf 的作用
当您的系统中使用多个 DNS 服务器时,系统会按顺序查询它们。因此,如果我的 resolv.conf 包含以下内容:
nameserver 1.2.3.4
nameserver 5.6.7.8
nameserver 10.10.1.0
nameserver 127.0.0.53
...那么任何请求您系统上的 DNS 记录的服务器都会首先尝试 1.2.3.4。如果 1.2.3.4 响应,那么一切就结束了(包括 SERVFAIL 错误响应和 NXDOMAIN 响应,两者都是“有效回复”)。但是,如果它在响应中超时并且没有返回响应,那么它会尝试下一个服务器 - 5.6.7.8。如果 5.6.7.8 响应,那么它会停在那里。如果它没有响应,那么它会继续尝试 10.10.1.0。这将持续到按顺序列出的服务器之一给出响应或它们都超时为止。这是 DNS 的设计,因为“第一个实际回复的服务器是我们处理的服务器”
这是因为查找顺序是初级、次级、第三级、第四级等。第一个响应的查询链将停止。
您的列表中的最后一个以及此处的示例列表中的最后一个,127.0.0.53,转到您的 SystemD ResolveD 存根,这就是问题 #3 的答案所在。
回答#3:这与您的 GUI 设置有何不同?
简而言之,resolv.conf
在后台用于确定您的 DNS 服务器优先级设置。通常在 18.04 中它只会指向127.0.0.53
哪个是您的systemd-resolved
处理程序。
您的处理程序将依次由您的网络管理器 GUI 设置提供,您的 DNS 服务器将使用它们进行递归查询。这是我的 GUI 设置提供给我的 wifi 连接的systemd-resolved
设置示例:systemd-resolved
$ systemd-resolve --status
....
Link 2 (wlp59s0)
Current Scopes: DNS
LLMNR setting: yes
MulticastDNS setting: no
DNSSEC setting: no
DNSSEC supported: no
DNS Servers: 10.10.1.0
DNS Domain: ~.
当您的系统收到 DNS 查询并将其交给 127.0.0.53 时,系统会检查其本地 DNS 缓存,以查看是否存在已知记录。如果失败,系统会查询系统中指定的 DNS 服务器。在本例中,假设我的系统resolve.conf
是一个基本系统,如下所示:
$ cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "systemd-resolve --status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 127.0.0.53
... 将导致查找google.com
本地systemd-resolved
实例,如果它没有缓存的 DNS 条目,它将使用来自内部的 DNS 请求转到 10.10.1.0 resolved
。
但是,在您的系统中,根据答案#2,行为会有所不同,因为您的 resolv.conf 中有多个其他修订版本,这些修订版本会破坏此过程。
回答问题 1:这些地址是什么?
某人或某物改变了您的 resolv.conf 系统以添加这些额外的地址。
这是你或 Docker 所为。10.0.0.10 可能是另一个 Docker 实例或通过 dnsmasq 或类似物的另一个 Docker 监听器或你环境中的其他网络添加了它。
不幸的是,我们无法提供任何有关 10.0.0.10 的信息,因为这可能是任何数字。我们可以识别 172.17.0.1,因为您说它是 Docker,以及 127.0.0.53,因为那是 SystemD ResolveD。
127.0.0.53 正如我在上面的第 2 和第 3 个问题的答案中所述,systemd-resolved
它是您 GUI DNS 设置的输入。
问题 4 的答案:如何使改变永久生效?
除非你删除符号链接,否则文件将由 提供resolvconf
。除非你的resolvconf
配置不同,否则它将是一个符号链接。制作一个永久的改变就是断开符号链接,然后只保留一个静态文件。因此,要使用 Docker DNS 和系统 DNS,您需要一个静态文件,其/etc/resolv.conf
内容如下:
# THIS IS NOT FED BY resolvconf, any changes here are PERMANENT.
nameserver 172.17.0.1
nameserver 127.0.0.53
这将是永久的配置设置,直到您更改它或将 resolv.conf 设置回符号链接。
然而不幸的是,除了删除符号链接并用静态文件替换之外,没有办法告诉resolvconf
这里保留一组永久的命令。
还有其他更复杂的方法,例如拥有单独配置的 DNS 服务器系统,但这超出了“正常”的范围,并且绝对是“一种黑客解决方法”,您可能不想开始深入研究。