我知道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)如何公开主机 namespace 中的某些端口和其他 namespace (容器)中的某些端口?我读了一些代码,但仍然不明白,有人可以帮助回答吗?

谢谢。

最佳答案

也许您已经发现Docker(aka Moby)内部使用libnetwork来配置和enable the embedded DNS resolver。 Libnetwork将解析器绑定(bind)到容器的环回接口(interface),以便127.0.0.11上的DNS查询可以(通过iptables)路由到Docker Engine中的“后端DNS解析器”。参见libnetwork type和实际的ResolveName() code。每个容器的Sandbox允许通过网络 namespace 路由DNS查询。

关于您的问题,一个进程如何可以暴露主机上和容器内的端口:在这种情况下,将处理程序线程绑定(bind)到接口(interface)将是更合适的表达。 Docker引擎创建一个容器并配置其网络 namespace ,因此它还可以通过iptables配置容器的网络接口(interface)和数据包路由。将解析程序绑定(bind)到容器的内部接口(interface)是为什么您没有在侦听端口53的主机上找到任何进程的原因。

09-04 21:34
查看更多