Docker嵌入式DNS解析器如何工作?

时间:2017-01-17 21:45:03

标签: docker namespaces

我知道Docker有一个嵌入式Dns解析器 当我在自己的桥上运行一个容器时:

$ docker run -it --rm --privileged --network=mybridge xxx bash

root@18243bfe6b50:/# cat /etc/resolv.conf  
nameserver 127.0.0.11  
options ndots:0  

root@18243bfe6b50:/# netstat -anop  
Active Internet connections (servers and established)  
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name Timer  
tcp        0      0 127.0.0.11:45997        0.0.0.0:*               LISTEN      -                off (0.00/0/0)  
udp        0      0 127.0.0.11:49614        0.0.0.0:*        

it shows there is a dns resolver, and iptables help do a port transfer.  

root@18243bfe6b50:/# iptables -nvL -t nat  
.....  
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:45997  
    0     0 DNAT       udp  --  *      *       0.0.0.0/0            127.0.0.11           udp dpt:53 to:127.0.0.11:49614  

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:45997 to::53  
    0     0 SNAT       udp  --  *      *       127.0.0.11           0.0.0.0/0            udp spt:49614 to::53  

but, which process is the dns resolver? I guess it is dockerd?  but dockerd is running in host network namespace, obviously it is different with the container network namespace, also, I can not find dockerd has dns port listening in host:  

root@test:~# netstat -tnop |grep dockerd  
tcp        0      0 10.5.79.50:59540        10.5.79.50:2377         ESTABLISHED 3332/dockerd     off (0.00/0/0)  
tcp        0      0 127.0.0.1:35792         127.0.0.1:2377          ESTABLISHED 3332/dockerd     off (0.00/0/0)  
tcp6       0      0 10.5.79.50:2377         10.5.79.70:45934        ESTABLISHED 3332/dockerd     off (0.00/0/0)  
tcp6       0      0 127.0.0.1:2377          127.0.0.1:35792         ESTABLISHED 3332/dockerd     off (0.00/0/0)  
tcp6       0      0 10.5.79.50:2377         10.5.79.50:59540        ESTABLISHED 3332/dockerd     off (0.00/0/0)  

一个进程(dockerd)如何暴露主机命名空间中的某些端口以及其他命名空间(容器)中的某些端口?我读了一些代码,但仍然无法弄清楚,有人可以帮忙解答吗?

感谢。

1 个答案:

答案 0 :(得分:8)

也许您已经发现Docker(又称Moby)在内部使用libnetwork进行配置和enable the embedded DNS resolver。 Libnetwork将解析器绑定到容器的loopback接口,以便127.0.0.11处的DNS查询可以(通过iptables)路由到Docker Engine中的“后端DNS解析器”。请参阅libnetwork type和实际ResolveName() code。每个容器的Sandbox允许通过网络命名空间路由DNS查询。

关于你的问题,一个进程如何在主机上和容器内部公开端口:在这种情况下, binding 处理程序线程到接口将是一个更合适的表达式。 Docker引擎创建一个容器并配置其网络命名空间,因此它还可以通过iptables配置容器的网络接口和包路由。将解析程序绑定到容器的内部接口是您在主机上侦听端口53时未找到任何进程的原因。