问题描述
今天在使用 Docker Compose 部署周报系统时,遇到了网络创建失败的错误:
错误类型一:无可用地址池
failed to create network deploy_weekly-network: Error response from daemon: could not find an available, non-overlapping IPv4 address pool among the defaults to assign说明:这个错误发生在让 Docker 自动分配网络地址时,Docker 的默认地址池(172.17.0.0/16, 172.18.0.0/16, 172.19.0.0/16 等)都被占用了,无法找到可用的非重叠 IPv4 地址池。
错误类型二:子网地址冲突
failed to create network deploy_weekly-network: Error response from daemon: Pool overlaps with other one on this address space问题分析
1. 初始配置
最初的docker-compose.yml配置中指定了固定的网络子网:
networks:weekly-network:driver:bridgeipam:driver:defaultconfig:-subnet:172.20.0.0/24gateway:172.20.0.12. 错误原因
Docker 网络子网冲突的主要原因:
错误类型一:could not find an available, non-overlapping IPv4 address pool among the defaults to assign
- 默认地址池耗尽:Docker 的默认地址池(172.17.0.0/16 到 172.31.0.0/16)已被全部占用
- 大量容器部署:服务器上运行了大量 Docker 容器,消耗了所有默认网络段
- 未清理网络:已删除的容器对应的网络未被清理,仍然占用地址池
Docker 默认地址池:
172.17.0.0/16 (bridge 网络默认) 172.18.0.0/16 172.19.0.0/16 ... 172.31.0.0/16当这些地址段都被占用时,Docker 无法自动分配新的网络。
错误类型二:Pool overlaps with other one on this address space
- 子网地址重复:
172.20.0.0/24与系统中已存在的 Docker 网络使用了相同的 IP 地址段 - 多项目部署:在同一台服务器上运行多个 Docker Compose 项目时,容易产生子网冲突
- 历史遗留:之前创建的容器或网络未被清理,占用了 IP 地址段
3. 相关警告
同时发现了版本警告:
WARN[0000] /home/jiangcaidu/Exp/deploy/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion解决方案
方案一:更换子网地址
尝试 1:使用 172.25.0.0/24
networks:weekly-network:driver:bridgeipam:driver:defaultconfig:-subnet:172.25.0.0/24gateway:172.25.0.1结果:仍然冲突 ❌
尝试 2:使用 10.0.0.0/24
networks:weekly-network:driver:bridgeipam:driver:defaultconfig:-subnet:10.0.0.0/24gateway:10.0.0.1结果:成功创建 ✅
方案二:移除版本字段
删除过时的version: '3.8'字段:
# 删除这一行# version: '3.8'services:# ...方案三:使用自动网络分配(备选)
如果不想手动指定子网,可以让 Docker 自动分配:
networks:weekly-network:driver:bridge# 不指定 ipam 配置,让 Docker 自动分配注意:如果出现"could not find an available, non-overlapping IPv4 address pool among the defaults to assign"错误,说明 Docker 的默认地址池已耗尽。此时必须手动指定子网地址。
方案四:清理未使用的网络
当默认地址池耗尽时,可以先清理未使用的网络:
# 查看所有网络dockernetworkls# 清理未使用的网络dockernetwork prune# 查看网络使用情况dockernetwork inspect bridge清理后,Docker 可以回收被占用的地址池,重新尝试自动分配。
排查步骤
1. 查看现有网络
dockernetworkls2. 检查网络详细信息
dockernetwork inspect<网络名称>3. 清理未使用的网络
dockernetwork prune4. 完全清理并重新开始
# 停止并删除容器、网络、卷docker-composedown -v# 重新启动docker-composeup -d最佳实践
1. 子网选择建议
推荐使用以下子网范围,避免冲突:
10.0.0.0/8- 私有网络 A 类地址172.16.0.0/12- 私有网络 B 类地址(注意:Docker 默认使用 172.17.0.0/16)192.168.0.0/16- 私有网络 C 类地址
推荐顺序:
- 优先使用
10.x.x.x范围 - 其次使用
192.168.x.x范围 - 最后考虑
172.16-31.x.x范围
2. 项目命名规范
为每个项目使用独特的网络名称:
networks:project-name-network:driver:bridge3. 配置文件优化
- 移除过时字段:删除
version字段 - 使用环境变量:通过环境变量配置子网,便于不同环境部署
- 文档化:在 README 中记录使用的子网范围
最终配置
services:mysql:image:mysql:8.4.5container_name:weekly-mysqlrestart:alwaysnetworks:-weekly-networkbackend:build:context:./backenddockerfile:Dockerfilecontainer_name:weekly-backendrestart:alwaysdepends_on:-mysqlnetworks:-weekly-networkfrontend:image:nginx:latestcontainer_name:weekly-frontendrestart:alwaysports:-"5173:80"depends_on:-backendnetworks:-weekly-networknetworks:weekly-network:driver:bridgeipam:driver:defaultconfig:-subnet:10.0.0.0/24gateway:10.0.0.1经验总结
- 网络冲突是常见问题:在多项目部署环境中,网络子网冲突是高频问题
- 先检查后配置:在指定子网前,先查看现有网络配置
- 使用私有地址:优先使用 RFC 1918 定义的私有地址段
- 保持配置简洁:Docker Compose 新版本不需要
version字段 - 文档化配置:记录每个项目使用的网络配置,便于维护
相关命令速查
# 查看所有网络dockernetworkls# 查看网络详情dockernetwork inspect<网络名称># 清理未使用的网络dockernetwork prune# 创建自定义网络dockernetwork create --driver bridge --subnet10.0.0.0/24 my-network# 连接容器到网络dockernetwork connect<网络名称><容器名称># 断开容器与网络的连接dockernetwork disconnect<网络名称><容器名称># 删除网络dockernetworkrm<网络名称>参考资源
- Docker 网络文档
- Docker Compose 网络配置
- RFC 1918 - 私有互联网地址分配
如果部署中遇到同样的问题,觉得有帮助,欢迎点赞收藏!有问题欢迎评论区交流~