错误原因:
Docker 给容器分配内网 IP 的「地址库」已经用完了,没法给新创建的容器 / 网络分配新的 IP 了。
Docker 的「地址池」是什么?
Docker 启动时会预设几个「私有 IP 网段」(比如172.17.0.0/16、172.18.0.0/16、172.19.0.0/16等),这些网段就是「预定义地址池」。172.17.0.0/16网段能分配65534个 IP(172.17.0.1 ~ 172.17.255.254);每个 Docker 自定义网络,会从这些地址池里「切一块子网」(默认是
/24,即 254 个 IP)。
错误怎么产生的?
每次你执行
docker-compose up创建新网络时,Docker 会从预定义地址池里找一个未被使用的/24子网分配给这个网络。- 比如第一次创建网络,分配
172.17.0.0/24; - 第二次创建,分配
172.17.1.0/24; - 当
172.17.0.0/16里的 256 个/24子网都被用完后,Docker 会用下一个预定义池172.18.0.0/16; - 当所有预设的地址池(172.17、172.18、172.19…)里的子网都被分配完,就会报
all predefined address pools have been fully subnetted错误。
- 比如第一次创建网络,分配
为什么服务器会出现这个问题?
不是真的用了几万 / 几十万 IP,而是:- 反复执行
docker-compose down/up,每次down时没有清理旧网络(Docker 不会自动删除未使用的网络); - 这些「僵尸网络」占用了大量子网,慢慢把 Docker 的预定义地址池耗尽了;
- 哪怕你的容器已经删除,只要网络没删,子网就会一直被占用。
- 反复执行
- 登录服务器,执行以下命令清理废弃网络:
1. 查看所有 Docker 网络(找到未使用的网络)
docker network ls2. 清理所有未被容器使用的网络(安全,不会删除正在使用的网络)
docker network prune -f上面的方法是比较推荐的。
但是如果清理后仍频繁出现该问题,需要修改 Docker 配置文件,增加自定义地址池:
# 1. 创建/编辑 Docker 配置文件 vim /etc/docker/daemon.json # 2. 添加以下内容(新增 192.168.0.0/16 地址池,避免和默认池冲突) { "default-address-pools": [ {"base":"192.168.0.0/16","size":24} ] } # 3. 重启 Docker 服务 systemctl restart docker第一个方法我自己实践过,解决了我的问题。
第二个方法我没用过,但是理论上应该能解决