Docker 容器的 DNS 是怎么实现的!
- 2025-06-30 10:20:46
- 529
在日常使用 Docker 构建微服务架构的过程中,我们经常会遇到一个问题:多个容器之间是如何通过名字互相访问的?DNS 是怎么做到的?
从底层机制讲清楚 Docker 的 DNS 系统
1. 容器间通信的前提:同一个网络
Docker 默认会创建一个叫 bridge 的网桥网络。所有未指定网络的容器,都会被分配到这个 bridge 网络中。
在这个默认网络中,虽然每个容器都有一个独立的 IP 地址,但要实现通过容器名访问其他容器,就必须依赖 Docker 提供的 DNS 服务。
⚠️ 注意:只有在用户自定义的 bridge 网络中,容器名解析才默认开启!默认的 bridge 网络不支持容器名解析!
2. Docker 的内置 DNS 是如何工作的?
Docker 在每个容器启动时,会将容器的 /etc/resolv.conf 文件指向一个特殊的 DNS 地址:127.0.0.11
这个地址并不是真的公网 DNS,而是 Docker Daemon 内置的 DNS 服务器。
这个 DNS 有以下作用:
解析外部域名(比如访问百度、Google)
解析容器内部服务名(比如 web, db 等容器名)
它的背后是 Docker 的 embedded DNS server,工作机制大概如下:
1️⃣ 容器发出 DNS 查询请求(查某个服务名)
2️⃣ 请求发到 127.0.0.11(docker 的内部 DNS)
3️⃣ Docker DNS 根据网络配置,找到对应容器的 IP 地址
4️⃣ 将结果返回给发起请求的容器
3. 实验验证:容器名访问是否生效?
我们创建一个自定义网络,并启动两个容器测试下
# 创建一个自定义 bridge 网络docker network create mynet# 启动容器A,名字叫 webdocker run -it --rm --name web --network mynet busybox sh# 启动容器B,在这个网络中尝试 ping webdocker run -it --rm --network mynet busybox sh
在 B 容器中输入:
ping web
你会发现,DNS 能自动解析出 web 的 IP,这就说明 Docker 的内置 DNS 正常工作啦
4. 自定义服务名(别名)怎么设置?
有时候我们希望容器访问的名字不是容器名,而是我们指定的服务名。Docker 也支持这一点:
docker run -it --rm \ --network mynet \ --name mydb \ --network-alias database \ busybox sh
然后在其他容器中,就可以通过 database 这个名字访问它
5. 与外部 DNS 的协同
Docker 的 embedded DNS 并不是万能的,它在无法解析服务名时,会把请求转发给 /etc/resolv.conf 中指定的上游 DNS。
这意味着:
外部网络访问正常(比如你容器内 ping www.baidu.com)
内部容器名也能解析
Docker DNS 是中间层代理
这个设计非常巧妙!兼顾了内外网的域名解析。
6. 容器 DNS 失效的常见问题
❌ 没有使用自定义网络,导致 DNS 解析失败
❌ 使用了 host 网络,容器直接共享宿主机网络,无法使用 Docker 的 DNS
❌ 被 resolv.conf 修改或者挂载了宿主机 DNS 文件
❌ 某些 VPN 环境导致容器 DNS 路由异常
解决方法建议:
尽量使用自定义 bridge 网络
检查 /etc/resolv.conf 是否被覆盖
检查 Docker 网络配置 docker network inspect
总结
Docker 容器之间的 DNS 解析,其实是靠 Docker Daemon 内置的 DNS 服务(监听在 127.0.0.11)来实现的,它能让容器通过服务名互相访问,还支持 alias、自定义网络、多级域名等能力。
- 上一篇:洛杉矶当地华人
- 下一篇:原来排卵期一直都在被误解