Docker 容器之间到底怎么互联?3 种写法一次讲清,附排查清单

编程狮(w3cschool.cn) 2026-10-26 10:34:35 浏览数 (59)
反馈

用 Docker 部署真实应用时,最现实的需求就是“容器 A 要能访问容器 B”,比如 Web 容器连数据库容器、前端容器调后端容器。本文先把结论放最前面:容器互联有三条主流路径——把容器放进同一个自定义桥接网络按名称互通、让容器直接共享宿主机网络栈、以及把端口映射到宿主机再由其他容器访问。三种写法的隔离性、性能和适用场景完全不同,选错就会连不通或踩到安全坑。下面把每种写法的配置命令、适用边界、性能取舍和常见失败原因讲清楚,并给出一张可直接照做的排查清单,帮你在 5 分钟内定位“为什么 ping 不通、为什么连不上端口”。如果你对 Linux 基础命令还不熟,建议先补一下常用命令再回来动手,会顺手很多。

Docker 容器之间怎么互联?

一、推荐写法:自定义桥接网络,按容器名互通

默认情况下,用 docker run 直接启动的容器都挂在一个匿名 bridge 上,它们之间不能按名称互相发现,只能靠易变的 IP 通信。正确做法是用 docker network create 建一个自定义网络,再把相关容器都连上去:

docker network create mynet
docker run -d --name db --network mynet mysql:8
docker run -d --name web --network mynet myweb:latest

连到同一自定义网络的容器,可以用容器名直接互相访问。比如在 web 容器里执行 mysql -h db 就能连上 db 容器,不再依赖 IP。这是生产环境最常用、也最稳的方案,因为它既有网络隔离,又省去了手工维护 IP 的麻烦。新增容器时只要带 --network mynet 即可自动加入互通名单。容器之间传递的数据本质上还是普通的 SQL 查询,所以网络通了之后,连接失败往往就变成了应用层账号或权限问题,排查思路要和纯网络问题分开。

二、写法二:host 网络共享宿主机栈

如果容器需要和对宿主机共用同一套网络命名空间,可以用 --network host:

docker run -d --network host myweb:latest

此时容器不再拥有独立 IP,直接复用宿主机的网络接口,访问 localhost 上的服务就能互相连通,网络性能也最好,没有额外的 NAT 开销。代价是失去了网络隔离——端口直接在宿主机上暴露,多个容器不能占用同一个宿主机端口,安全性也更低。它适合对网络延迟敏感、且只在单台主机内联调的场景,例如本地压测或临时排障。配套的 Node.js 服务 如果用 host 模式,要特别注意端口冲突。

三、写法三:端口映射到宿主机再访问

最朴素也最通用的方法是把容器端口发布到宿主机,再由宿主机上的其他容器或外部客户端访问:

docker run -d -p 3306:3306 --name db mysql:8
docker run -d -p 8080:80 --name web myweb:latest

web 容器通过宿主机的 host.docker.internal(Mac/Windows)或宿主机真实 IP 访问 db 的 3306 端口。这种方式跨主机也适用,但需要显式暴露端口,并且依赖宿主机地址配置。在单主机开发联调时非常直观,也是从本地开发过渡到多机部署的过渡形态。跨容器传递结构化数据时,常会用到 JSON 数据格式,它和是否走端口映射无关,但调试接口连通性时是关键的一环,建议先确认数据格式再排网络。

四、边界、版本与失败排查

容器连不通时,按下面顺序逐一核对,基本能覆盖九成的失败原因:

  1. 两个容器是否真的在同一网络?用 docker network inspect mynet 看 Containers 成员列表,确认两边都在;
  2. 用自定义网络时,是否用容器名而非 IP 访问(IP 会变,名字不会);
  3. 防火墙、云安全组或 iptables 是否拦了对应端口;
  4. 应用自身是否只监听了 127.0.0.1——容器里监听回环地址,外部一样连不进来,要改成监听 0.0.0.0;
  5. 跨主机场景,单纯 bridge 网络无法互通,需要 overlay 网络或端口映射。

性能层面要注意:bridge 网络经过一次 NAT 转发,高并发小包场景会有轻微延迟;host 网络没有这层开销但牺牲隔离;端口映射在跨主机时最灵活,但需要维护宿主机地址。版本层面,Docker 1.13 起 docker network 子命令已稳定,老版本用 docker run --link 的写法已被废弃,不要再依赖。需要直接在宿主机上确认网络状态、抓包或看路由时,可以配合 Linux 命令基础 里的工具,例如 ss、ip 和 tcpdump,它们能帮你看到容器流量到底走到哪一步。

具体排障时建议按“运行命令→观察输出→定位故障→修复配置”的闭环走:先运行 docker network inspect mynet 验证成员是否齐全,再运行 docker logs db 看对端应用是否真的在监听;如果发现应用只绑定了回环地址,就修复它的监听配置改为 0.0.0.0,然后重新运行容器验证连通性。很多“连不通”最终都落在应用监听地址或防火墙这两处,把它们逐一验证一遍,问题基本跑不掉。

Docker 容器互联三招

五、进阶:用 Compose 与 overlay 管理多容器

单机多容器用 Docker Compose 最省心,在 docker-compose.yml 里声明 networks 字段,所有服务默认加入同一个自定义网络,按 services 下的名字互相访问,不用手工 docker network create。跨主机集群则要上 overlay 网络,依赖 Docker Swarm 或 Kubernetes 的 CNI 插件,此时容器名解析交给集群的 DNS,单机的 bridge 规则不再适用。新手先把单机自定义桥接网络跑通,再考虑 Compose 与 overlay,避免在没理解网络模型前就堆叠复杂度。

总结

Docker 容器互联有三招:自定义桥接网络按容器名互通(隔离好、最常用)、host 网络共享宿主机栈(性能高、无隔离)、端口映射到宿主机再访问(通用、跨主机可用)。排查时先确认容器是否在同一网络、是否用名字而非易变 IP、应用是否监听 0.0.0.0,再看防火墙与安全组。把网络选型和监听地址这两点核对清楚,连不通的问题基本就能解决。新手优先用自定义桥接网络,等确需跨主机再升级到 overlay 或端口映射。

常见问题

Q:都用了默认 bridge,为什么容器名互相 ping 不通?

A:默认匿名 bridge 不支持按名称发现。要互通必须建自定义网络并用 --network 把容器都连上去,然后用容器名访问,不能依赖默认网络里的 IP。

Q:容器里服务监听 127.0.0.1 会被连不上吗?

A:会。回环地址只对本容器可见,其他容器访问的是容器间网络而非回环。应用要监听 0.0.0.0,其他容器才能访问到该端口。

Q:host 网络和 bridge 网络怎么选?

A:追求隔离和标准化用自定义 bridge;追求网络性能、且单机联调、可接受无隔离时用 host。生产环境更推荐 bridge 加端口映射的组合。

延伸学习

0 人点赞