Docker如何实现DNS nameserver?同网络容器DNS互访原理咨询
你对Docker容器间DNS解析的基础理解是正确的,以下是你三个问题的具体解答:
问题1:DNS服务的运行位置与进程查看
- 该DNS服务不是独立的隐藏容器进程,是直接集成在
dockerd(Docker守护进程)中的功能模块,运行在你docker-machine对应的Linux虚拟机内部,和dockerd属于同一个进程。 - 你可以直接登录docker-machine的Linux虚拟机,执行
ps aux | grep dockerd即可找到对应的进程,不存在单独的DNS服务进程。 - 你架构中Linux虚拟机层级的
nameserver 10.0.2.3是docker-machine默认使用的VirtualBox虚拟化层提供的DNS转发地址,并非Docker内置DNS服务的监听地址。
问题2:DNS服务的实现方式
- Docker没有使用bind这类传统DNS服务工具,是完全自研的轻量DNS解析模块,基于Go语言标准库的DNS相关能力开发。
- 它的核心解析逻辑非常简洁:优先匹配当前自定义网桥下的容器名、网络别名、Swarm服务名,如果匹配不到对应记录,就会把解析请求转发给上游DNS,也就是Linux虚拟机配置的
10.0.2.3,再逐层向上转发到Mac宿主机的DNS完成解析。
问题3:容器内127.0.0.11地址的暴露原理
- 127.0.0.11并不是Docker DNS服务的真实监听地址,是Docker依靠Linux
iptables的NAT规则实现的虚拟地址,具体实现逻辑如下:- Docker会为每个容器的独立网络命名空间单独配置DNAT(目标地址转换)规则,所有发往
127.0.0.11:53(DNS服务默认端口,包含UDP和TCP协议)的请求,都会被自动转发到dockerd内置DNS服务的实际监听端口上。 - 因为规则是每个容器网络命名空间独立配置的,所以所有容器内都能看到
127.0.0.11这个地址,互相不会产生冲突。 - 你可以进入任意一个运行中的容器,执行
iptables -t nat -L -n命令,就能看到对应的DNAT转发规则。
- Docker会为每个容器的独立网络命名空间单独配置DNAT(目标地址转换)规则,所有发往
补充机制说明
- 只有使用用户自定义网桥(即通过
docker network create手动创建的网络)时,才会自动启用该内置DNS服务并配置127.0.0.11作为默认nameserver,Docker默认的docker0网桥使用旧版DNS机制,不会启用该功能。 - 如果手动修改容器内的
/etc/resolv.conf文件,会覆盖Docker默认的DNS配置,可能导致容器名、服务名解析失效。
内容的提问来源于stack exchange,提问作者user2490003
相关产品推荐
相关产品推荐

