dns解析失败导致“temporary failure in name resolution”,需从容器内配置、docker守护进程策略及宿主机网络栈三层排查:先用ping和nslookup定位是否为dns问题,再通过临时覆盖resolv.conf或--dns参数验证,最后通过修改daemon.json、挂载宿主机resolv.conf或自定义网络dns实现永久修复。

当Docker容器内执行curl google.com报错“Temporary failure in name resolution”,或apt update卡在“Resolving packages...”时,说明DNS解析已中断——这不是网络连通性问题,而是域名到IP的翻译环节失效,必须从容器内部DNS配置、Docker守护进程策略、宿主机网络栈三层切入排查。
第一步:确认是DNS问题而非网络不通
进入容器执行:docker exec -it sh,然后依次运行:
① ping -c 3 8.8.8.8 —— 若能通,说明三层路由和NAT转发正常;若不通,先查宿主机net.ipv4.ip_forward是否开启、安全组出方向规则是否放行TCP/UDP。
② nslookup www.baidu.com 8.8.8.8 —— 强制指定公共DNS发起查询。如果返回IP,证明容器能发请求、也能收响应,只是默认DNS服务器不可用;如果超时或报connection timed out,说明容器发出的DNS请求被拦截或丢弃。
③ cat /etc/resolv.conf —— 查看当前生效的DNS配置。注意:Docker 20.10+默认写入nameserver 127.0.0.11,这是Docker内置DNS代理地址,不是真实DNS服务器;若此处出现127.0.0.1或内网DNS(如192.168.1.1),而宿主机本身又无法访问该地址,则必然失败。
第二步:临时验证DNS修复效果
方法一:直接覆盖容器内resolv.conf(仅限调试)
在容器中执行:echo "nameserver 8.8.8.8" > /etc/resolv.conf,然后立即测试nslookup google.com。这一步能快速验证是否为DNS配置错误导致——但【此操作在容器重启后失效,且可能被Docker守护进程自动覆盖】。
方法二:使用--dns参数重跑容器(推荐)
docker run --dns 114.114.114.114 --dns 8.8.8.8 -it ubuntu:22.04 ping -c 2 baidu.com。这个命令绕过所有全局配置,强制注入两个可靠DNS,适合快速验证环境兼容性。若成功,说明问题出在Docker daemon默认策略或网络模式上。
第三步:永久修复DNS配置
方案1:修改Docker daemon全局配置(影响所有新容器)
编辑/etc/docker/daemon.json,加入"dns"字段:
{ "dns": ["114.114.114.114", "8.8.8.8"] }
保存后执行:sudo systemctl restart docker。注意:【此操作不会自动更新已运行容器的DNS,只对后续启动的容器生效】。
方案2:挂载宿主机resolv.conf(适用于企业内网DNS)
若宿主机DNS可正常解析(nslookup baidu.com返回正确结果),可让容器复用它:
docker run -v /etc/resolv.conf:/etc/resolv.conf:ro -it ubuntu:22.04 nslookup google.com
该方式避免了硬编码DNS,也规避了Docker自动生成127.0.0.11带来的不确定性,特别适合阿里云等云主机上宿主机DNS已配置好内网解析的场景。
方案3:为自定义网络单独指定DNS
先创建网络:docker network create --driver bridge --opt com.docker.network.bridge.enable_ip_masquerade=true --dns 114.114.114.114 mynet,再运行容器:docker run --network mynet -it ubuntu:22.04 nslookup google.com。这种方式隔离性强,不影响默认bridge网络,适合多租户或混合DNS策略环境。











