容器内 DNS 是什么
在用户自定义网络上,Docker 会为容器配一个内嵌 DNS 服务(监听 127.0.0.11),容器名、网络别名与 Compose 里的服务名都能被解析成对应容器的地址。这套解析完全由 Docker 维护,不依赖宿主机的 DNS 配置。默认 bridge 网络没有这个能力,容器之间只能靠 IP 互访或自己维护 hosts 文件——这是很多「服务名连不上」问题的根源。
基本信息
| 解析器地址 | 容器内 /etc/resolv.conf 指向 127.0.0.11 |
|---|---|
| 可用范围 | 用户自定义网络(docker network create / Compose 网络) |
| 可解析名称 | 容器名、网络别名(--network-alias)、Compose 服务名 |
| 默认 bridge | 无容器名解析能力 |
| 上游解析 | 容器内请求的外部域名由内嵌 DNS 转发到宿主 DNS |
| 相关机制 | 自定义网络内的容器可通过 --link 之外的别名机制互相发现 |
典型使用场景
- Compose 或自定义网络里用服务名当连接串主机名,例如数据库地址写 db
- 给容器加别名,让连接串与业务代码里的历史名字保持兼容
- 排查「改完 IP 后连接串失效」:改用容器名后地址随容器重建自动更新
- 验证网络归属是否正确:解析失败往往说明两个容器不在同一张网
- 用同一个别名指向新容器做灰度切换
观察与验证
观察与验证
# 看容器内解析器配置:自定义网络里会指向 127.0.0.11
docker exec web cat /etc/resolv.conf
# 在同一自定义网络里解析另一个容器的名字
docker run --rm --network app-net alpine getent hosts db
# 默认 bridge 网络上做同样测试:预期解析不到容器名
docker run --rm --network bridge alpine getent hosts db
# 给容器追加别名,让历史连接串继续可用
docker run -d --network app-net --network-alias api.internal --name api app/api:1.4.2
# 核对网络内成员与别名
docker network inspect app-net解析行为对照
| 场景 | 能否按名字解析 | 说明 |
|---|---|---|
| 自定义网络内互访 | 可以 | 内嵌 DNS 提供服务名与别名 |
| 默认 bridge 内互访 | 不可以 | 只有 IP,需自行维护 hosts |
| 跨不同自定义网络 | 不可以 | 除非两个容器接入同一张网 |
| 解析外部域名 | 可以 | 由内嵌 DNS 转发到宿主上游 |
| 容器访问自身名字 | 可以 | /etc/hosts 中自带本机条目 |
容器重建后 IP 可能变化,用容器名或服务名做地址比记 IP 稳定得多;反过来,把 IP 写进配置文件就是给自己埋雷。
宿主机上的程序无法通过容器名访问容器,宿主不在容器网络里。要让宿主访问,应发布端口,或让宿主进程接入容器可到达的地址。