Docker网络迷宫:从隔离地带到跨主机密道,容器隐形通信模块架构解密
文章目录

本篇摘要
本篇将介绍Docker网络通过CNM模型管理,提供bridge(默认)、host(共享宿主机)、container(复用其他容器)、none(完全隔离)四种模式,支持自定义网络与跨主机通信。核心命令涵盖创建、连接、查看及清理网络,灵活平衡隔离与连通需求,满足不同场景的容器组网与安全策略。
一.Docker Network(网络) 简介
为啥docker需要网络管理
核心矛盾:容器默认网络是隔离的(为了安全),但实际应用又需要各种通信(为了功能)。
管理范围:网络管理不仅要解决“连通”问题(如让外部访问nginx),也要解决“隔离”问题(如彻底禁用网络),还要实现“定制”需求(如组建容器私有局域网)。
总之,管理容器网络的核心在于能 按需灵活配置,在隔离与连通之间取得平衡,以满足不同场景的复杂需求。
docker网络构架简介
- 核心架构:
Docker网络由CNM模型规范,包含三大基础要素:

- Sandbox(沙盒):提供容器独立的虚拟网络栈(IP、端口、路由等),实现网络隔离。
- Network(网络):一个内部的虚拟子网,允许接入的容器相互通信。
- Endpoint(端点):虚拟网络接口,负责将容器(沙盒)连接到某个网络。
- 连接规则:
- 一个Endpoint只能接入一个Network。
- 一个容器(沙盒)可以通过多个Endpoint接入多个Network,从而实现多网络通信。
- 通信原则:
- 只有接入同一个Network的容器之间才能直接通信(如图中容器A和B),不同网络间的容器无法直接互通(如图中容器A和C)。
认识下几个概念:
-
Libnetwork(相当于cnm的一个实例化对象):是Docker网络的核心库,用Go语言编写。它完整实现了CNM模型,并提供了服务发现、负载均衡等关键网络功能。
-
驱动(Driver):负责具体的数据传输和网络资源管理(如连通性、隔离性)。不同驱动对应不同的网络类型(如桥接、覆盖网络)。
Libnetwork作为控制层实现网络的管理和抽象,而驱动作为数据层负责具体网络的实现和操作。两者协同工作,共同构成了Docker的网络栈。
常见网络类型
-
Bridge(桥接):默认网络模式。在主机上创建虚拟网桥,实现同主机内容器间的通信与隔离。
-
Host(主机):容器直接使用主机网络,没有网络隔离,性能高,但端口冲突风险大。
-
Container(容器):新容器共享指定容器的网络命名空间(IP和端口),两者网络互通(相当于再同一个容器通信)。
-
None(无网络):完全网络隔离。容器内无任何网络接口,适用于绝对安全的场景。
-
Overlay(覆盖):用于跨主机通信。通过搭建虚拟网络,连接不同主机上的容器,是集群服务的基础。

- Docker覆盖网络 = 跨主机的内部局域网,它让不同机器上的容器能像在同一个内部网络里一样直接通信。
- 在 Docker 安装时,会自动安装一块 Docker 网卡称为 docker0,它是一个网桥设备,主要用于 Docker 各容器及宿主机的网络通信。
总之,Docker 通过一个叫 Libnetwork 的核心组件,用“可插拔”的驱动来灵活管理容器网络。
二.docker network 管理命令
1.docker network create 命令
- 功能:用于创建自定义的Docker网络。
- 语法:基本命令格式为
docker network create [OPTIONS] NETWORK。 - 关键参数:
-d, --driver:指定网络驱动(如 bridge、overlay,默认值是 bridge 桥接模式)。--subnet:用CIDR格式指定网络的IP网段。--gateway:指定该网络的网关地址。--ipv6:启用IPv6支持。
- 用途:通过自定义网络,可以实现容器间更灵活、安全的通信。
下面演示下:

- 子网段一共可以出现对应2^16次方个网号(/后面的是已经占用的2的多少次方了,比如子网掩码就是255.255.0.0)。
2.docker network inspect 命令
- 功能:查看 Docker 网络的详细配置信息。
- 用法:命令后直接跟网络名称,如
docker network inspect mynetwork。 - 关键参数:
-f或--format可用于自定义输出信息的格式。 - 特点:可同时检查一个或多个网络的详情。
演示下:

