有没有办法配置 Docker 的嵌入式 DNS 服务器的上游名称服务器的端口?

时间:2021-04-22 21:43:22

标签: linux docker dns

一般背景

Docker 守护进程带有一个嵌入式 DNS 服务器。它解析本地 Docker 群和网络记录,并将对外部记录的查询转发到使用 --dns 1 配置的上游名称服务器。

文档说您可以使用 --dns=[IP_ADDRESS...] 为该上游名称服务器设置 IP 地址。使用的默认端口是 53。

我的问题

我也可以配置使用的端口吗?

我的主持人的 /etc/docker/daemon.json 显示 "dns": ["10.99.0.1"],。有没有办法让我指定类似 "dns": ["10.99.0.1:53"] 的内容,以便 dockerd 始终知道将 DNS 查询转发到端口 53?

我的用例

就我而言,10.99.0.1 是 localhost 网桥接口的 IP。我在这台主机上运行本地 DNS 缓存服务器。因此发送到 10.99.0.1:53 的 DNS 查询有效。但是 dockerd 会将源自连接到用户定义的桥接网络(使用 docker network create 创建)的容器的查询转发到它选择的非标准端口。请参阅下面的终端输出。

详细的终端输出和调试信息

“toogle”是一个 Docker 容器,它连接到我用 docker network create 创建的 Docker 网络。 127.0.0.11 是另一个环回地址。源自连接到用户定义的 Docker 网络的 Docker 容器内的 DNS 查询以该 IP 为目标。

Docker 的嵌入式 DNS 服务器是否真的在运行?

DNS 查询是由 Toogle 的防火墙规则以这种方式路由的。

$ sudo nsenter -n -t $(docker inspect --format {{.State.Pid}} toogle) iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 1 packets, 60 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 1 packets, 60 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER_OUTPUT  all  --  *      *       0.0.0.0/0            127.0.0.11

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER_POSTROUTING  all  --  *      *       0.0.0.0/0            127.0.0.11

Chain DOCKER_OUTPUT (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            127.0.0.11           tcp dpt:53 to:127.0.0.11:37619   <-- look at this rule
    0     0 DNAT       udp  --  *      *       0.0.0.0/0            127.0.0.11           udp dpt:53 to:127.0.0.11:58552   <-- look at this rule

Chain DOCKER_POSTROUTING (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 SNAT       tcp  --  *      *       127.0.0.11           0.0.0.0/0            tcp spt:37619 to::53
    0     0 SNAT       udp  --  *      *       127.0.0.11           0.0.0.0/0            udp spt:58552 to::53

在这些端口上监听的任何东西都在接受 TCP 和 UDP 连接

$ sudo nsenter -n -t $(docker inspect --format {{.State.Pid}} toogle) nc 127.0.0.11 37619 -vz

127.0.0.11: inverse host lookup failed: Host name lookup failure
(UNKNOWN) [127.0.0.11] 37619 (?) open

$ sudo nsenter -n -t $(docker inspect --format {{.State.Pid}} toogle) nc 127.0.0.11 58552 -vzu

127.0.0.11: inverse host lookup failed: Host name lookup failure
(UNKNOWN) [127.0.0.11] 58552 (?) open

但是两者都没有 DNS 回复

$ sudo nsenter -n -t $(docker inspect --format {{.State.Pid}} toogle) dig @127.0.0.11 -p 58552 accounts.google.com

; <<>> DiG 9.11.3-1ubuntu1.14-Ubuntu <<>> @127.0.0.11 -p 58552 accounts.google.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached


$ sudo nsenter -n -t $(docker inspect --format {{.State.Pid}} toogle) dig @127.0.0.11 -p 37619 accounts.google.com +tcp

; <<>> DiG 9.11.3-1ubuntu1.14-Ubuntu <<>> @127.0.0.11 -p 37619 accounts.google.com +tcp
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

dockerd 正在从工具中侦听该 IP 和端口上的 DNS 查询。

$ sudo nsenter -n -p -t $(docker inspect --format {{.State.Pid}} toogle) ss -utnlp
Netid        State          Recv-Q         Send-Q                    Local Address:Port                    Peer Address:Port
udp          UNCONN         0              0                            127.0.0.11:58552                        0.0.0.0:*             users:(("dockerd",pid=10984,fd=38))
tcp          LISTEN         0              128                          127.0.0.11:37619                        0.0.0.0:*             users:(("dockerd",pid=10984,fd=40))
tcp          LISTEN         0              128                                   *:80                                 *:*             users:(("toogle",pid=12150,fd=3))

但是 dockerd 正在尝试将 DNS 查询转发到 10.99.0.1,这是我的 docker0 网桥网络接口。

$ sudo journalctl --follow -u docker
-- Logs begin at Tue 2019-11-05 18:17:27 UTC. --
Apr 22 15:43:12 my-host dockerd[10984]: time="2021-04-22T15:43:12.496979903Z" level=debug msg="[resolver] read from DNS server failed, read udp 172.20.0.127:37928->10.99.0.1:53: i/o timeout"
Apr 22 15:43:13 my-host dockerd[10984]: time="2021-04-22T15:43:13.496539033Z" level=debug msg="Name To resolve: accounts.google.com."
Apr 22 15:43:13 my-host dockerd[10984]: time="2021-04-22T15:43:13.496958664Z" level=debug msg="[resolver] query accounts.google.com. (A) from 172.20.0.127:51642, forwarding to udp:10.99.0.1"

dockerd 将请求名称服务器 127.0.0.11:58552 的 DNS 查询转发到 10.99.0.1,但只更改 IP 而不是端口。因此 DNS 查询被转发到 10.99.0.1:58552 并且没有在该端口监听。

$ dig @10.99.0.1 -p 58552 accounts.google.com
[NO RESPONSE]

$ nc 10.99.0.1 58552  -vz
10.99.0.1: inverse host lookup failed: Unknown host
(UNKNOWN) [10.99.0.1] 58552 (?) : Connection refused

对 10.99.0.1:53 的 DNS 查询按预期工作。

dig @10.99.0.1 -p 53 accounts.google.com

; <<>> DiG 9.11.3-1ubuntu1.14-Ubuntu <<>> @10.99.0.1 -p 53 accounts.google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53674
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;accounts.google.com.       IN  A
;; ANSWER SECTION:
accounts.google.com.    235 IN  A   142.250.1.84
;; Query time: 0 msec
;; SERVER: 10.99.0.1#53(10.99.0.1)
;; WHEN: Thu Apr 22 17:20:09 UTC 2021
;; MSG SIZE  rcvd: 64

1 个答案:

答案 0 :(得分:0)

我认为没有办法做到这一点。我也误读了输出。 Docker 守护进程正在转发到端口 53。

read udp 172.20.0.127:37928->10.99.0.1:53: i/o timeout