欢迎光临
我们一直在努力

Docker 容器无法访问外网?DNS 与网络故障排查教程

在 Linux 云服务器上部署 Docker 后,有时会遇到这样的问题:

  • 宿主机可以正常访问互联网;
  • Docker 容器却无法访问外网;
  • ping 1.1.1.1 不通;
  • ping baidu.com 或 curl 域名失败;
  • 容器内 apt update、yum、dnf 无法下载;
  • Docker 重启后网络突然异常。

这类问题不一定是 Docker 本身故障,也可能与 DNS、系统转发、防火墙、iptables 或宿主机网络配置有关。

Docker 容器无法访问外网

下面按照从简单到复杂的顺序进行排查。


一、先确认宿主机网络是否正常

首先不要直接修改 Docker 配置,需要确认服务器自身能否访问互联网。

执行:

ping -c 4 1.1.1.1

再测试 DNS:

ping -c 4 www.baidu.com

或者:

curl -I https://www.baidu.com

如果服务器本身就无法访问互联网,那么问题通常不在 Docker,需要先检查:

  • 云服务器网关;
  • DNS;
  • 防火墙;
  • 路由;
  • 安全组;
  • 上游网络。

如果宿主机访问正常,而容器访问失败,再继续排查。


二、检查 Docker 容器是否能访问 IP

先进入存在问题的容器:

docker exec -it 容器名称 bash

部分精简镜像没有 Bash,可以使用:

docker exec -it 容器名称 sh

然后测试:

ping -c 4 1.1.1.1

如果镜像没有 ping 命令,也可以:

curl -I https://1.1.1.1

这里主要分成两种情况。

情况一:IP 可以访问,但域名无法访问

例如:

ping 1.1.1.1

正常,但是:

ping www.baidu.com

提示:

Temporary failure in name resolution

这种情况基本可以优先检查 DNS。

情况二:IP 和域名都无法访问

这种情况需要进一步检查 Docker 网桥、IP 转发、iptables 和防火墙。


三、检查 Docker DNS

Docker 容器中经常可以看到:

cat /etc/resolv.conf

输出类似:

nameserver 127.0.0.11

这里的:

127.0.0.11

是 Docker 自带的内部 DNS,并不代表配置错误。

Docker 会通过内部 DNS 再转发到宿主机或指定的上游 DNS。

可以先查看宿主机:

cat /etc/resolv.conf

例如:

nameserver 223.5.5.5
nameserver 119.29.29.29

如果宿主机 DNS 本身存在问题,Docker 容器也可能无法正常解析。


四、给 Docker 指定 DNS

如果确定是 DNS 问题,可以考虑给 Docker Daemon 指定 DNS。

编辑:

nano /etc/docker/daemon.json

如果文件不存在可以直接创建。

例如:

{
  "dns": [
    "223.5.5.5",
    "119.29.29.29"
  ]
}

如果服务器主要位于境外,也可以根据实际网络情况选择适合的 DNS。

修改完成后检查 JSON 格式,然后重启 Docker:

systemctl restart docker

再重新测试容器:

docker exec -it 容器名称 cat /etc/resolv.conf

以及:

docker exec -it 容器名称 ping -c 4 www.baidu.com

需要注意,重启 Docker 可能影响正在运行的业务,生产环境建议提前安排维护时间。


五、检查 Linux IP 转发

Docker 默认需要 Linux 的 IP 转发功能。

执行:

sysctl net.ipv4.ip_forward

正常通常应该是:

net.ipv4.ip_forward = 1

如果显示:

net.ipv4.ip_forward = 0

可以临时开启:

sysctl -w net.ipv4.ip_forward=1

再检查:

sysctl net.ipv4.ip_forward

如需永久生效,可以检查:

/etc/sysctl.conf

或:

/etc/sysctl.d/

确保存在:

net.ipv4.ip_forward=1

然后:

sysctl --system

六、检查 Docker 网桥

查看 Docker 网络:

docker network ls

通常会看到:

bridge
host
none

继续:

ip addr show docker0

正常情况下会看到类似:

docker0
172.17.0.1/16

如果 docker0 不存在,可以查看 Docker 服务状态:

systemctl status docker

以及日志:

journalctl -u docker --no-pager -n 100

重点检查是否出现:

network
bridge
iptables
failed

等错误。


七、检查容器默认路由

进入容器:

docker exec -it 容器名称 sh

执行:

ip route

正常通常类似:

default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0

如果没有:

default

默认路由,容器自然无法访问外网。

这时候建议先检查 Docker 网络:

docker inspect 容器名称

重点查看:

IPAddress
Gateway
NetworkMode

八、检查 iptables NAT

Docker 容器通过宿主机访问互联网,一般需要 NAT。

可以执行:

iptables -t nat -L -n -v

重点看是否存在:

MASQUERADE

例如:

MASQUERADE  all  --  172.17.0.0/16

也可以:

iptables-save | grep -i MASQUERADE

