容器网络是 Docker 最容易被低估、也最容易在生产环境中出问题的部分。很多开发者习惯用默认配置跑通 docker run 之后就很少再关注网络,直到遇到端口冲突、容器间无法通信、跨主机调度失败才回头补课。Docker 提供了四种基础网络模式——bridge、host、none 和 overlay,每一种都对应不同的隔离级别和通信需求。理解它们的底层机制和适用边界,比记住命令更重要。
bridge 模式:默认选项,也是最需要理解的一个
bridge 是 Docker 的默认网络模式。每次创建容器时,如果不指定 --network,Docker 会把它接入名为 docker0 的虚拟网桥。这个网桥本质上是一个 Linux bridge 设备,容器通过 veth pair 连接到网桥上,再由宿主机的 iptables NAT 规则完成对外通信。
# 查看默认 bridge 网络
docker network inspect bridge
# 创建自定义 bridge 网络
docker network create --subnet=172.20.0.0/16 my-bridge
# 将容器接入自定义网络
docker run -d --name web --network my-bridge nginx
默认 bridge 和自定义 bridge 有一个关键区别:默认 bridge 上的容器只能通过 IP 互相访问,无法使用容器名做 DNS 解析;而自定义 bridge 网络内置了嵌入式 DNS 服务器,容器之间可以直接用名字通信。这也是为什么在 Docker Compose 中,服务之间可以用服务名互相访问——Compose 会自动创建一个自定义 bridge 网络。
bridge 模式适合绝大多数单机场景:Web 应用与数据库容器互联、开发环境隔离、需要端口映射对外暴露服务的场景。它的代价是多了一层 NAT,吞吐量略低于 host 模式,且端口映射需要显式声明 -p。
host 模式:去掉网络隔离,换取性能
host 模式下,容器不再拥有独立的 network namespace,而是直接共享宿主机的网络栈。容器里的进程看到的网卡、路由表、iptables 规则与宿主机完全一致。
docker run -d --network host nginx
这意味着容器直接监听宿主机的端口,不需要 -p 映射,也不存在 NAT 转换开销。对于网络密集型应用——比如高频交易系统、DNS 服务器、需要处理大量并发连接的负载均衡器——host 模式能带来可观的性能提升。
但代价同样明显:端口冲突成为硬约束。如果宿主机 80 端口已被占用,容器里的 Nginx 就无法启动。容器之间也失去了网络隔离,一个容器可以嗅探到宿主机上其他进程的网络流量。因此 host 模式通常只用于性能敏感且端口规划明确的场景,不建议在多租户或安全边界要求高的环境中使用。
none 模式:完全断网,用于极端隔离
none 模式给容器分配一个空的 network namespace——只有 loopback 接口,没有任何外部网络连接。
docker run -d --network none alpine sleep 3600
这个模式看起来"没什么用",但在特定场景下非常关键。比如运行纯离线批处理任务、执行安全敏感的密钥运算、或者需要完全手动配置网络栈的场景。你也可以在 none 模式基础上,通过 docker exec 进入容器手动创建 veth 和路由规则,实现完全自定义的网络拓扑。Kubernetes 中某些 CNI 插件的实现思路就借鉴了这种"先断网、再按需接线"的模式。
overlay 模式:跨主机通信的标准方案
前面三种模式都局限于单台宿主机。当容器分布在多台机器上时,就需要 overlay 网络。overlay 基于 VXLAN 技术,在宿主机物理网络之上构建一层虚拟网络,让不同主机上的容器仿佛处于同一个二层网络中。
overlay 模式通常与 Docker Swarm 配合使用:
# 初始化 Swarm
docker swarm init
# 创建 overlay 网络
docker network create --driver overlay --attachable my-overlay
# 在 Swarm 服务中使用
docker service create --network my-overlay --name api myapi:latest
overlay 网络支持加密通信(--opt encrypted),并且内置服务发现和负载均衡。当你在 Swarm 中部署一个多副本服务时,overlay 网络会自动将请求分发到各个副本。
需要注意的是,overlay 模式对底层网络有要求:VXLAN 需要宿主机之间特定的端口(默认 4789/UDP)可达,且 MTU 需要相应调整以避免分片。在云环境中,如果底层网络不支持 VXLAN 或存在 MTU 限制,可能需要改用其他 CNI 方案。另外,如果你使用的是 Kubernetes 而非 Swarm,overlay 网络的实现通常由 Calico、Flannel、Cilium 等 CNI 插件负责,而不是 Docker 原生的 overlay driver。
如何选择:一张决策清单
面对具体问题时,可以按以下顺序判断:
- 容器需要跨主机通信吗? 需要则考虑 overlay(或 Kubernetes CNI),否则进入下一步。
- 需要网络隔离吗? 如果多个容器需要互相通信但又要与宿主机其他服务隔离,选自定义 bridge。
- 对网络性能极度敏感吗? 如果应用是网络密集型且端口规划清晰,选 host。
- 需要完全断网吗? 安全沙箱或离线任务选 none。
- 不确定? 从自定义 bridge 开始,它是最安全的默认选择。
实践中的几个常见坑
端口映射与 host 模式混用:在 host 模式下指定 -p 不会报错,但会被忽略,容易造成困惑。
自定义 bridge 的 DNS 解析:只有自定义网络才有嵌入式 DNS,默认 bridge 没有。如果你发现容器间无法用名字 ping 通,先检查是否用了默认 bridge。
overlay 的 MTU 问题:VXLAN 封装会增加 50 字节开销,如果宿主机 MTU 是 1500,容器内应设置为 1450,否则大包会被丢弃,表现为"小请求正常、大文件传输卡死"。
iptables 规则冲突:Docker 会自动管理 iptables 规则,如果宿主机上运行着 firewalld 或自定义防火墙规则,可能与 Docker 的规则产生冲突,导致容器无法访问外网或端口映射失效。
小结
Docker 的四种网络模式本质上是在隔离性、性能和复杂度之间做权衡。bridge 提供了合理的默认隔离,host 用隔离换性能,none 提供极端隔离,overlay 解决跨主机通信。没有哪种模式是"最好"的,只有最适合当前场景的。理解每种模式背后的 Linux 网络机制——network namespace、veth pair、bridge、VXLAN——才能在遇到问题时快速定位,而不是靠试错。
未经允许不得转载:任鹏个人博客 » Docker 容器网络模式详解:bridge、host、none 与 overlay 的适用场景与配置实践


朋友圈点赞图在线生成源码