- 这里显示就是没有容器等连接这个网络。
3.docker network connect 命令
- 功能:用于将一个正在运行的容器连接到某个已存在的网络中。
- 用法:命令后跟网络名称和容器名称/ID,格式为
docker network connect [网络名] [容器名]。 - 关键参数:
--ip:为容器在该网络中指定一个静态IPv4地址。--ip6:为容器在该网络中指定一个静态IPv6地址。
- 效果:连接后,该容器即可与同一网络内的其他容器直接通信。
演示下:
以busybox镜像实例化容器为例:

- 可以看到对应的eth0的一个ip地址(是由对应的docker0 网桥分配的)。

- 把对应的mybox容器添加到对应的局域网中,可以看到对应的mybox配置就出现了对应的net1分配的网号(注意busybox只有sh没有bash)。

- 而查看net1网络详情就可以看到容器被添加进来了一个关于mybox的信息。
4.docker network disconnect 命令
- 功能:将一个正在运行的容器从指定的网络中断开。
- 用法:基本命令格式为
docker network disconnect [OPTIONS] NETWORK CONTAINER。 - 关键参数:
-f, --force:强制断开容器的网络连接。
- 效果:断开后,该容器将无法再访问该网络,并与该网络内的其他容器失去连接。
演示下:
- 断开对应局域网连接,对应容器字段就没了。
5.docker network prune 命令
- 功能:一键删除所有
未被任何容器使用的自定义网络,用于清理闲置网络资源。 - 用法:直接运行
docker network prune即可。 - 关键参数:
-f或--force:跳过确认提示,直接执行删除操作。
- 注意:此命令不会删除正在被容器使用的网络,也不会删除默认网络(如
bridge,host,none)。
演示下:

- 发现刚创建的是三个无容器使用的局域网被删除了。
6.docker network rm 命令
- 功能:用于删除一个或多个指定的 Docker 网络。
- 语法:基本命令格式为
docker network rm NETWORK [NETWORK...],可以同时删除多个网络。 - 关键参数:
-f:强制删除网络,即使网络正在被使用也会尝试移除。
- 注意:此命令需要明确指定网络名称来删除,与
prune命令(清理所有未使用网络)不同。

7.docker network ls 命令
- 功能:列出所有已创建的 Docker 网络。
- 用法:直接运行
docker network ls或使用其别名docker network list。 - 关键参数:
-q, --quiet:仅显示网络的 ID,不显示其他详细信息。-f, --filter:根据条件(如驱动类型、网络名)过滤显示结果。--format:自定义输出信息的格式(如只显示名称、驱动等)。--no-trunc:显示完整的网络 ID,不进行截断省略。
- 用途:用于快速查看当前主机上的所有 Docker 网络及其基本信息。
演示下:

命令汇总清单:
| 命令 | 别名 | 功能 | 备注 |
|---|---|---|---|
| docker network create | 无 | 创建网络 | 无 |
| docker network connect | 无 | 连接网络 | 无 |
| docker network disconnect | 无 | 断开网络 | 无 |
| docker network ls | docker network list | 列出网络 | 无 |
| docker network prune | 无 | 删除不使用的网络 | 无 |
| docker network inspect | 无 | 查看网络详情 | 无 |
| docker network rm | docker network remove | 删除一个或多个网络 | 无 |
基于两种方式加入网络的差异测试
以busybox为例进行测试:

- 首先创建了一个n1局域网,对应没有接入容器。

- 下面创建个busybox的容器mx1,把它创建时候就加进去。

- 查看对容器详情可以看到就一个对应的网络,也就是创建时候加进去的n1网络。


- 创建时候不加入网络,发现默认被加入了bridge(网桥中)。
下面看下对应的bridge信息:

- 这里其实是docker默认一个docker0操作,创建的容器如果不指定网络,就默认加入到它的bridge网桥中,从这里进行通信等。


- 先创建后续手动加入进去对应网络发现对应容器的network有俩,也就是可以在这俩区域内通信。

- 把这两容器从n1网络移除。


- 发现默认添加进容器的bridge网桥不会消失。


