LV025-自定义网络
一、概述
1. 前言
Docker 自定义网络允许用户创建和管理自己的网络,以便在容器之间进行通信,并连接到外部网络。通过自定义网络,用户可以更好地控制容器之间的通信方式和网络配置,提高容器化应用的灵活性和安全性。
在 Docker 中,有四种类型的网络驱动器:桥接(bridge)、主机(host)、覆盖网络(overlay)和无网络(none)。使用自定义网络时,可以选择使用桥接网络或覆盖网络,具体选择取决于应用的需求和部署环境。
2. 要了解的命令
- 网络相关命令
| docker network ls | 查看已存在的网络模式列表 |
|---|---|
| docker network create -d [mode_type] net_name | 创建新的自定义网络 |
| docker network rm [id | name] | 移除自定义网络模式 |
| docker network connect [id | name] | 连接到特定网络 |
| docker network disconnect net_name container_id/name | 给指定容器,取消某个网络模式 |
| docker network [birdge | none | host | 自定义] | 查看网络模式的详细网络信息 |
- 容器相关命令
| docer exec -it container_[id | name] | 进入容器内部 |
| docker inspect container_[id | name] | 查看指定容器网络模式详细信息 |
二、自定义网络
1. 自定义 bridge 网络
1.1 简介介绍
Bridge 网络就像是 Docker 中的一个虚拟交换机,它在宿主机上创建一个名为 docker0 的网桥, 所有连接到这个网桥的容器都可以通过它进行通信。当你安装 Docker 时,会自动创建一个默认的 bridge 网络, 它一般使用 172.17.0.0/16 这个网段,所有未指定网络的容器都会自动连接到这个默认网络中。 不过,默认的 bridge 网络功能比较简单,容器之间只能通过 IP 地址互相访问,不支持通过容器名称来通信。
为了解决这个限制,Docker 提供了用户自定义 bridge 网络的功能。 当你创建自己的 bridge 网络时,连接到这个网络的容器就能获得更多便利的特性:容器之间可以通过名称相互访问, 网络隔离性更好,还可以随时将容器从网络中添加或移除。这就像是给容器们创建了一个独立的局域网, 既安全又方便管理。比如说,你可以把一个应用的前端、后端和数据库容器都放在同一个自定义 bridge 网络中, 它们就能通过容器名称轻松地相互通信,同时又与其他应用的容器网络保持隔离。
1.2 怎么创建?
- -d 执行网络模式
docker network ls
docker network create -d bridge b-net # 创建自定义网络
docker network create -d bridge c-net
docker network ls
docker network rm c-net # 实验完毕移除自定义网络
docker network rm b-net【例】

- 不指定网络模式:docker network create 自定义网络时,不指定网络模式,默认就是 bridge 桥接模式
docker network create mybridgework #不用-d 指定网络模式,默认就是 bridge
docker network ls
docker network inspect mybridgework #查看自定义网络详细信息
docker network rm mybridgework #实验完毕移除自定义网络【例】

会发现新创建的 bridge 的子网将会在 172.20.x.x 这个网段,而 docker 默认创建的则是在 172.17.x.x

2. 创建 overlay 网络
2.1 简介
Overlay 网络是 Docker 用于实现跨主机容器通信的网络驱动,主要用于 Docker Swarm 集群环境。 它通过在不同主机的物理网络之上创建虚拟网络,使用 VXLAN 技术在主机间建立隧道,从而实现容器间的透明通信。 在 Overlay 网络中,每个容器都会获得一个虚拟 IP,容器之间可以直接通过这个 IP 进行通信, 而不需要关心容器具体运行在哪个主机上。这种网络类型特别适合于微服务架构、分布式应用以及需要跨主机通信的容器化应用, 例如分布式数据库集群、消息队列集群等。Overlay 网络支持网络加密,能确保跨主机通信的安全性, 同时还提供了负载均衡和服务发现等特性,是构建大规模容器集群的重要基础设施。
2.2 怎么创建?
docker network create -d overlay myOverLay #需要用-d 指定 overlay
docker network inspect myOverLay【例】
➜ /workspace git:(main) docker network create -d overlay myOverLay
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.这个错误表明当前节点不是 Swarm 管理器,因此无法创建 Overlay 网络,因为 Overlay 网络需要 Swarm 模式的支持。解决方法是初始化 Swarm 模式或加入现有的 Swarm 集群。
如果想要单节点 Swarm,可以运行 docker swarm init。如果想要将节点加入已有的 Swarm 集群,则运行 docker swarm join 命令。

