自定义 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 网络(格式:),并支持通过服务名进行 DNS 解析。
总结
自定义 bridge = 默认 bridge 的”增强版”。最大的优势是自动 DNS 解析(容器名→IP)和更好的隔离性。面试中说清楚”为什么自定义 bridge 是生产环境标配”就能体现对 Docker 网络的深度理解。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容