
1. 问题现象与初步诊断当你进入Docker容器执行ping google.com时看到Temporary failure in name resolution错误但ping 8.8.8.8却能正常通信这就像你的手机能拨通电话号码却无法通过联系人名字拨打——问题出在域名解析环节。这种情况通常表明容器内的DNS配置出现了问题。我遇到过最典型的场景是开发环境突然无法拉取镜像CI/CD流水线报错或者微服务之间突然无法通过服务名通信。先别急着改配置让我们用以下命令做个快速诊断# 检查容器内DNS配置 docker exec -it 容器名 cat /etc/resolv.conf # 测试基础网络连通性 docker exec -it 容器名 ping -c 4 114.114.114.114 # 检查域名解析 docker exec -it 容器名 nslookup google.com如果第一个命令返回空值或异常的DNS服务器地址第二个能通但第三个失败那就确认是DNS问题。这里有个容易忽略的细节不同Docker网络模式下的/etc/resolv.conf生成机制完全不同我们会在第三章详细展开。2. 主机层网络检查2.1 IP转发与防火墙配置就像快递中转站必须允许包裹转发一样Linux主机需要开启IP转发功能。我曾在CentOS环境遇到因为ip_forward未开启导致容器网络异常的案例# 检查ip_forward状态 cat /proc/sys/net/ipv4/ip_forward # 返回1表示已开启 # 若返回0需要永久启用 echo net.ipv4.ip_forward 1 /etc/sysctl.conf sysctl -p防火墙配置更是常见坑点。某次生产环境故障就是因为firewalld的masquerade未开启# Firewalld检查 firewall-cmd --query-masquerade # 返回yes表示正常 # 若返回no需要执行 firewall-cmd --add-masquerade --permanent firewall-cmd --reload # UFW防火墙需放行DNS端口 ufw allow 53/udp ufw allow 53/tcp2.2 宿主DNS服务状态主机自身的DNS解析异常会直接影响到容器。曾经有台Ubuntu服务器因为systemd-resolved服务崩溃导致所有容器解析失败# 检查systemd-resolved状态 systemctl status systemd-resolved # 检查DNS缓存服务 nscd -g | grep hosts cache dnsmasq --test建议同时检查/etc/resolv.conf内容是否合理。我见过有人误删这个文件导致整个系统DNS瘫痪的案例。正常应该包含有效的nameserver记录比如nameserver 8.8.8.8 nameserver 114.114.114.1143. Docker网络模式深度解析3.1 桥接模式下的DNS机制默认的bridge网络模式下Docker会通过内置的DNS服务器(127.0.0.11)处理容器请求。这就像公司内网的行政前台负责把部门名字转成分机号。但有以下几种情况会导致前台罢工自定义网络未启用DNSdocker network inspect 网络名 | grep EnableIPv6容器启动时覆盖了DNS配置# 错误的启动方式示例 docker run --dns ...宿主机防火墙阻断了DNS流量3.2 Host网络模式对比使用--networkhost时容器直接复用主机网络栈相当于省去了前台中转。但这种方式优点直接使用主机DNS配置网络性能更好缺点端口冲突风险失去网络隔离性我曾帮客户排查过一个经典案例他们的监控容器在host网络下解析正常但业务容器在bridge网络下解析失败最终发现是Docker守护进程的DNS配置被误删。4. Docker DNS配置大全4.1 全局DNS配置修改/etc/docker/daemon.json是最稳妥的方案记得备份原文件{ dns: [114.114.114.114, 8.8.8.8], dns-opts: [timeout2, attempts2], dns-search: [mydomain.com] }配置后必须重启Docker服务systemctl restart docker重要提示在Kubernetes集群中这样修改会影响所有节点需要谨慎操作。我遇到过某次批量修改导致集群DNS瘫痪的事故。4.2 单容器DNS设置对于特定容器可以在运行时指定docker run --dns223.5.5.5 --dns-searchdev.svc.cluster.local ...或者使用docker-compose.ymlservices: app: dns: 223.5.5.5 dns_search: dev.svc.cluster.local4.3 特殊场景处理当使用自定义网络时建议显式指定DNSdocker network create --driverbridge --subnet172.28.0.0/16 \ --gateway172.28.5.1 --opt com.docker.network.bridge.namedocker1 \ --dns8.8.8.8 my-bridge-network在Swarm模式下需要修改/etc/docker/daemon.json后滚动重启节点。5. 高级排错技巧5.1 诊断工具集# 查看容器完整配置 docker inspect --format{{.NetworkSettings}} 容器名 # 抓取DNS查询包 docker run --rm --netcontainer:目标容器名 nicolaka/netshoot \ tcpdump -i any -n udp port 53 # 使用dig工具测试 docker run --rm --dns8.8.8.8 radial/busyboxplus dig google.com5.2 典型故障树根据经验整理出以下排查路径检查容器内/etc/resolv.conf内容验证基础网络连通性测试DNS服务器可达性检查防火墙规则审查Docker守护进程配置检查自定义网络设置5.3 日志分析要点重点关注以下日志关键词Temporary failure in name resolutionName or service not knownDNS timeoutServfail在Kubernetes环境中还需要检查CoreDNS或kube-dns的日志kubectl logs -n kube-system -l k8s-appkube-dns6. 生产环境最佳实践6.1 配置规范建议所有环境统一DNS配置为不同环境设置不同的搜索域开发环境dev.example.com生产环境prod.example.com设置合理的超时和重试参数重要服务配置DNS缓存6.2 监控方案建议监控以下指标DNS查询延迟DNS查询失败率DNS缓存命中率Prometheus示例配置- job_name: container_dns metrics_path: /metrics static_configs: - targets: [dns-exporter:9100]6.3 灾备方案主备DNS服务器配置dns: [主DNS, 备DNS]定期测试DNS故障转移准备应急脚本快速切换DNS7. 跨平台注意事项7.1 macOS/WSL特殊处理在Docker Desktop for Mac中需要修改~/.docker/daemon.json{ dns: [host.docker.internal] }WSL2环境下建议# 在/etc/wsl.conf中添加 [network] generateResolvConf false7.2 云环境适配各大云厂商的DNS服务AWSVPC DNS服务器阿里云100.100.2.136/100.100.2.138腾讯云183.60.83.19/183.60.82.98在Kubernetes集群中CoreDNS配置示例apiVersion: v1 kind: ConfigMap metadata: name: coredns data: Corefile: | .:53 { forward . 8.8.8.8 223.5.5.5 cache 30 }8. 终极解决方案当所有常规方法都失效时可以尝试以下杀手锏完全重置Docker网络systemctl stop docker rm -rf /var/lib/docker/network systemctl start docker使用第三方网络插件docker plugin install weaveworks/net-plugin:latest切换为Containerd运行时最后提醒每次修改配置后建议按顺序执行以下验证# 测试基础解析 docker run --rm busybox nslookup google.com # 测试服务发现 docker run --rm --networkmy-network busybox nslookup service-name # 测试外部连通性 docker run --rm busybox ping -c 4 baidu.com