在 Docker 中,容器之间“能启动却连不上”的问题,通常并不在应用本身,而在网络命名空间、虚拟网卡、网桥、DNS 或主机防火墙。每个采用默认网络隔离的容器都有独立的网络栈,包括网卡、路由表、端口和协议栈。因此,容器里的 127.0.0.1 只代表该容器自身,并不代表宿主机或其他容器。理解这一点,是排查容器间通信故障的起点。🔍
一、理解网络命名空间隔离
Docker 启动容器时,会为其创建或分配网络命名空间,并通过虚拟以太网设备将容器连接到 Docker 网络。以常见的 bridge 模式为例,虚拟网卡的一端位于容器内,另一端连接宿主机上的 Linux 网桥。处于同一用户自定义 bridge 网络中的容器可以直接通信,而未加入该网络的容器通常会受到隔离。
需要特别区分默认的 bridge 网络和用户自定义 bridge 网络。默认 bridge 网络通常不提供基于容器名称的自动解析,容器往往只能通过 IP 地址互访;用户自定义网络则支持自动 DNS 解析,可以使用容器名或网络别名访问服务。Docker 也建议多容器应用优先使用用户自定义网络,相关差异可参考 Docker Bridge 网络官方文档。
二、先确认容器是否位于同一网络
排查时,不要一开始就修改防火墙或重启 Docker。首先执行 docker network ls 查看现有网络,再使用 docker network inspect 网络名 检查目标容器是否同时出现在 Containers 列表中。如果两个容器连接到了不同的 bridge 网络,即使宿主机相同,也可能无法直接访问。
还可以执行 docker inspect 容器名,重点查看 NetworkSettings、Networks、IPAddress、Gateway 和 Aliases。若容器加入了多个网络,应确认应用实际使用的目标地址属于哪一个网段,避免请求被错误路由到不可达接口。
发现网络不一致时,可以使用 docker network connect 网络名 容器名 将运行中的容器接入目标网络;不再需要的连接可通过 docker network disconnect 网络名 容器名 移除。生产环境中更推荐修改 Compose 配置并重新部署,避免临时命令造成实际状态与配置文件不一致。
三、检查服务监听地址和端口
网络连通不代表应用端口一定可用。常见错误是服务只监听 127.0.0.1,此时只有当前容器内部能够访问。需要让其他容器连接时,服务一般应监听 0.0.0.0 或容器对应网卡地址。可在容器内执行 ss -lntp 或 netstat -lntp,确认目标端口是否真正处于 LISTEN 状态。
容器之间通过同一 Docker 网络通信时,应访问目标容器的内部端口,而不是宿主机映射端口。例如数据库在容器内监听 3306,即使配置了宿主机端口 13306,其他同网络容器通常仍应访问 db:3306。端口发布主要用于让宿主机或外部客户端进入容器,并不是容器间通信的必要条件。
易错点:在应用容器中配置数据库地址为 localhost,会让请求回到应用容器自身。正确做法通常是填写数据库容器名、Compose 服务名或网络别名。⚠️
四、逐层验证 DNS、路由与端口
- 验证名称解析:在源容器中执行 getent hosts 目标容器名 或 nslookup 目标容器名。若解析失败,检查双方是否加入同一用户自定义网络,以及服务名和别名是否填写正确。
- 验证 IP 可达性:使用 ping 目标IP 进行基础测试,但要注意精简镜像可能没有 ping 工具,目标也可能禁止 ICMP,因此 ping 失败不能直接等同于业务端口不可达。
- 验证 TCP 端口:使用 nc -vz 目标名 端口、curl -v 来源链接 或应用协议客户端测试。若 DNS 正常但端口被拒绝,通常说明服务未启动、监听地址错误或端口填写错误。
- 检查路由:在容器内执行 ip addr 和 ip route,确认网卡地址、子网掩码和默认网关正常。若地址与预期网段不符,应继续检查网络配置及 IP 地址池。
五、排查宿主机防火墙与 Docker 规则
Docker bridge 网络依赖宿主机的转发和网络过滤规则。若管理员手动清理 iptables 或 nftables 规则、关闭 IP 转发,或将 FORWARD 链默认策略设为拒绝,容器间流量可能被阻断。可检查 sysctl net.ipv4.ip_forward、iptables -L FORWARD -n -v、iptables -t nat -L -n -v,并观察是否存在异常丢包计数。
不要在不了解影响的情况下直接清空防火墙规则,这可能导致已发布端口失效、远程连接中断或隔离策略被破坏。更稳妥的方式是先备份现有规则,再结合系统日志和计数器定位具体链路。Docker 网络驱动的用途及隔离特征可查看 官方网络驱动说明。
六、Compose 环境中的典型故障
Docker Compose 默认会为项目创建独立网络,服务可通过服务名互相访问。常见故障包括:两个 Compose 项目分别创建了不同网络;手动指定 external 网络但该网络不存在;服务重建后 IP 改变,而应用仍缓存旧 IP;配置文件中使用了宿主机端口而非容器端口。
- 优先使用稳定的服务名,不要在配置中硬编码容器 IP。
- 需要跨项目通信时,显式创建共享网络,并让相关服务共同加入。
- 修改 networks、aliases 或端口后,使用 Compose 重新创建容器。
- 应用存在 DNS 缓存时,检查连接池和客户端是否能够重新解析地址。
七、推荐的故障定位顺序
建议按照“容器状态 → 网络归属 → DNS 解析 → 服务监听 → TCP 端口 → 路由 → 防火墙”的顺序排查。若问题仍未定位,可在宿主机或目标网络接口上使用 tcpdump 抓包:没有请求包说明问题位于源端、DNS 或路由;有请求但没有响应,重点检查目标服务和防火墙;出现响应却未返回应用,则继续检查回程路由、连接跟踪或地址冲突。
总结
Docker 容器网络故障的核心,是判断流量究竟在哪一层中断。先确认容器是否共享正确的网络命名空间连接关系,再检查名称解析、监听地址、内部端口、路由和宿主机过滤规则。日常部署中应优先采用用户自定义网络、服务名访问和声明式 Compose 配置,避免依赖动态 IP。只要坚持逐层验证而不是盲目重启,大多数容器间通信问题都能快速、稳定地定位。✅