3、Docker网络基础:Docker网络模式详解(bridge、host、none、overlay、macvlan)

聊到Docker网络,我其实挺感慨的。刚接触容器那会儿,总觉得网络是个黑盒——容器跑起来了,能ping通就行。直到有一次生产环境出了故障,我才意识到,不懂网络模式,就像开车不看仪表盘,迟早要翻车。

今天咱们就把Docker的五大网络模式掰开揉碎。你想想看,容器本质上是进程隔离,那网络怎么隔离?怎么互通?说白了,就是靠这几种模式来定义「容器怎么连上网络」。

3.1 bridge网络模式——最常用的默认模式

这是Docker默认的网络模式。你执行 docker run 不加任何网络参数,用的就是它。

它的原理很简单:Docker daemon启动时,会在宿主机上创建一个虚拟网桥 docker0。每个容器启动后,会创建一对veth pair,一头连着容器的eth0,另一头连到 docker0 上。这样容器之间就能通过网桥通信了。

核心特点:

  • 容器拥有独立的网络命名空间
  • 容器之间可以通过IP直接通信
  • 容器访问外网需要经过NAT(iptables MASQUERADE)
  • 宿主机以外的设备无法直接访问容器(需要端口映射)

我在项目中遇到过一个问题:默认的 docker0 网段是 172.17.0.0/16,如果公司内网正好用了这个段,那容器就访问不了内网资源了。嗯,这里要注意,你可以通过 --bip 参数自定义网段。

# 查看docker0网桥信息
ip link show docker0
brctl show docker0

# 自定义网桥网段(修改daemon.json)
{
  "bip": "10.88.0.1/24"
}

避坑指南:我曾经在生产环境遇到过容器IP重启后变化的问题。如果你依赖固定IP,建议使用 --ip 参数指定,或者创建自定义bridge网络。

3.2 host网络模式——性能优先的选择

host模式就直白了——容器直接使用宿主机的网络栈,不隔离网络命名空间。说白了,容器里的进程就像直接跑在宿主机上一样。

什么时候用?我个人的习惯是:对网络性能要求极高,或者需要监听大量端口的场景。比如一些高性能的负载均衡器、监控代理。

# 启动一个host模式的nginx
docker run --network host -d nginx

# 此时访问宿主机80端口,就等于访问容器内的nginx

注意:host模式下,端口映射参数 -p 是无效的。因为容器直接用了宿主机的端口,你再映射就冲突了。我曾经看到有人同时用 --network host-p 80:80,结果容器启动报错,排查了半天。

host模式的好处很明显——没有NAT转换,网络延迟极低。但坏处也突出:缺乏隔离性,容器里如果监听了端口,宿主机上就多了一个端口。安全审计的时候要格外小心。

3.3 none网络模式——完全隔离

none模式,顾名思义,容器没有网络接口。只有lo回环接口,连eth0都没有。

你可能会问:这有什么用?其实场景还挺多的。比如一些离线计算任务、纯数据处理容器,根本不需要网络。或者你想自己手动配置复杂的网络拓扑,先启动一个none模式的容器,再手动把veth对加进去。

# 启动一个没有网络的容器
docker run --network none -it alpine sh

# 查看网络接口,只有lo
ip addr

我记得有一次做安全测试,需要模拟一个完全离线的环境。用none模式启动容器,然后在里面跑一些敏感的数据处理脚本,确保数据不会外泄。嗯,这种场景下none模式就特别合适。

3.4 overlay网络模式——跨主机的利器

overlay模式是Docker Swarm集群的核心网络方案。它能让不同宿主机上的容器,像在同一个二层网络里一样通信。

原理其实不复杂:它基于VXLAN技术,在宿主机之间建立隧道。每个容器分配一个虚拟IP,数据包通过VXLAN封装后,在宿主机网络里传输。你想想看,这不就是给容器们搭了一座「空中桥梁」吗?

使用前提:

  • 需要Docker Swarm集群环境
  • 宿主机之间网络互通(通常是三层可达)
  • 需要配置键值存储(如Consul、etcd)
# 创建overlay网络
docker network create -d overlay my-overlay

# 在Swarm服务中使用
docker service create --network my-overlay --name web nginx

我在项目中用overlay网络部署过微服务架构。十几个服务分布在三台宿主机上,通过overlay网络互相调用,延迟在1ms以内。不过要注意,overlay网络会带来额外的封装开销,对MTU比较敏感。我建议把宿主机网卡的MTU设置为1450或更小,避免分片。

避坑指南:我曾经遇到overlay网络通信偶尔超时的问题。排查了半天,发现是宿主机防火墙把VXLAN的UDP端口(4789)给封了。嗯,这个坑踩过一次就记住了。

3.5 macvlan网络模式——让容器拥有独立MAC地址

macvlan模式比较特殊。它让每个容器直接拥有一个独立的MAC地址,看起来就像一台真实的物理设备连在网络上。

为什么需要这个?有些老旧的应用,或者基于MAC地址做认证的网络环境,容器必须拥有真实的MAC地址才能正常工作。macvlan就是为这种场景设计的。

# 创建macvlan网络(桥接模式)
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  my-macvlan

# 启动容器使用macvlan网络
docker run --network my-macvlan --ip=192.168.1.100 -it alpine sh

重要限制:macvlan模式下,宿主机和容器之间默认不能通信。因为macvlan的父接口(比如eth0)被设置成了混杂模式,宿主机自己的IP和容器的IP不在同一个广播域。解决办法是创建一个macvlan子接口给宿主机用。

我个人不太推荐在生产环境大规模使用macvlan。原因有二:一是IP地址消耗快,每个容器都要一个独立IP;二是网络排障比较麻烦,因为每个容器都有自己的MAC,交换机上的MAC表会迅速膨胀。

3.6 五种模式对比总结

网络模式 隔离性 性能 跨主机 适用场景
bridge 中等 中等(有NAT) 单机容器通信,最常用
host 高(无NAT) 高性能需求,端口密集场景
none 最高 无网络 离线任务,自定义网络
overlay 中等(有封装) Swarm集群,微服务
macvlan MAC地址依赖,物理网络集成

最后说一句:没有最好的模式,只有最合适的模式。我刚开始做容器网络时,总想着用一种模式打天下,后来发现每个场景都有自己的脾气。bridge适合单机开发,host适合性能敏感的服务,overlay是集群标配,macvlan是特殊场景的救星。你根据实际需求选就好。

我的建议:如果你刚开始接触Docker网络,先把bridge和host玩透。这两个模式覆盖了90%的单机场景。等遇到跨主机通信需求了,再深入研究overlay。macvlan嘛,遇到了再说,别提前焦虑。