Docker 将应用程序打包成了可以轻松组合的“积木”。然而,要让这些积木之间能够通信、访问外网,甚至在不同的服务器之间协作,网络配置是关键所在。
很多开发者在 Docker 上遇到瓶颈,往往不是因为不会构建镜像,而是卡在了复杂的网络模式上——容器启动了却无法访问数据库,或者跨主机部署时容器间无法互通。这篇文章将深入浅出地为你剖析 Docker 的四大核心网络模式(Bridge/Host/Overlay/None),每种模式都配有实操命令,力求让你看完就能直接应用于项目。更多容器与 网络/系统 相关的深度探讨,欢迎在 云栈社区 交流。
一、Docker网络的核心逻辑
要理解 Docker 网络,首先要明白其本质:它为每个容器划分了一个独立的网络地盘,技术上称为 网络命名空间。
简单来说,每个容器都拥有自己专属的虚拟网卡、IP地址、路由表,就像每家每户有自己的门牌号和围墙,彼此隔离,互不干扰。Docker 则通过虚拟网桥、虚拟网卡等“工具”,来打通容器之间、容器与外部世界之间的通道。
在开始之前,先掌握一个最基础、最常用的命令,用于查看当前 Docker 环境中已有的网络:
docker network ls
执行后会看到类似下面的输出,这三个默认网络正是我们今天的主角:
NETWORK ID NAME DRIVER SCOPE
b32d6b8a5f43 bridge bridge local # 默认桥接网络
7d1e8d7c4a1d host host local # 主机网络
ee4c62b16a32 none null local # 无网络
二、Bridge模式:默认的“常规操作”
这是 Docker 容器启动时的默认网络模式,也是最常见的场景,适合单台宿主机上的多个容器进行互联。
1. 核心原理
宿主机内核会自动创建一个名为 docker0 的虚拟网桥,你可以把它理解成一个虚拟的交换机。所有未指定网络的容器,默认都会连接到这个交换机上,并从这个交换机(docker0)获取一个私有 IP 地址。这个网桥同时负责容器与外网通信时的 NAT 地址转换。
它的网络拓扑可以简单表示为:
+------------------------+
| 宿主机(你的服务器) |
| |
| +-----------------+ |
| | docker0 网桥 |---|-- 连外网(NAT转发)
| +---+---------+---+ |
| | | | 一头连网桥,一头连容器
| [虚拟网卡] [虚拟网卡] |
| | | |
| 容器A 容器B |
+------------------------+
2. 实操:启动容器与测试通信
让我们启动两个 Nginx 容器,默认就会使用 Bridge 网络:
# 启动web1容器
docker run -d --name web1 nginx
# 启动web2容器
docker run -d --name web2 nginx
这里有个需要注意的点:在默认的 Bridge 网络中,容器之间无法通过容器名称直接访问,只能使用 IP 地址。所以我们需要先查询 IP,再进行通信测试:
# 第一步:查询 web2 容器的 IP 地址
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web2
# 第二步:进入 web1 容器,ping web2 的IP(假设查到是 172.17.0.3)
docker exec -it web1 ping 172.17.0.3
如果能 ping 通,说明两个容器在网络层面已经可以正常通信。
3. 进阶实践:自定义 Bridge 网络(生产推荐)
默认 Bridge 网络无法使用容器名通信,这在实际协作中很不方便。自定义 Bridge 网络可以完美解决此问题,并提供更好的网络隔离,是生产环境的推荐做法。
# 1. 新建一个自定义 Bridge 网络(例如命名为 mydocker)
docker network create mydocker
# 2. 启动容器时,指定加入这个自定义网络
docker run -d --name app1 --network mydocker nginx
docker run -d --name app2 --network mydocker busybox sleep 3600
# 3. 测试:现在可以直接用容器名 ping 通了!
docker exec -it app1 ping app2
看,使用自定义网络后,Docker 内置的 DNS 会自动解析容器名,大大简化了多容器应用中的 运维/DevOps/SRE 配置工作。
三、Host模式:追求极致性能的“直连方案”
如果你运行的服务对网络性能有极致要求,例如监控代理、VPN 网关等,Host 模式就是你的首选。
1. 核心逻辑
Host 模式下,容器不再拥有自己独立的网络命名空间,而是直接“借用”宿主机的网络栈。这意味着容器将与宿主机共享 IP 地址和端口范围,没有额外的 NAT 或虚拟网桥开销,网络性能达到最佳。
打个比方:Bridge 模式是容器住在有独立小房间的公寓楼里,而 Host 模式则是容器直接住进了宿主机的“客厅”,共享所有网络资源。
2. 优缺点一览
优点:性能最佳、配置简单、无需端口映射。
缺点:网络隔离性差,容器与宿主机可能发生端口冲突(例如,容器占用了80端口,宿主机上的 Nginx 服务就无法启动了)。
3. 实操示例
# 使用 Host 模式启动一个 Nginx 容器
docker run -d --name web-host --network host nginx
启动后,你只需在浏览器输入宿主机 IP 即可直接访问这个 Nginx 服务,无需指定任何端口号(因为它直接使用了宿主机的80端口)。注意,在此模式下,-p 80:80 这样的端口映射参数是无效的。
四、Overlay模式:跨服务器通信的“集群神器”
当你的容器需要部署在多台服务器上(例如构建 Docker 集群)时,单机 Bridge 模式就无能为力了——不同宿主机上的容器不在同一个二层网络,无法直接通信。
Overlay(覆盖)网络正是为解决此问题而生。它能在多台物理服务器之间构建一条“虚拟隧道”,让所有宿主机上的容器仿佛身处同一个局域网内,可以无障碍通信。
1. 核心逻辑
Overlay 网络基于 VXLAN 等技术,将容器间的通信数据包封装,通过物理网络进行传输,在逻辑上构建出一个跨越主机的虚拟子网。
简单拓扑示意:
服务器A(Node1) 服务器B(Node2)
+-------------+ +-------------+
| 容器A |<---------->| 容器B |
|(10.0.0.2) | 虚拟隧道 |(10.0.0.3) |
+-------------+ +-------------+
2. 实操步骤(需启用 Docker Swarm 集群)
Overlay 网络需要依赖 Docker Swarm 集群模式来管理集群状态。配置步骤如下:
# 1. 在管理节点上初始化 Swarm 集群(请替换成你的服务器IP)
docker swarm init --advertise-addr 你的服务器IP
# 2. 创建一个 Overlay 网络(命名为 my-cluster-net)
docker network create -d overlay my-cluster-net
# 3. 创建一个集群服务,并将其连接到 Overlay 网络(例如启动3个 Nginx 副本)
docker service create --name web-cluster --network my-cluster-net --replicas 3 nginx
完成以上步骤后,无论这3个 Nginx 容器副本被调度到集群中的哪台服务器上,它们都能通过这个 Overlay 网络互相访问,这是构建弹性 云原生/IaaS 应用架构的基础。
五、None模式:完全隔离的“离线方案”
这是最特殊的一种模式,顾名思义,容器启动后将处于“无网络”状态。它只有本地回环接口(lo),既不能访问外网,也无法被其他容器或外部访问。
1. 实操示例
# 启动一个 None 网络模式的容器,适合执行离线任务
docker run -d --name offline-task --network none alpine sleep 3600
2. 适用场景
- 离线数据处理/日志分析:任务本身无需网络即可完成。
- 高安全需求场景:彻底切断网络访问,杜绝网络层面的攻击面。
- 需要手动配置自定义网络栈:作为一张“白纸”,由用户完全自定义网络配置。
六、四大网络模式快速对比与选型
担心记混?这张对比表可以帮助你根据实际场景快速决策:
| 模式 |
隔离性 |
共享宿主机网络 |
支持容器名解析 |
跨主机通信 |
典型适用场景 |
| Bridge |
好 |
不共享 |
自定义网络支持 |
不支持 |
本地开发、单服务器多容器互联 |
| Host |
差 |
完全共享 |
不支持 |
不支持 |
高性能服务、监控代理、VPN |
| Overlay |
好 |
不共享 |
支持 |
支持 |
集群部署、跨服务器微服务通信 |
| None |
极致好 |
不共享 |
不支持 |
不支持 |
离线任务、高安全隔离、自定义网络 |
七、常用 Docker 网络命令速查
将以下命令加入你的运维工具箱,以备不时之需:
| 操作需求 |
命令 |
| 查看所有网络 |
docker network ls |
| 查看网络详细信息(用于排错) |
docker network inspect <网络名或ID> |
| 新建自定义网络 |
docker network create <网络名> |
| 删除无用网络 |
docker network rm <网络名或ID> |
| 将运行中的容器连接到指定网络 |
docker network connect <网络名> <容器名> |
| 将容器从指定网络断开 |
docker network disconnect <网络名> <容器名> |
八、实战场景:一键部署方案
1. 本地 Web 应用 + 数据库部署(最常用)
需求:Web 容器需要访问 MySQL 数据库,且希望通过容器名直接连接。
# 1. 创建专用的应用网络
docker network create app-net
# 2. 启动 MySQL 容器,加入该网络
docker run -d --name mysql --network app-net -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0
# 3. 启动 Web 应用容器,通过环境变量或配置直接用 `mysql` 主机名连接数据库
docker run -d --name web --network app-net -e DB_HOST=mysql your-web-app-image
2. 跨服务器集群服务部署
需求:在多台服务器上部署相同的服务,并确保所有实例能互通。
# 1. 在所有节点初始化或加入同一个 Swarm 集群
# 主节点:docker swarm init --advertise-addr <manager-ip>
# 工作节点:docker swarm join --token <token> <manager-ip>:2377
# 2. 创建 Overlay 网络
docker network create -d overlay global-net
# 3. 创建全局模式服务,集群内每个节点都会运行一个该服务的实例
docker service create --name app-global --network global-net --mode global nginx
九、总结与最佳实践
- 本地开发/单服务器部署:优先使用自定义 Bridge 网络,在易用性和隔离性之间取得最佳平衡。
- 追求极致网络性能:考虑使用 Host 网络,但务必提前规划好端口使用,避免冲突。
- 多服务器集群/云原生部署:必须采用 Overlay 网络,并搭配 Docker Swarm 或 Kubernetes 等编排工具,实现服务的无缝跨主机通信。
- 离线任务或最高安全等级需求:使用 None 网络,最大限度地减少网络暴露面。
掌握 Docker 网络的关键不在于死记硬背所有命令,而在于理解每种模式的核心设计思想与适用场景。结合文中的实操命令亲自练习一遍,你就能在项目中游刃有余地选择和配置合适的网络方案。