如果 Docker 的 NAT 规则完全消失,容器可能无法访问互联网。

这种情况有时发生在:

  • 安装防火墙后;
  • 修改 iptables 后;
  • nftables 与 iptables 混用;
  • 执行防火墙清空脚本;
  • Docker 启动后又重新加载了防火墙规则。

九、检查 FORWARD 链

执行:

iptables -L FORWARD -n -v

注意默认策略。

如果看到:

Chain FORWARD (policy DROP)

并且 Docker 对应的允许规则不存在,就可能导致容器流量被拦截。

同时查看:

iptables -L DOCKER -n -v

以及:

iptables -L DOCKER-FORWARD -n -v

不同 Docker 版本对应规则名称可能有所区别。

不建议发现 DROP 后就直接把整个服务器改成:

iptables -P FORWARD ACCEPT

因为这可能影响服务器现有安全策略。

正确做法是先判断到底是哪条防火墙规则阻止了 Docker 流量。


十、检查 nftables

Debian 12、Ubuntu 新版本以及部分 Linux 系统可能同时涉及 nftables。

执行:

nft list ruleset

如果服务器同时存在:

iptables

和:

nftables

规则,需要注意两套防火墙之间是否存在冲突。

特别是安装:

  • 宝塔防火墙;
  • 第三方安全软件;
  • 自定义防火墙脚本;

之后,如果 Docker 突然无法访问互联网,可以重点检查这一部分。


十一、测试 Docker 新容器

如果只有某个容器没网,而其他容器正常,那么问题可能来自该容器自己的网络配置。

可以新启动一个临时容器测试:

docker run --rm alpine ping -c 4 1.1.1.1

再测试域名:

docker run --rm alpine ping -c 4 www.baidu.com

如果新容器正常,而原来的容器不正常,重点检查原容器:

docker inspect 容器名称

包括:

  • NetworkMode;
  • DNS;
  • Gateway;
  • 自定义网络;
  • Docker Compose 网络配置。

十二、Docker Compose 也要检查 DNS

如果通过 Docker Compose 部署,可以检查:

services:
  app:
    dns:
      - 223.5.5.5
      - 119.29.29.29

然后:

docker compose down
docker compose up -d

不过不建议在没有确定 DNS 存在问题之前盲目修改。


十三、检查宿主机是否设置代理

部分服务器可能安装过:

  • Clash;
  • Xray;
  • sing-box;
  • OpenVPN;
  • WireGuard;
  • HTTP/SOCKS 代理;
  • 透明代理。

检查环境变量:

env | grep -i proxy

例如出现:

HTTP_PROXY
HTTPS_PROXY
ALL_PROXY

还可以检查 Docker:

systemctl show docker | grep -i proxy

某些代理配置被删除或代理服务停止以后,也可能导致 Docker 拉取镜像或容器访问互联网异常。


十四、Docker 拉取镜像失败不一定等于容器没网

例如:

docker pull nginx

失败,并不一定说明 Docker 容器本身无法访问互联网。

可以分别测试:

curl -I https://registry-1.docker.io

以及:

docker run --rm alpine ping -c 4 1.1.1.1

这样才能区分:

  • Docker Registry 访问问题;
  • DNS 问题;
  • Docker 容器整体网络问题。

十五、推荐的排查顺序

遇到 Docker 没网时,可以按照下面顺序快速定位:

1. 宿主机能不能访问互联网
        ↓
2. 容器能不能访问 IP
        ↓
3. 容器能不能解析域名
        ↓
4. 检查 /etc/resolv.conf
        ↓
5. 检查 net.ipv4.ip_forward
        ↓
6. 检查 docker0
        ↓
7. 检查容器默认路由
        ↓
8. 检查 iptables NAT
        ↓
9. 检查 FORWARD
        ↓
10. 检查 nftables / 宝塔防火墙

如果:

ping 1.1.1.1

正常,但:

ping www.baidu.com

失败,就优先查 DNS。

如果两个都失败,则优先查:

路由
IP Forward
NAT
iptables
防火墙

这样排查效率通常会高很多。


总结

Docker 容器无法访问外网,最常见的问题主要集中在:

  • DNS 解析异常;
  • Linux IP Forward 未开启;
  • Docker NAT 规则丢失;
  • iptables FORWARD 拦截;
  • nftables 与 Docker 规则冲突;
  • 第三方防火墙重新加载规则;
  • 容器自身网络配置错误。

对于长期运行 Docker、网站、数据库或监控系统的云服务器,建议除了关注 CPU、内存和磁盘之外,也定期检查服务器网络、防火墙和 Docker 服务状态。

在莱卡云等云服务器上部署 Docker 时,如果遇到容器网络异常,也建议先按照本文从宿主机到容器逐层测试,而不是直接重装 Docker。很多情况下,问题只是 DNS 或防火墙规则发生变化,定位后即可处理。

赞(0)
未经允许不得转载:莱卡云 » Docker 容器无法访问外网?DNS 与网络故障排查教程