← 全部笔记

Docker · 5 容器网络

同一自定义网络,按名字找到彼此

给容器起名还不够:把它们接入同一个自定义 bridge 网络,Docker 才会自动解析彼此的名字。

约 15 分钟 · 截至 2026-11-03,Docker Engine 29.x · 实验未实测

图 1 默认配置下,两种 bridge 都能在网内传包;自定义网络还提供容器名自动解析。

先预测

有名字还不够

DNS(Domain Name System,域名系统)把名字转换为 IP 地址。--name 给容器命名;能否用这个名字找到它,还取决于双方连接的网络。

A、B 都有 --name,使用相同镜像。第一组接默认 bridge,第二组接同一自定义 bridge。A 按 B 的容器名 ping,哪组默认能成功?假设容器正常运行,未改网络配置。

第二组能自动解析。默认 bridge 不提供这项容器名解析能力,但网内按 IP 通信默认可行。自定义网络提供有作用范围的名字解析,前提是双方共享该网络。依据:bridge 网络差异。

自定义 bridge 网络是你用 docker network create 建立的本机容器网络。bridge 是驱动类型;bridge 同时也是那个默认网络的名字。名字不同的两个自定义网络,也有各自的边界。

默认 bridge 能手动补上名字吗?

能,例如旧式 --link 或手动配置 hosts。它们不属于默认的自动 DNS 解析,本页不采用。也不要把宿主机能识别一个名字,等同于容器也能识别。

若需要回顾镜像与运行实例,先读镜像、容器与仓库;需要回顾 run 的创建过程,可读第一次 docker run。

拆开机制

先查名字,再发包

在自定义网络内,容器使用 Docker 的内置 DNS,地址为 127.0.0.11。它是容器内看到的回环地址,不是对端容器 IP,也不是要填写到宿主机网卡上的地址。

A 先解析 B 的名字,再向 B 发包 示意图:A 内的 ping 查询内置 DNS 127.0.0.11,DNS 按共同网络返回 B 的实际 IP。之后 ICMP 请求和响应直接在 A、B 之间流动,不由 DNS 转发。 lp25-a · 网络命名空间 ping 内置 DNS 127.0.0.11 lp25-b同一网络 ping lp25-b 查询 lp25-b 网内记录:lp25-b对应 B 的实际 IP 返回 B 的 IP 按 B 的 IP 发送 ICMP 请求 B 向 A 返回 ICMP 响应
  1. A 运行 ping lp25-b,需要先得到目的 IP。先猜:A 要向哪个地址询问这个名字?
  2. 名称解析请求发给容器内的 127.0.0.11。
  3. 内置 DNS 查找共同网络中的容器名记录。这里双方都连接 lp25-lab。
  4. DNS 返回 B 的实际 IP,查名字阶段完成。先猜:后续 ping 的数据包还要交给 DNS 转发吗?
  5. A 直接向 B 的 IP 发出 ICMP 请求;ICMP 是 ping 使用的控制报文协议。
  6. B 返回 ICMP 响应。DNS 只负责解析,不承担这段数据传输。
图 2 名字解析和 IP 通信是两个阶段;图中省略网桥与虚拟网卡,只保留查询和传包关系。

同网的应用若监听了容器端口,其他容器可以访问该端口,无需先用 -p 发布。ping 测的是 ICMP 可达性,不能证明某个 TCP 服务已经启动。

127.0.0.11、localhost 与外部域名

localhost 通常指本容器的回环地址,不能用来找另一个独立容器。网络命名空间是容器各自的网络视图,包含接口、路由和回环接口。内置 DNS 在这个视图中提供服务;外部域名查询会转发给宿主机配置的 DNS。默认 bridge 则获得宿主机 DNS 配置的副本。见官方 DNS services。

A 能把 B 的名字解析成 IP,但访问 B 的 TCP 端口提示拒绝连接。下一步先查什么?