- 手动把对应的mx2的bridge的连接移除。
总结下:
如果创建容器时候不指定对应加入网络,就会被docker0默认加入到自己的bridge网络中,而启动时指定的就不会加入bridge里而是自己指定的网络,然后容器可以加入包括bridge等多个网络中,对于这个容器的bridge网络只能手动disconnect掉。
三.docker bridge 网络
-
Docker Bridge 网络是一种由 Docker 内置
bridge驱动创建的默认网络类型;其底层实现依赖于 Linux 内核中的 Linux bridge 技术。 -
Bridge 网络是一个软件网桥(链路层设备),用于在不同网络段间转发流量。
-
Docker 默认创建的软件网桥名为
docker0;连接到同一个 bridge 网络的容器之间可以相互通信;同时,该网络提供了与未连接到此网桥的其他容器之间的隔离。
Docker Container 的 bridge 桥接模式:

-
不指定网络时,Docker容器默认加入一个网络;这个默认网络的名字叫 “bridge”;它是一个单机桥接网络,用于同一台主机上的容器通信。
-
也就是对内通过docker0(开机自动创建bridge这个网络)的bridge通信;对外就是通过eth0的ip_forward(想象成路由器)进行对外网络通信。
对应bridge与docker0关系:
- Docker容器默认连接的网络名为 “bridge”。
- 这个“bridge”网络在Linux内核中对应一个名为
docker0的软件网桥。 - Docker的网络名(bridge)和内核的设备名(docker0)指的是
同一个东西,只是在不同层面的称呼。
容器间基于docker0网桥的bridge网络进行通信测试
下面以busybox镜像为例:

- 查看下bridge网络信息,可以看到默认底层连接的是docker0网桥。

- 启动两个busybox实例化的容器(这里busybox对应容器是类似终端,如果不让它卡住就会立即退出,因此这里以交互模式运行,为了不影响shell因此后台运行)。


- 通过ifconfig可以看到对应的bridge的网关和docker0桥的inet相同。


- 在这两个容器中执行sh终端时候可以互相根据对应容器ip进行ping到。

- 当然,两者都被默认加入到对应的bridge网络,所有才能互相网络通信。

- 这里如果把对应的b1从bridge网络移除,这样就不能互相ping到了。
基于自定义桥接网络进行通信测试
如果只想让部分容器在对应的网络下进行通信,因此可以划分出这个网络,让指定容器加进去即可。

- 创建对应桥接网络。


- 不指定对应的网络号范围与子网掩码;则默认生成,也可以看到对应的网关信息。


- 两busybox实例化出来的容器加入这个网络,会发现对应网络信息种添加了对应的里面容器信息。


- 互相也是可以ping通的。
总结下:
对的docker0对应的名为bridge网络是一个桥接网络,而用户还可以自定义一个桥接网络如net1,一般底层对应不是docker0而是br-<网络ID>。
基于自定义桥接网络的DNS功能测试
还是以busybox为例:


- 发现被加入到了bridge网络。
然后下面试下DNS功能:


- 默认的docker0的bridge网络没有DNS解析功能。

- 对应的加入到自定义的net1网络的容器。


- 自定义网络的容器能互相更具容器名ping到。
总结:
默认的docker0的bridge网络无DNS解析功能,而自定义的网络,加入进去的容器能ping到,即局域DNS解析功能。
端口暴露与转发
- 两种暴露方式:
-P:将容器所有已暴露的端口,随机映射到宿主机的动态端口上。-p <宿主端口>:<容器端口>:将指定的容器端口映射到宿主机的指定端口上。
- 端口转发:
- 让连接在
bridge等内部网络的容器能对外提供服务;即将流量从宿主机端口转发到内部容器端口。
- 效果图:

- 这里访问对应服务器的对应端口就被转发到了对应的容器对应端口,来访问容器了。
演示下:


- 映射后能访问(注意对应服务器端口必须开放才行,一般
-P有的不开放)。
总结下:
Bridge网络特点:
- 容器对外通信需要经过端口转发和NAT地址转换(容器间不需要)。
- 缺点:会消耗额外的计算资源,导致网络性能有一定损耗。
四.docker host 网络
-
Docker 容器默认拥有自己独立的网络空间(Network Namespace),实现网络隔离,有自己的虚拟网卡和IP地址;但是使用
--network=host参数时,容器不会创建独立的网络空间。 -
在 Host 模式下,容器与宿主机共享同一个 Network Namespace。
-
容器不再虚拟自己的网卡和IP,而是直接使用宿主机的网卡、IP地址和端口(也只是有被重复占用冲突风险的)。
对比效果如图所示:

