对于网络小白来说,理解 --subnet 和 --gateway 最简单的方法是把它想象成**"给容器们分配一个独立的房间"**。
- 宿主机(你的电脑/服务器):是大房子。
- Docker 网络:是大房子里的一个小房间。
- Subnet (子网):规定这个房间里有多少个床位(IP地址范围)。
- Gateway (网关):是这个房间的"门口",容器要出去上网或找宿主机,必须经过这个门口。
🛑 核心原则:不要和"大房子"里的其他房间撞车
你不能 随便写,是因为如果 Docker 分配的 IP 段和你家里路由器、或者公司网络的 IP 段重复了,就会发生"交通堵塞"(路由冲突),导致你上不了网或连不上打印机。
✅ 第一步:查看宿主机哪些配置需要避开?
你需要避开的是宿主机当前正在使用的网段。请在终端执行以下命令查看:
Linux / macOS:
bash
ip route show
# 或者
route -n
Windows (PowerShell):
powershell
Get-NetRoute | Where-Object { $_.DestinationPrefix -ne '::/0' -and $_.DestinationPrefix -ne '0.0.0.0/0' }
重点关注输出中的这一列:
通常你会看到类似这样的行:
text
default via 192.168.1.1 dev eth0 ...
192.168.1.0/24 dev eth0 ...
172.17.0.0/16 dev docker0 ...
你需要避开的网段是:
- 物理网卡网段 :比如上面的
192.168.1.0/24。这意味着你家路由器大概是192.168.1.x。千万不要 把 Docker subnet 设为192.168.1.x。 - 默认 Docker 网段 :上面的
172.17.0.0/16。这是 Docker 安装时自动创建的默认桥接网络。不要 用172.17.x.x。 - 其他已有 Docker 网络 :如果你之前创建过自定义网络,也要避开。可以用
docker network ls查看。
✅ 第二步:如何安全地书写?(抄作业模板)
为了绝对安全,建议使用 10.x.x.x 开头的私有网段,因为绝大多数家用和公司局域网都不用这个段,几乎不会冲突。
推荐方案 A:最稳妥(推荐新手使用)
这个网段极其冷门,几乎不可能冲突。
bash
docker network create \
--driver bridge \
--subnet 10.20.30.0/24 \
--gateway 10.20.30.1 \
my-safe-net
- 解释 :
10.20.30.0/24:表示 IP 范围是10.20.30.1到10.20.30.254。10.20.30.1:作为网关(门口)。- 容器会自动获得
10.20.30.2,10.20.30.3等 IP。
推荐方案 B:如果你想要更大的空间
如果你预计会有超过 250 个容器,可以用 /16。
bash
docker network create \
--driver bridge \
--subnet 10.50.0.0/16 \
--gateway 10.50.0.1 \
my-big-net
- 解释 :
10.50.0.0/16:表示 IP 范围是10.50.0.1到10.50.255.254(约 6 万个 IP)。10.50.0.1:作为网关。
❌ 绝对不要写的例子(踩坑指南)
假设你的 ip route 显示默认网关是 192.168.1.1:
-
❌ 错误写法 1(冲突):
bash--subnet 192.168.1.0/24 --gateway 192.168.1.1后果:你和路由器抢 IP,全网瘫痪。
-
❌ 错误写法 2(冲突):
bash--subnet 172.17.0.0/24 --gateway 172.17.0.1后果:和 Docker 默认网络冲突,创建失败。
-
❌ 错误写法 3(逻辑错误):
bash--subnet 192.168.10.0/24 --gateway 192.168.20.1后果:网关不在子网里,报错
Gateway ip ... is not in the range。
💡 总结:小白万能公式
如果你不想去查 ip route,只想无脑创建一个能用的网络,请直接复制下面这条命令,99.9% 不会出错:
bash
docker network create \
--driver bridge \
--subnet 10.10.10.0/24 \
--gateway 10.10.10.1 \
my-network
验证是否成功:
bash
docker network inspect my-network
如果能看到 JSON 输出,且 Subnet 是 10.10.10.0/24,那就大功告成了!