127.0.0.11 是解析服务的地址;它不承载 B 的应用。

已经拿到 IP,说明名字解析完成。同网访问容器端口也不要求 -p。

查到地址不代表端口上有服务。“拒绝连接”应继续检查应用和监听状态,例如是否只监听了 B 自己的回环地址。

动手验证

让两个容器互 ping

未实测 · 会改动网络

以下命令尚未在本环境执行:这里没有 Docker。预期现象依据官方文档,具体输出由维护者补测。请在自己的学习环境运行:同一 Docker Engine 的 Linux 容器,默认 bridge 配置,Docker CLI 可连接守护进程。Docker Desktop 请切到 Linux 容器。

创建 bridge 会由 Docker 管理宿主机的网桥、路由及防火墙规则;Desktop 中这些改动发生在 Linux 虚拟机里。无需手改 iptables 或使用 --privileged。首次运行可能拉取 BusyBox 镜像;busybox:1.37 是本实验选用的标签,不表示本机已验证版本。

下面全部命令都在宿主机的同一个 POSIX shell 中执行。保留这个终端,后面还要用到变量。先确认 lp25- 前缀未被其他实验占用;若冲突,请统一换名,不要删除别人的资源。

① 建网并启动 A、B

docker network create --driver bridge lp25-lab
docker run --rm -d --name lp25-a --network lp25-lab busybox:1.37 sleep 3600
docker run --rm -d --name lp25-b --network lp25-lab busybox:1.37 sleep 3600

预期现象(未实测):建网成功返回网络 ID;两次 run 各返回容器 ID。sleep 3600 让容器保持运行一小时,方便执行后续命令;退出后 --rm 自动删除容器。

② 看 DNS,再双向 ping

docker exec lp25-a cat /etc/resolv.conf
docker exec lp25-a ping -c 2 -W 2 lp25-b
docker exec lp25-b ping -c 2 -W 2 lp25-a

预期现象(未实测):解析配置包含指向 127.0.0.11 的 nameserver 项。两次 ping 各应收到两份响应,命令退出码为 0。实际 IP、耗时和完整输出以你机器为准;-c 2 限制请求数,-W 2 限制等待响应的秒数。

③ 与默认 bridge 对照

临时探针容器是只运行一次检测命令的容器,退出即删除。这里显式选 bridge,避免依赖环境的默认选择。

docker run --rm -d --name lp25-default --network bridge busybox:1.37 sleep 3600
docker run --rm --network bridge busybox:1.37 ping -c 2 -W 2 lp25-default
default_ip=$(docker inspect --format '{{(index .NetworkSettings.Networks "bridge").IPAddress}}' lp25-default)
docker run --rm --network bridge busybox:1.37 ping -c 2 -W 2 "$default_ip"

预期现象(未实测):按名测试在解析阶段失败,退出码非 0;按实际 IP 测试应收到响应。这排除了“默认 bridge 完全不能通信”的误解。inspect --format 从容器详细配置中取出指定网络的实际 IP,不要抄一个固定 IP。

不看上面的命令:要让新容器接入已存在的 lp25-lab,补哪一个参数值?

docker run --rm --network busybox:1.37 ping -c 2 lp25-b

--network lp25-lab 指定连接的网络;它不是容器名字,也不是镜像名字。该一次性探针可在同网内解析 lp25-b。

验证边界

跨网络分两层查

不同 bridge 网络默认隔离。只看到名字查不到,还不能证明 IP 也不可达;你需要再绕过 DNS,直接测试对端的实际 IP。

图 3 不共享网络时,名字的作用范围和直接 IP 通信的隔离分别生效。

other 只连 lp25-island。你把 B 的实际 IP 告诉它,它就能直接 ping 通 B 吗?先说明你的判断依据。

默认不能。知道 IP 只是跳过 DNS,Docker 对不同 bridge 的直接流量仍有隔离规则。这里假设没有自定义路由或防火墙放行,也没有把 other 再接到 lp25-lab。