下面测试下host模式与指定bridge网络模式(以nginx来测试):

- 因为host模式直接让对应的容器采取对应主机的80端口,因此这里手动停掉。

- 直接启动成功。

- 发现host网络加入了这个容器。


- 查看容器日志发现对应的80端口存在,无法绑定。

- 发现确实冲突了。

- 可以发现以对应host网络创建的容器内部网络配置信息与宿主机一模一样;就是复用。
总结下:
host模式,容器就直接根据自身开放的端口来占用对应的宿主机的,冲突就失败,网络也是用宿主机的,相当于直接全部对应映射。
对应优缺点:
优点:少了一层bridge层,网络性能最好,传输效率高,适合对网络要求高的应用。缺点:比如端口直接映射,发生端口冲突概率导致无法运行容器概率高。
五.docker container 网络
又称为 “other container”(容器)模;该模式下的容器直接使用另一个已有容器的网络栈(网络环境)。
- 共享无隔离:与它所依附的那个容器之间没有网络隔离,就像在同一台主机上运行的多个进程(直接用端口就行,访问快)。
- 外部有隔离:它们两者作为一个整体,与宿主机以及其他容器之间仍然存在网络隔离。
- 其网络隔离性介于 bridge(完全隔离)和 host(完全共享)模式之间。
网络模式图:

也就是一种让新容器直接共享使用另一个现有容器网络环境的模式。
实现方式:
- 两容器共享同一个网络命名空间 (Network Namespace)。
- 首先,找到要被共享网络的那个容器(other container)所在的网络命名空间; 然后,让新创建的容器直接使用这个已有的命名空间,而非创建新的;最终两容器的网络栈(如IP地址、端口、网卡等)完全一样,就像同一个容器内的两个进程。
下面演示下(以busybox为例):

- 创建对应容器,加入到对应桥接网络。

- 查看容器详情可以看到加入的详细网络。

- 创建容器h3加入到刚才h2对应的网络中。

- 查看容器h3详情,发现对应的没有加入网络。


- 进入容器h2和容器h3后发现对应的ip一模一样。

- 停止h2容器(这里因为容器共用ip问题导致停止的慢);发现h3对应的ip消失了。

- 这里停止h2后,发现h3对应的网络信息没了ip只有本地环回了;然后重启h2后,如果不重启h3是无法添加进来;然后再重启h3后发现h3中对应的h2的ip回来了(这里可以理解成对应的h3保留了寻找h2对应信息,比如拿到ip等,如果h2挂掉后,h3寻找找不到,就默认没ip了,然后h2重启了,h3不会改变状态,只有h3重启后,才会知道自己是和h2共享ip的,然后才回去找h2进而拿到对应h2ip作为自己的)。
总结下:
容器间可通过 localhost 直接通信,网络传输效率高(无NAT损耗);但是容器间存在强依赖关系,一荣俱荣,一损俱损;如若一个被依赖的容器重启,会导致另一个服务的网络立刻不可用(此时这个容器也需要重启才行)。
六.docker none 网络
- none 网络就是指没有网络。挂在这个网络下的容器除了 lo(本地回环),没有其他任何网卡。
下面演示下(以busybox为例):

- 创建h8容器加入到对应none网络。

- 查看对应none网络信息,发现h8容器被加入进来了。

- 发现对应的h8无外部网络,只有本地环回。

- 这里发现ping 百度还是宿主机网络还是对应的docker0桥网络都是无法的,因为它自身就没有网络ip。
总结下:
- 容器没有任何网络接口,完全与网络隔离,无法进行任何网络通信;运行对安全性要求极高且无需联网的任务,例如生成随机密码,从根本上防止密码通过网络泄露。
- 为第三方工具或应用提供空白画布。先由 Docker 创建无网络的容器,其复杂的网络配置再由这些专业工具后续自行配置。
- 没有网络ip,其他人找不到(不用担心泄露信息),因此可以干一些保密的事情。
七.本篇小结
Docker网络架构以沙盒、网络、端点三要素实现容器隔离与通信。bridge模式默认但需NAT转发,host模式性能最佳但易冲突,container模式共享网络栈但强依赖,none模式极致安全。自定义网络支持DNS发现,覆盖网络解决跨主机互通,通过命令行工具灵活管理网络生命周期与连接策略。
更多推荐

所有评论(0)