Docker容器默认使用宿主机DNS,但可通过--dns参数指定IP地址(如docker run --dns 8.8.8.8 nginx)覆盖/etc/resolv.conf;多DNS按序生效,推荐内网DNS;自定义网络或systemd-resolved可能导致配置被覆盖;全局配置需修改/etc/docker/daemon.json并重启docker服务。

在 Docker 容器中,默认使用宿主机的 DNS 配置(通常是 /etc/resolv.conf 中的内容),但有时会遇到容器内无法解析域名的问题,比如内部服务域名、私有镜像仓库或自建 DNS 服务不可达。这时可通过 docker run 显式指定 DNS 服务器,让容器使用更可靠或更符合业务需求的 DNS 解析路径。
使用 --dns 参数指定 DNS 服务器
最直接的方式是在运行容器时通过 --dns 参数传入一个或多个 DNS 地址。Docker 会将其写入容器内的 /etc/resolv.conf,覆盖默认配置。
- 单个 DNS:
docker run --dns 8.8.8.8 nginx - 多个 DNS(按优先级顺序):
docker run --dns 114.114.114.114 --dns 8.8.8.8 nginx - 配合其他参数(如端口映射、后台运行):
docker run -d --dns 192.168.1.100 -p 8080:80 nginx
注意:DNS 地址必须是可达的 IP(不支持域名),且建议优先使用内网 DNS(如公司 CoreDNS、dnsmasq)以保障解析速度和私有域名可用性。
避免 DNS 配置被覆盖的常见情况
某些场景下,即使指定了 --dns,容器启动后仍可能恢复为默认 DNS,原因包括:
- 使用了自定义 Docker 网络(
docker network create),而该网络在创建时已设置--dns,会覆盖容器级配置 - 容器内应用(如某些 Alpine 基础镜像中的 BusyBox)启动时主动重写
/etc/resolv.conf - 宿主机启用了
systemd-resolved或NetworkManager,导致 Docker daemon 自动注入 127.0.0.53
验证方式:进入容器执行 cat /etc/resolv.conf,确认内容与预期一致;再用 nslookup example.com 或 ping -c 1 google.com 测试连通性。
持久化 DNS 配置(全局生效)
若多数容器都需要统一 DNS,可在 Docker daemon 级别配置,避免每次 run 都重复指定:
- 编辑
/etc/docker/daemon.json(不存在则新建):
{
"dns": ["114.114.114.114", "8.8.8.8"]
}- 重启 Docker 服务:
sudo systemctl restart docker - 此后所有新启动的容器(除非显式用
--dns覆盖)都会继承该配置
该方式适合标准化运维环境,但需注意:它不影响已运行的容器,也不适用于需要差异化 DNS 的多租户场景。
调试与验证技巧
当 DNS 不生效时,可按以下步骤快速定位:
- 检查容器内
/etc/resolv.conf是否含预期 DNS 条目(注意:部分镜像会挂载只读tmpfs,导致修改无效) - 尝试手动执行
nslookup -server=8.8.8.8 example.com,绕过系统配置直连测试 - 确认容器网络是否能访问 DNS 端口:
telnet 8.8.8.8 53或nc -zv 8.8.8.8 53 - 若使用自定义桥接网络,检查是否禁用了 iptables 或存在防火墙拦截 UDP 53
对于基于 glibc 的镜像(如 Ubuntu、CentOS),DNS 解析行为较标准;Alpine 等基于 musl 的镜像对 resolv.conf 格式更敏感,避免添加注释或空行。










