使用Docker Compose 部署时网络冲突问题排查与解决

问题描述

今天在使用 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 配置中指定了固定的网络子网:

yaml 复制代码
networks:
  weekly-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/24
          gateway: 172.20.0.1

2. 错误原因

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
yaml 复制代码
networks:
  weekly-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.25.0.0/24
          gateway: 172.25.0.1

结果:仍然冲突 ❌

尝试 2:使用 10.0.0.0/24
yaml 复制代码
networks:
  weekly-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 10.0.0.0/24
          gateway: 10.0.0.1

结果:成功创建 ✅

方案二:移除版本字段

删除过时的 version: '3.8' 字段:

yaml 复制代码
# 删除这一行
# version: '3.8'

services:
  # ...

方案三:使用自动网络分配(备选)

如果不想手动指定子网,可以让 Docker 自动分配:

yaml 复制代码
networks:
  weekly-network:
    driver: bridge
    # 不指定 ipam 配置,让 Docker 自动分配

注意:如果出现"could not find an available, non-overlapping IPv4 address pool among the defaults to assign"错误,说明 Docker 的默认地址池已耗尽。此时必须手动指定子网地址。

方案四:清理未使用的网络

当默认地址池耗尽时,可以先清理未使用的网络:

bash 复制代码
# 查看所有网络
docker network ls

# 清理未使用的网络
docker network prune

# 查看网络使用情况
docker network inspect bridge

清理后,Docker 可以回收被占用的地址池,重新尝试自动分配。

排查步骤

1. 查看现有网络

bash 复制代码
docker network ls

2. 检查网络详细信息

bash 复制代码
docker network inspect <网络名称>

3. 清理未使用的网络

bash 复制代码
docker network prune

4. 完全清理并重新开始

bash 复制代码
# 停止并删除容器、网络、卷
docker-compose down -v

# 重新启动
docker-compose up -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 类地址

推荐顺序

  1. 优先使用 10.x.x.x 范围
  2. 其次使用 192.168.x.x 范围
  3. 最后考虑 172.16-31.x.x 范围

2. 项目命名规范

为每个项目使用独特的网络名称:

yaml 复制代码
networks:
  project-name-network:
    driver: bridge

3. 配置文件优化

  • 移除过时字段 :删除 version 字段
  • 使用环境变量:通过环境变量配置子网,便于不同环境部署
  • 文档化:在 README 中记录使用的子网范围

最终配置

yaml 复制代码
services:
  mysql:
    image: mysql:8.4.5
    container_name: weekly-mysql
    restart: always
    networks:
      - weekly-network

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: weekly-backend
    restart: always
    depends_on:
      - mysql
    networks:
      - weekly-network

  frontend:
    image: nginx:latest
    container_name: weekly-frontend
    restart: always
    ports:
      - "5173:80"
    depends_on:
      - backend
    networks:
      - weekly-network

networks:
  weekly-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 10.0.0.0/24
          gateway: 10.0.0.1

经验总结

  1. 网络冲突是常见问题:在多项目部署环境中,网络子网冲突是高频问题
  2. 先检查后配置:在指定子网前,先查看现有网络配置
  3. 使用私有地址:优先使用 RFC 1918 定义的私有地址段
  4. 保持配置简洁 :Docker Compose 新版本不需要 version 字段
  5. 文档化配置:记录每个项目使用的网络配置,便于维护

相关命令速查

bash 复制代码
# 查看所有网络
docker network ls

# 查看网络详情
docker network inspect <网络名称>

# 清理未使用的网络
docker network prune

# 创建自定义网络
docker network create --driver bridge --subnet 10.0.0.0/24 my-network

# 连接容器到网络
docker network connect <网络名称> <容器名称>

# 断开容器与网络的连接
docker network disconnect <网络名称> <容器名称>

# 删除网络
docker network rm <网络名称>

参考资源


如果部署中遇到同样的问题,觉得有帮助,欢迎点赞收藏!有问题欢迎评论区交流~

相关推荐
2501_927773073 小时前
uboot挂载
linux·运维·服务器
好好研究3 小时前
SpringBoot扩展SpringMVC
java·spring boot·spring·servlet·filter·listener
qidun2103 小时前
埃夫特机器人防护服使用范围详解-避免十大应用误区
网络·人工智能
Tim风声(网络工程师)3 小时前
防火墙-长链接、介绍作用
运维·服务器·网络
视觉AI3 小时前
【踩坑实录】Windows ICS 共享网络下,国产化盒子 SSH 连接异常的完整分析
网络·windows·ssh
独自破碎E3 小时前
Spring Boot + LangChain4j 报错:Bean 类型不匹配的解决办法
spring boot·python·pycharm
tb_first3 小时前
SSM速通3
java·jvm·spring boot·mybatis
weixin_395448914 小时前
main.c_cursor_0202
前端·网络·算法
橙露4 小时前
NNG通信框架:现代分布式系统的通信解决方案与应用场景深度分析
运维·网络·tcp/ip·react.js·架构