docker network create --driver bridge lp25-island
docker run --rm -d --name lp25-other --network lp25-island busybox:1.37 sleep 3600
docker exec lp25-other ping -c 2 -W 2 lp25-b
b_ip=$(docker inspect --format '{{(index .NetworkSettings.Networks "lp25-lab").IPAddress}}' lp25-b)
docker exec lp25-other ping -c 2 -W 2 "$b_ip"

预期现象(未实测):第一条 ping 无法解析 B 的名字;第二条已有 IP,却收不到响应,可能表现为超时或不可达。两条命令都应非 0 退出。错误措辞依环境而变,不要把两种失败原因混为一谈。

默认配置下的实验判读(预期,未实测)
位置与目标名字解析直接 ping IP
同一默认 bridge无自动容器名解析可达
同一自定义 bridge自动解析网内名字可达
两个独立 bridge,无共同网络查不到对方网内名字默认隔离
隔离的边界:不是“任何路径都不通”

这里测试的是不同 bridge 之间直接访问容器 IP。发布到宿主机的端口(-p)可成为另一条访问路径;自定义路由和防火墙设置也可能改变结果。一个容器还能连接多个网络:只要双方共享某个网络,就不能套用“两网隔离”的结论。普通自定义 bridge 通常仍能访问外网,“网络之间隔离”不等于“断网”。见发布端口与多网络连接。

清理本页资源

docker stop lp25-a lp25-b lp25-default lp25-other
docker network rm lp25-lab lp25-island

容器用了 --rm,停止后自动删除;再删除两个网络。若一小时已过,容器可能早已自动删除,停止时报“找不到”可跳过。网络若提示仍在使用,先检查成员,不要强删其他容器。

docker network inspect lp25-lab lp25-island

查看结果中的 Containers 成员;仅在确认没有其他使用者后,停止本页的残留容器并重试删除网络。本页不使用全局 prune;拉取的 BusyBox 镜像保留在本地。

间隔检索

记住四个判断

A、B 原来能按名字互 ping。后来重建 B 时漏了 --network,B 进入默认 bridge。A 还在 lp25-lab。最直接的修复是什么?

公共 DNS 不管理本机 Docker 网络内的容器名。

写死 IP 不能解除 bridge 之间的默认隔离;重建后 IP 也可能变化。

先恢复共同网络,再验证名字解析和通信。重建时指定 --network lp25-lab,能把网络归属明确写在启动命令里。已有运行容器也可用 docker network connect 接入网络,详见官方命令文档。

向同事解释:为什么“能解析名字”“能 ping”“应用能连接”是三个需要分别检查的判断?

DNS 只把名字变成 IP;ping 检查 ICMP 请求和响应;应用还需要正确的端口、监听地址和服务状态。

  • 提到 DNS 解析与 IP 可达性是两个阶段。
  • 提到同网才能使用网内自动容器名解析。
  • 提到 ping 成功并不等于 TCP 应用可用。

核查依据

来源与实测状态

官方资料核查于 2026-11-03,页面适用范围为 Docker Engine 29.x 的 Linux 容器及默认 bridge 驱动配置。以下命令均未实测,本页没有伪造终端记录;预期现象待维护者在实际环境补测。

  1. Bridge network driver:默认与自定义 bridge 的名字解析、网内互通、隔离及宿主机网络改动。
  2. Networking overview:内置 DNS 127.0.0.11、外部查询转发、多网络连接和发布端口。
  3. docker network create:创建 bridge 网络及默认驱动。
  4. docker run:--rm、--name、--network、后台运行。
  5. docker exec 与 docker inspect:容器内执行命令与读取指定网络 IP。
  6. Docker Official Images 的 BusyBox 标签清单:确认本页选用的 1.37 标签存在;不代替运行验证。
  7. docker network inspect 与 docker network rm:检查网络成员及清理。