容器跨网络通信失败的核心原因是未接入同一自定义网络,因默认bridge网络不支持服务名解析;需用docker network ls和inspect确认网络归属,再通过ping容器名、nslookup及nc测试dns解析与端口连通性。
容器跨网络通信失败,核心原因通常是容器没在同一个自定义网络里,或者网络配置本身有遗漏。排查重点不在“通不通”,而在“连没连对网”。
确认容器是否接入同一自定义网络
默认的 bridge 网络不支持服务名解析,跨容器通信必须使用自定义桥接网络。先查两个容器各自接入了哪些网络:
- 运行
docker network ls查看当前有哪些自定义网络(比如app-net) - 对每个容器执行:
docker inspect <container_name> --format='{{.NetworkSettings.Networks}}'</container_name>
输出应显示相同的网络名,例如"app-net":{...} - 如果一个在
app-net,另一个还在bridge或空值,说明根本没连对网
检查网络内 DNS 解析是否生效
自定义网络自带 Docker 内置 DNS,但只对容器名或 aliases 生效。验证方式很直接:
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
- 进入容器 A:
docker exec -it container_a sh - 执行:
ping container_b(注意是另一个容器的 名字,不是 IP) - 如果报
Name or service not known,说明 DNS 没起作用——常见原因是容器启动时没指定--network,或用docker-compose.yml时没统一声明networks字段 - 也可以手动查 DNS:
nslookup container_b,看是否返回对应 IP
验证网络连通性与端口可达性
能解析名字 ≠ 能通服务。DNS 正常后,还需确认目标容器的服务端口真正在监听、且没被拦截:
- 在容器 A 中执行:
nc -zv container_b 80(假设目标服务跑在 80 端口) - 如果连接拒绝(Connection refused),说明 container_b 的应用没起来,或监听地址写成了
127.0.0.1(应改用0.0.0.0) - 如果超时(timeout),可能是防火墙拦截,或容器 B 根本没暴露该端口(
EXPOSE只是声明,不等于开放;Docker 不强制校验) - 宿主机上若启用了
firewalld或ufw,也可能丢弃容器间流量,临时停用测试是否恢复
补充:Compose 场景下易忽略的点
用 docker-compose.yml 时,即使写了 networks,也容易踩坑:
- 服务没显式加入网络,而是依赖默认项目网络——但不同
docker-compose.yml文件默认网络互不相通 - 多个服务分散在不同
networks块里,却没做network_mode: "service:xxx"或external: true关联 -
depends_on只控制启动顺序,不解决网络连接问题;真正要连通,必须共网 - 推荐做法:在顶层
networks:下定义一个网络,所有服务都明确写networks: [- app-net]










