使用自定义网桥时,docker容器内nameserver为127.0.0.11:53
从Docker 1.10版本开始,当容器被分配到自定义网络(如用户定义的bridge网络或overlay网络)时,Docker会为这些容器提供一个内置的DNS服务器,其地址固定为127.0.0.11。这个内置的DNS服务器允许容器通过服务名称相互发现和通信,尤其是在多容器应用中非常有用。
dns是127.0.0.11,所以该dns server肯定是本地监听的,使用netstat -anu
查看容器本地的所有udp监听:
可以发现:没有进程在监听53端口,只有一个奇怪的41287
查看容器的nat iptables:
|
|
出现了这个奇怪的41287端口,这样就能解释netstat的输出内容了,整个解析过程到此是:
- 进程向127.0.0.11:53发出DNS请求
- iptables将发送到127.0.0.11:53的数据包NAT到127.0.0.11:41287
谁在监听41287端口?显然不可能是容器内的进程:
可以发现是dockerd在监听这个端口,宿主机的dockerd进程通过 setns 系统调用可以进入其他network namespace。
查看dockerd进程的系统调用:
|
|
所以,当nameserver为127.0.0.11:53时,其域名解析的流程如下:
- 进程向127.0.0.11:53发出DNS请求
- iptables将发送到127.0.0.11:53的数据包NAT到127.0.0.11:41287,也就是dockerd进程
- dockerd通过setns系统调用进入容器的network namespace,然后再向真正的DNS服务器发出请求,由于请求是从容器的network namespace发出的,请求包的IP地址是容器的IP地址
- dockerd收到DNS响应,将结果写入127.0.0.11:41287
- iptables再将127.0.0.11:41287重写回127.0.0.11:53,进程接收到DNS响应,请求完毕
注意:如果dns服务器的53端口做了限制,只对宿主机ip放行,其他ip全部拒绝的话,那么容器内是无法访问dns服务器的。所以这种情形需要放行容器的网段。
host模式或者使用默认的bridge网桥时,docker容器内nameserver和宿主机的/etc/resolv.conf保持一致
源码分析:
- containerStart
initializeNetworking()是重点,/var/lib/docker/containers/xxxx/resolv.conf文件的内容就是在此处被覆盖的。
|
|
- initializeNetworking
- allocateNetwork()
|
|
- connectToNetwork
|
|
- NewSandbox
|
|
- setupResolutionFiles
- setupDNS
|
|
宿主机 /etc/resolv.conf 动态变化
在容器启动时,Docker 会将宿主机的 /etc/resolv.conf 内容复制到容器中。
如果宿主机 DNS 配置后续发生变化,已运行的容器不会自动更新,但新启动的容器会继承最新配置。
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。