这里默认创建的子网网段为 10.0.1.0/24,这个子网掩码为 255.255.255.0,所以子网都会在 10.0.1.x。
3. --subnet
使用--subnet 选项创建子网而言,bridge 网络只能指定一个子网,而 overlay 网络支持多个子网。在 bridge 和 overlay 网络驱动下创建的网络可以指定不同的参数。
三、自定义网络模式示例
开始之前我们重开一个开发环境,或者删除之前创建的网络模式,后面我们重新创建。
1. 创建自定义 bridge 网络
这里需要注意一下,因为 docker0 网卡,已经把网段 172.17.0.0/16 占用了(用 docker inspect bridge 可以得知,这里我们 mynet 就指定为 172.25.0.0/16,各网卡之间的子网网段不能有重叠!
docker network create -d bridge --subnet 172.25.0.0/16 mynet #自定义名字为 mynet 的网络,subnet 指定子网网段(不能与其他网卡的网段重叠)
docker network inspect mynet【例】
➜ /workspace git:(main) docker network create -d bridge --subnet 172.25.0.0/16 mynet
48b9a3dac4c1c908e6e300e9be5c425e42619fc0d753a3e8fe2d9e9a478855f5
➜ /workspace git:(main) docker network inspect mynet
[
{
"Name": "mynet",
"Id": "48b9a3dac4c1c908e6e300e9be5c425e42619fc0d753a3e8fe2d9e9a478855f5",
"Created": "2025-11-02T01:56:56.374220302Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.25.0.0/16"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]2. 查看宿主机网卡信息
在宿主机中执行:
ifconfig【例】
➜ /workspace git:(main) ifconfig
br-48b9a3dac4c1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.0.1 netmask 255.255.0.0 broadcast 172.25.255.255
inet6 fe80::42:f2ff:fe7c:1a04 prefixlen 64 scopeid 0x20<link>
ether 02:42:f2:7c:1a:04 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:73ff:feae:3d0d prefixlen 64 scopeid 0x20<link>
ether 02:42:73:ae:3d:0d txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5 bytes 526 (526.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.27.61.2 netmask 255.255.255.0 broadcast 172.27.61.255
ether 02:42:ac:1b:3d:02 txqueuelen 0 (Ethernet)
RX packets 5717 bytes 24376554 (23.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4903 bytes 5667066 (5.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 132 bytes 10532 (10.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 132 bytes 10532 (10.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0在通过 docker network create 命令创建新的网络模式,并指定--subnet 子网网段时,会自动创建新的虚拟网卡 br-48b9a3dac4c1,这里的 IP 为 172.25.0.1,就是我们指定的网段。
3. 创建三个容器
3.1 使用不同的网络
我们再创建三个容器分别使用不同的网络:
docker run -itd --name=container1 nginx:alpine # 使用默认的 docker0 网卡
docker run -itd --name=container2 nginx:alpine # 使用默认的 docker0 网卡;注:稍后下面会单独给 container2 添加自定义网络 mynet,使其拥有两个网络模式
docker run -itd --name=container3 --net=mynet --ip=172.25.3.3 nginx:alpine # 只使用自定义网络这网格容器启动后,默认都是使用 docker0 网卡,并且都是桥接模式,会产生三个虚拟网卡:
➜ /workspace git:(main) ifconfig
br-48b9a3dac4c1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.0.1 netmask 255.255.0.0 broadcast 172.25.255.255
inet6 fe80::42:f2ff:fe7c:1a04 prefixlen 64 scopeid 0x20<link>
ether 02:42:f2:7c:1a:04 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:73ff:feae:3d0d prefixlen 64 scopeid 0x20<link>
ether 02:42:73:ae:3d:0d txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5 bytes 526 (526.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.27.61.2 netmask 255.255.255.0 broadcast 172.27.61.255
ether 02:42:ac:1b:3d:02 txqueuelen 0 (Ethernet)
RX packets 5717 bytes 24376554 (23.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4903 bytes 5667066 (5.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 132 bytes 10532 (10.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 132 bytes 10532 (10.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth98e1256: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::14dd:b0ff:fe23:acdf prefixlen 64 scopeid 0x20<link>
ether 16:dd:b0:23:ac:df txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13 bytes 1182 (1.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vethab3ef76: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::8bf:9fff:fe18:4588 prefixlen 64 scopeid 0x20<link>
ether 0a:bf:9f:18:45:88 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vethfb91bbf: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::38e1:94ff:feec:bc8e prefixlen 64 scopeid 0x20<link>
ether 3a:e1:94:ec:bc:8e txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12 bytes 1112 (1.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 03.2 container2 添加自定义网络
我们在宿主机执行下面的命令:
docker network connect mynet container2 #指定 container2 的网络模式为 mynet【例】我们进入这个容器,敲 ifconfig 就会发现它有个网卡了
➜ /workspace git:(main) docker exec -it 81824b473456 /bin/sh
/ #
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:13 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1006 (1006.0 B) TX bytes:0 (0.0 B)
eth1 Link encap:Ethernet HWaddr 02:42:AC:19:00:02
inet addr:172.25.0.2 Bcast:172.25.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:13 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1006 (1006.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)4. 查看三个容器的网络情况
我们在宿主机执行下面的命令:
# 查看这三个容器的网络情况
docker inspect container1 # docker0
docker inspect container2 # docker0, mynet
docker inspect container3 # mynet4.1 container1 网络情况
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "02:42:ac:11:00:02",
"NetworkID": "1ef224a7cbab9dd7f9d55d20b7e9854f6ba4dfe5e4aa97cb0a7fd71a227bb1ba",
"EndpointID": "24dbc9ab3209d346d7730aa7a867c06bfee905876d86ac179d8cfcef32f00225",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DriverOpts": null,
"DNSNames": null
}
}可以看到网络模式就是默认的 bridge,网卡使用的是 docker0。
4.2 container2 网络情况
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "02:42:ac:11:00:03",
"NetworkID": "1ef224a7cbab9dd7f9d55d20b7e9854f6ba4dfe5e4aa97cb0a7fd71a227bb1ba",
"EndpointID": "030bfc1183e32e75204856261caf36edc8ac1915650a1c6a925ffabba9cfd87f",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DriverOpts": null,
"DNSNames": null
},
"mynet": {
"IPAMConfig": {},
"Links": null,
"Aliases": [],
"MacAddress": "02:42:ac:19:00:02",
"NetworkID": "48b9a3dac4c1c908e6e300e9be5c425e42619fc0d753a3e8fe2d9e9a478855f5",
"EndpointID": "0e1880873a8a5c0593b59da0371bdac5d6ac3ffe91464dc21fe19cbf2165f105",
"Gateway": "172.25.0.1",
"IPAddress": "172.25.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DriverOpts": {},
"DNSNames": [
"container2",
"81824b473456"
]
}
}可以看到有两个网卡:IP 分别是 172.17.0.3、172.25.0.2。
4.3 containe3 网络情况
"Networks": {
"mynet": {
"IPAMConfig": {
"IPv4Address": "172.25.3.3"
},
"Links": null,
"Aliases": null,
"MacAddress": "02:42:ac:19:03:03",
"NetworkID": "48b9a3dac4c1c908e6e300e9be5c425e42619fc0d753a3e8fe2d9e9a478855f5",
"EndpointID": "43fc287b315ae4593ac8441d20a640a6e1a659a49b38ba6235e71f72c96a826c",
"Gateway": "172.25.0.1",
"IPAddress": "172.25.3.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DriverOpts": null,
"DNSNames": [
"container3",
"88ebcb87419f"
]
}
}contain3 只有一个 mynet 网卡,可以看到 IP 是,172.25.3.3 (该 IP 的上面 docker run 该容器时指定的)。
5. 默认网络与自定义 bridge 网络
默认网络和自定义的 bridge 网络是有差异的,我们来看一下。
5.1 网络方面
默认网络 docker0:网络中所有主机间 只能 用 IP 相互访问。
自定义网络(bridge):网络中所有主机除 ip 访问外,还可以直接用 容器名(container-name)作为 hostname 相互访问。
我们执行下面的命令:
docker ps # 查看已启动容器的列表
docker exec -it container2 /bin/sh # 进入 contain2 容器内部,注,因为 nginx 镜像是 alpine 版本,默认不支持/bin/bash
ping -w 3 172.17.0.2 # 尝试在 contain2 内部 ping 通 contain1 的 IP(可以 ping 通)
ping -w 3 container1 # 不可以 ping 通
ping -w 3 container3 # 可以 ping 通我们通过 decker exec 命令进入 container2 容器(它同时拥有默认的 bridge 网络模式+自定义网络模式),因为 container1 没有使用自定义网络模式,所以在 container2 中 ping container1 的别名 ping 不通,但是 ping container1 的 ip 可以 ping 通。此时的 contain2 和 contain3 都使用了自定义网络模式(名称为 mynet), 所以他们之间可以使用别名通信。
【例】

5.2 容器连接方面
- 默认网络:--link 是静态的,不允许链接容器重启,并且被链接容器必须提前创建好;
- 自定义网络:--link 是动态的,支持链接容器重启(以及 IP 变化),且该模式下被链接的容器不必预先建好。
使用 docker network connect 将容器连接到新网络中时,用参数 --link 链接相同的容器时,可以指定不同的别名,它们是针对不同网络的。
Tips:--link 附参
shell--link 容器时指定alias: --link=<Container-Name>:<Alias> --icc=false 隔离性,实现容器间的安全连接
可以执行下面的命令:
# 运行容器使用自定义网络,同时使用--link 链接尚不存在的 container5 容器
docker run --net=mynet -itd --name=container4 --link container5:c5 nginx:alpine
# 创建容器 container5
docker run --net=mynet -itd --name=container5 --link container4:c4 nginx:alpine
# 不同的网络环境连接中,使用不同的 alias 链接
docker network connect --link container5:foo local_alias container4
docker network connect --link container4:bar local_alias container5注意:docker run --link=[CONTAINER_NAME]:[ALIAS] [IMAGE] [COMMAND] 以指定代号访问容器,可避免 IP 变化带来的影响,在容器中即可以用别名访问容器(修改了 host 和改变了 env)。(但是官方不推荐使用 docker network --link), 后续版本有可能会被废弃。所以这里并不是学习重点!
6. 断开/移除自定义网络
6.1 查看 container3 的 ip
我们在宿主机执行下面的命令查看一下 container3 的 IP:
docker inspect container3 # 查看 container3 的元数据,主要看 IP【例】

6.2 移除 container2 的自定义网络模式
# 上面单独给 container2 添加了 mynet 自定义网络,在此予以移除(移除后,只剩下了默认的网络模式 bridge 桥接模式)
docker network disconnect mynet container2
# 先获取三个容器的IP地址
docker inspect container1 # 查看容器1的ip,得知是 "IPAddress": "172.17.0.2"
docker inspect container2 # 查看容器1的ip,得知是 "IPAddress": "172.17.0.3",
docker inspect container3 # 查看容器3的ip,得知是 "IPAddress": "172.25.3.3"
# 再次进入 container2 容器内部 注:如果 contain2 处于 run 状态,可以通过 docker exec -it container2 /bin/sh 命令进入容器内部
docker exec -it container2 /bin/sh
# 此时就不能再通过容器别名 ping 通 conatin3 了,因为此时的 container2 和 container1 没有本质区别,都是只有一个网络模式,使用的是 docker0 网卡的 bridge 桥接模式
ping -w 3 container3 # ping container3 的 容器名(无法ping通,因为conatin2没有使用自定义网络了)
ping -w 3 172.17.0.2 # ping container1 的IP(可以ping通,因为它们在同一个网段)
ping -w 3 172.25.3.3 # ping container3 的IP(无法ping通,因为它们不在同一个网段)移除后,在 container2 容器内部,再尝试用 container3 的容器名称去 ping,发现 ping 不通了,因为 container2 的自定义网络模式 mynet 被移除了,而 container3 的网络模式依然是 mynet。
(1)此时的 container2 的自定义网络模式被移除了,只剩下自定义的网络模式 bridge 桥接模式,此时的 container2 和 container1 处于同一个网络模式下,所以 container2 和 container1 虽然不能通过别名访问,但是可以通过 IP 相互访问(两者 IP 的网段,处于同一网段);
(2)反之,container3 使用了自定义网络模式 mynet,且指定了 IP 为 172.25.3.3,此时的 container3 与 container1、container2 不在同一个网段(container1 和 contain2 在 docker run 时没有额外指明 IP,所以默认是一个网段),所以,此时在 container2 容器内部可以用 IP ping 通 contain1,不能 ping 同 container3。
【例】

6.3 结论
结论:只有使用了自定义网络模式,容器之才可以使用别名通信!
7. 删除自定义网络模式
docker network ls # 查看网络模式列表(此时还是有mynet)
docker network rm mynet # 移除自定义网络mynet(因为container3依然使用的是mynet,所以会报错)
docker kill container3 # kill或stop 容器3
docker network rm mynet # 移除自定义网络mynet
docker network ls # 查看网络模式列表(此时mynet消失)参考资料:
Docker 学习:容器五种(3+2)网络模式 | bridge 模式 | host 模式 | none 模式 | container 模式 | 自定义网络模式详解-CSDN 博客