Docker 容器启动正常,端口也能映射,但在容器内执行 curl、拉取依赖或连接第三方 API 时一直超时,这是服务器运维中很常见的一类问题。它看起来像“容器断网”,实际可能发生在 DNS 解析、容器路由、Docker 网桥、主机转发、防火墙或上游网络中的任意一层。
排查这类故障,最重要的是先把“域名解析失败”和“IP 链路不通”分开。不要一开始就重启 Docker、关闭防火墙或删除全部网络,这些操作既可能扩大影响,也容易掩盖真正原因。

一、先确认故障范围
先在宿主机测试外网和 DNS:
curl -I --connect-timeout 5 https://www.example.com
getent hosts www.example.com
再进入故障容器执行相同测试:
docker exec -it <容器名或ID> sh
容器镜像中如果有 curl、getent 或 ping,可以依次检查:
cat /etc/resolv.conf
ip route
getent hosts www.example.com
curl -I --connect-timeout 5 https://www.example.com
精简镜像可能没有这些工具。不要为了测试直接修改生产容器,可以启动一个临时排障容器,并让它加入相同网络:
docker run --rm -it --network <网络名> nicolaka/netshoot
根据结果,故障通常可以先分为四类:
| 现象 | 优先检查方向 |
|---|---|
| 宿主机和容器都不能访问外网 | 云平台安全策略、宿主机路由、上游网络 |
| 宿主机正常,所有容器都不通 | Docker 转发、NAT、防火墙、daemon 配置 |
| 只有一个容器或一个网络不通 | 容器网络模式、自定义网络、默认网关 |
| IP 可以访问,域名不能解析 | /etc/resolv.conf、Docker DNS、上游 DNS |
二、区分 DNS 故障和网络不通
先尝试访问一个已知 IP,再测试域名。不同环境可能禁止 ICMP,因此 ping 失败不能单独证明网络中断,更可靠的办法是测试 TCP 连接:
curl -I --connect-timeout 5 http://1.1.1.1
getent hosts www.example.com
如果 IP 能连接而域名解析失败,重点查看容器中的 DNS 配置:
cat /etc/resolv.conf
使用默认 bridge 网络时,容器通常会获得宿主机 DNS 配置的副本;使用用户自定义网络时,Docker 会提供内置 DNS,并把外部查询转发给宿主机配置的 DNS 服务器。因此,宿主机的 /etc/resolv.conf、本地 DNS 服务或企业内网 DNS 出现异常,都可能传递到容器。
可以先为单个容器临时指定 DNS 验证判断:
docker run --rm --dns 1.1.1.1 alpine nslookup www.example.com
如果临时指定 DNS 后恢复,再考虑为 Docker daemon 配置稳定的 DNS。编辑前先备份 /etc/docker/daemon.json,并确保它是合法 JSON:
{
"dns": ["1.1.1.1", "8.8.8.8"]
}
验证配置后再重启 Docker:
dockerd --validate --config-file=/etc/docker/daemon.json
systemctl restart docker
重启 Docker 可能影响正在运行的业务容器,应安排维护窗口。企业内网环境还要确认公共 DNS 是否能够解析内部域名,不要直接用公共 DNS 覆盖公司 DNS。
三、检查容器网络模式和默认网关
查看容器使用的网络模式、IP 地址和网关:
docker inspect <容器名或ID>
docker network inspect <网络名>
重点关注 NetworkMode、IPAddress、Gateway 和容器连接的网络名称。容器内也可以检查路由:
ip addr
ip route
正常情况下应存在一条默认路由,例如:
default via 172.18.0.1 dev eth0
常见问题包括:
- 容器被配置为
network_mode: none,本身就不会获得外网连接。 - 自定义网络与宿主机、VPN 或其他 Docker 网络的网段冲突。
- 容器同时加入多个网络,错误的默认网关被选中。
- Compose 文件调整后只重启了进程,没有重新创建容器,旧网络配置仍在使用。
- 使用
macvlan、ipvlan或自定义路由时,上游交换机和路由器没有对应配置。
如果确认是网络配置问题,可以在评估影响后重新创建容器,而不是直接删除整个 Docker 网络:
docker compose up -d --force-recreate <服务名>
四、检查宿主机是否允许 IP 转发
Docker 的桥接网络需要宿主机在不同网络接口之间转发数据。检查 IPv4 转发状态:
sysctl net.ipv4.ip_forward
通常应返回:
net.ipv4.ip_forward = 1
如果该值为 0,要继续确认它为什么被关闭。临时开启可以用于验证:
sysctl -w net.ipv4.ip_forward=1
需要长期生效时,应通过发行版推荐的 sysctl 配置文件管理,而不是只修改运行时值。还要注意,启用转发会改变主机的网络行为,云服务器、VPN 网关或多网卡主机应同步检查安全策略。
五、检查 Docker NAT 和防火墙规则
桥接网络中的容器访问外网,通常依赖宿主机的转发和源地址转换。Docker 会根据网络和端口配置创建相应的防火墙规则;如果安全软件、运维脚本或防火墙重载清除了这些规则,容器可能突然失去外网连接。
先确认 Docker 使用的防火墙后端及现有规则,不要直接执行清空规则的命令:
docker info
iptables -S
iptables -t nat -S
nft list ruleset
如果服务器使用 firewalld,还可以检查:
firewall-cmd --state
firewall-cmd --get-active-zones
firewall-cmd --list-all
重点关注以下情况:
FORWARD链的默认策略或自定义规则阻止了 Docker 网桥流量。- Docker 的 NAT/MASQUERADE 规则被防火墙重载或第三方脚本覆盖。
DOCKER-USER链中存在过于宽泛的拒绝规则。- 云安全组、主机防火墙和 Docker 规则叠加后,实际出口被阻断。
- 系统从 iptables 切换到 nftables 后,旧脚本仍在操作另一套规则。
不要用 iptables -F、nft flush ruleset 或关闭 firewalld 作为长期解决方案。这类操作可能同时暴露数据库、管理端口和容器服务。更稳妥的做法是先导出规则,定位具体命中链,再添加最小范围的放行策略。
六、检查代理、VPN和云平台出口限制
有些容器可以访问普通网站,却无法访问代码仓库、镜像站或特定 API。这时还要检查:
- 宿主机是否通过 HTTP/HTTPS 代理出网,而容器没有设置代理变量。
- VPN 或 WireGuard 是否改写了默认路由、策略路由或 MTU。
- 云平台是否限制公网出口,或实例本身没有公网 IP、NAT 网关和正确路由。
- 企业网络是否要求使用内部 DNS、出口代理或白名单。
- 请求是否因为 IPv6 优先、路径 MTU 或 TLS 检查而超时。
查看容器中的代理变量:
env | grep -i proxy
如果使用 Compose,可以在服务级别明确设置代理,但不要把包含账号密码的代理地址写入公开仓库:
services:
app:
environment:
HTTP_PROXY: http://proxy.example:3128
HTTPS_PROXY: http://proxy.example:3128
NO_PROXY: localhost,127.0.0.1,.example.internal
七、按最小影响顺序恢复
完成定位后,建议按以下顺序处理:
- 修正单个容器或 Compose 服务的 DNS、网络和代理配置。
- 重新创建受影响的单个容器,验证问题是否消失。
- 修正宿主机转发、防火墙或 NAT 规则,并保存变更前后的规则快照。
- 只有在确认 daemon 配置或 Docker 规则异常时,才安排重启 Docker。
- 变更后同时验证 DNS、TCP 连接、业务 API 和容器重启后的持久性。
可以使用下面的简化检查清单复核:
# 宿主机
curl -I --connect-timeout 5 https://www.example.com
sysctl net.ipv4.ip_forward
docker info
# 容器和网络
docker inspect <容器名或ID>
docker network inspect <网络名>
docker exec <容器名或ID> cat /etc/resolv.conf
docker exec <容器名或ID> ip route
总结
Docker 容器无法访问外网,不等于 Docker 服务本身损坏。先比较宿主机和容器的结果,再把 DNS、路由、转发、NAT、防火墙和上游出口逐层拆开,通常能在不影响其他容器的情况下找到原因。
生产环境中最需要避免的是“为了恢复网络,先清空防火墙或重启所有服务”。正确的处理方式应当是保留现场、缩小范围、进行可回滚的最小修改,并在容器重新创建和服务器重启后再次验证。
参考资料
- Docker Docs: Networking overview
https://docs.docker.com/engine/network/
- Docker Docs: Bridge network driver
https://docs.docker.com/engine/network/drivers/bridge/
- Docker Docs: Packet filtering and firewalls
https://docs.docker.com/engine/network/firewall-iptables/
- Docker Docs:
docker network inspect
https://docs.docker.com/reference/cli/docker/network/inspect/
- Docker Docs: Configure the Docker daemon
https://docs.docker.com/engine/daemon/
核验日期:2026年8月25日




