自定义 bridge 与默认差异

自定义 bridge 与默认差异

面试题

自定义 bridge 网络和默认 bridge 网络有什么区别?为什么推荐使用自定义 bridge?

标准答案

自定义 bridge 和默认 bridge 底层都基于 Linux 网桥技术实现,但在功能上有显著差异。简单来说:自定义 bridge = 默认 bridge 的功能超集。

核心区别一览

对比项 默认 bridge 自定义 bridge
创建方式 Docker 自动创建 docker network create
DNS 解析 ❌ 不支持容器名 ✅ 支持容器名 ↔ IP
IP 分配 自动,不可控 自动或手动指定
网络隔离 同一宿主机整体互通 网络间完全隔离
运行时连接/断开 ❌ 需重建容器 ✅ 支持
环境变量共享 支持 –link(已废弃) ❌ 无
子网自定义 ❌ 固定 172.17.0.0/16 ✅ 完全自定义
别名支持 ❌ 不支持 ✅ 支持

差异详解

1. 自动 DNS 解析(最关键区别)

# 默认 bridge:只能通过 IP 访问
docker run -d --name web nginx
docker run -d --name client alpine sleep 3600

docker exec client ping web
# ping: bad address 'web' ❌

# 自定义 bridge:自动 DNS 解析
docker network create mynet
docker run -d --name web --network mynet nginx
docker run -d --name client --network mynet alpine sleep 3600

docker exec client ping web
# PING web (10.0.0.2): 56 data bytes ✅

为什么重要: 微服务架构中服务通过名称互访是刚需。IP 会变,服务名不会变。

2. 网络隔离性

# 默认 bridge:所有容器在同一个网络
docker run -d --name app1 alpine sleep 3600
docker run -d --name app2 alpine sleep 3600
# app1 可以访问 app2(默认互通)

# 自定义 bridge:每个网络是一个独立广播域
docker network create net-a
docker network create net-b
docker run -d --name container-a --network net-a alpine sleep 3600
docker run -d --name container-b --network net-b alpine sleep 3600
# container-a 和 container-b 完全隔离 ❌

3. 运行时网络连接

# 默认 bridge:不能运行时连接/断开
docker run -d --name app alpine sleep 3600
# ❌ 无法动态加入默认 bridge
# 需要用 --network bridge 重新创建

# 自定义 bridge:运行时自由连接/断开
docker network connect mynet app
docker network disconnect mynet app
# 不需要重启容器 ✅

4. 固定 IP 分配

# 默认 bridge:不支持指定 IP
docker run -d --ip 172.17.0.10 nginx
# 报错 ❌

# 自定义 bridge:支持固定 IP
docker network create --subnet 10.0.0.0/16 mynet
docker run -d \
  --network mynet \
  --ip 10.0.0.50 \
  --name db \
  postgres:15 

5. 新增网络别名

# 自定义 bridge 支持网络别名
docker network connect --alias my-db --alias database mynet container

# 同一容器在不同网络中可以有不同的别名
docker network connect --alias api-v1 frontend myapp
docker network connect --alias worker backend myapp

为什么默认 bridge 不支持 DNS?

默认 bridge 的设计初衷是简单的容器网络连接。Docker 的嵌入式 DNS 服务(127.0.0.11)在设计时就只在自定义网络中启用:

# 验证:查看容器的 resolv.conf
# 自定义网络中的容器
docker exec web cat /etc/resolv.conf
# nameserver 127.0.0.11 ← Docker 内嵌 DNS
# options ndots:0

# 默认 bridge 中的容器
docker exec web cat /etc/resolv.conf
# 继承宿主机 DNS 配置
# nameserver 8.8.8.8
# nameserver 114.114.114.114

实际推荐

# ❌ 不推荐:依赖 --link 或硬编码 IP
docker run -d --name db --link web:web postgres

# ✅ 推荐:使用自定义 bridge
docker network create app-net
docker run -d --name db --network app-net postgres
docker run -d --name web --network app-net nginx
# db 中可以直接用 "web" 访问 nginx

迁移默认 bridge 容器到自定义网络

# 已有容器在默认 bridge
docker run -d --name myapp myapp:latest

# 创建自定义网络
docker network create app-net

# 将容器连接过去(保留原来的连接)
docker network connect app-net myapp

# 或者完全切换(断掉默认 bridge 连接)
docker network disconnect bridge myapp

不同自定义网络之间的隔离

# 两个不同的自定义网络完全隔离
docker network create frontend
docker network create backend

docker run -d --name web --network frontend nginx
docker run -d --name db --network backend postgres

# web 无法访问 db(即使在同一个宿主机上)
docker exec web curl db:5432  # ❌ 超时

面试追问

问:自定义 bridge 网络的数量有限制吗?

Docker 没有硬限制,但每个网桥占用一个子网和一个 Linux 网桥设备。大量创建可能耗尽 IP 池或影响性能。

问:容器可以同时连接默认 bridge 和自定义 bridge 吗?

可以。容器可以有多个网络接口。但默认 bridge 不支持通过容器名访问,所以只作为备选。

问:docker-compose 默认创建什么网络?

docker-compose 会自动为项目创建自定义 bridge 网络(格式:_default),并支持通过服务名进行 DNS 解析。

总结

自定义 bridge = 默认 bridge 的”增强版”。最大的优势是自动 DNS 解析(容器名→IP)和更好的隔离性。面试中说清楚”为什么自定义 bridge 是生产环境标配”就能体现对 Docker 网络的深度理解。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容