docker容器默认dns由四层配置决定,优先级为:--dns参数>自定义网络--dns>daemon.json全局配置>宿主机/etc/resolv.conf;推荐通过--dns强制指定或自定义网络上游dns实现可控解析。

Docker 容器内部默认 DNS 的来源不是固定不变的,而是由多层配置共同决定,优先级从高到低依次为:容器启动时 --dns 参数 → 自定义网络创建时指定的 --dns → Docker 守护进程全局配置(daemon.json)→ 宿主机 /etc/resolv.conf(经 Docker 过滤后写入)。要真正“自定义容器内部的默认 DNS”,关键在于明确控制哪一层生效,并确保目标 DNS 服务器本身支持递归查询。
启动单个容器时强制指定 DNS(最高优先级)
这种方式最直接、最可靠,适用于调试、测试或临时部署场景。Docker 会完全忽略其他 DNS 来源,只把 --dns 提供的地址写入容器 /etc/resolv.conf。
- 支持多个 DNS 地址,按顺序排列,系统调用会依次尝试
- 只接受 IP 地址(不支持域名),例如
--dns 192.168.10.50或--dns 2001:4860:4860::8888 - 若需同时设置搜索域或解析选项,可搭配
--dns-search和--dns-opt使用
docker run --dns 192.168.10.50 --dns 114.114.114.114 --dns-search corp.local -it alpine nslookup api.corp.local
注意:该方式对已运行容器无效,仅作用于新启动实例;若容器加入已设 DNS 的自定义网络,
--dns仍会覆盖网络级配置。
全局统一修改所有新容器的默认 DNS
适合企业内网环境,比如所有容器必须走公司 CoreDNS 做审计和私有域名解析。
- 编辑
/etc/docker/daemon.json,添加dns、dns-search和dns-opts字段 - 必须重启 Docker 守护进程才能生效:
sudo systemctl restart docker - 已运行容器不受影响,但后续新建容器都会继承该配置
示例配置:
{
"dns": ["192.168.10.50", "8.8.8.8"],
"dns-search": ["corp.local", "svc.cluster.local"],
"dns-opts": ["ndots:5"]
}
验证是否生效:
docker run --rm alpine cat /etc/resolv.conf
提示:
192.168.10.50必须是一台能对外递归查询的 DNS 服务(如 dnsmasq、CoreDNS),否则容器将无法解析公网域名。
在自定义网络中启用内嵌 DNS 并转发查询
这是推荐的服务发现 + 外部解析混合方案。Docker 为每个自定义网络自动分配内嵌 DNS(地址固定为 127.0.0.11),它不直接响应外部域名,而是把非本网络的查询转发给指定的上游 DNS。
- 创建网络时通过
--dns指定上游 DNS,例如:docker network create --dns 192.168.10.50 mynet
- 启动容器时只指定网络,无需再加
--dns:docker run --network mynet --name db postgres
- 此时容器
/etc/resolv.conf写入的是nameserver 127.0.0.11,而127.0.0.11会把db解析成本网络 IP,把baidu.com转发给192.168.10.50
优势:既保留容器名和服务别名自动解析能力,又支持内网/公网域名统一递归;缺点是无法绕过内嵌 DNS 直接使用宿主机 DNS。
使用 Docker Compose 声明 DNS 配置
适用于编排场景,等效于 docker run --dns,但更易维护。
- 在
docker-compose.yml的 service 级别或 network 级别声明dns字段 - 支持数组形式,也可配合
dns_search和dns_opt
示例:
services:
app:
image: nginx
dns:
- 192.168.10.50
- 114.114.114.114
dns_search:
- corp.local
注意:Compose v2+ 中
dns字段作用于容器层级;若同时定义了自定义网络并设置了driver_opts: {"com.docker.network.bridge.enable_ip_masquerade": "true"},需确认无冲突。
不复杂但容易忽略











