1. 概述

Docker 改变了开发者构建、共享和运行容器化应用的方式。尽管它简化了工作流,但在使用过程中仍可能遇到一些令人困惑的错误。其中,在尝试删除网络时遇到的 “Network has active endpoints” 错误就非常常见。

这个错误的出现,是因为 Docker 检测到目标网络中仍然存在“活跃的端点(endpoints)”,即使这些容器已经被停止。本文将深入解析 Docker 网络的基本概念,解释 endpoint 是什么、为什么会残留,以及如何解决这个错误。我们不仅会列出相关命令,还会结合实际场景说明其背后原理,帮助你彻底理解并应对该问题。


2. 什么是 Endpoint?常见错误原因

在 Docker 中,endpoint 是容器与网络之间的连接点。可以理解为:每个容器连接到某个网络时,Docker 会为其创建一个虚拟网卡,并将其插入到对应的虚拟网络中。这个连接点就是 endpoint。

✅ 示例:运行一个带网络的容器

# docker run -d --name my_app1 --network my_bridge_net nginx

这条命令背后发生了什么?

  • 容器 my_app1 启动
  • Docker 为其分配 IP 地址
  • 创建网络接口并连接到 my_bridge_net 网络

Docker 默认使用的是 bridge 网络驱动。当我们创建自定义网络时:

# docker network create my_bridge_net

Docker 会创建一个虚拟交换机、分配子网,并允许连接到该网络的容器通过虚拟网卡通信。

⚠️ Endpoint 生命周期

Endpoint 的生命周期由以下两个操作控制:

  • 容器被删除(docker rm
  • 容器从网络断开(docker network disconnect

⚠️ 注意: 停止容器(docker stop)并不会删除 endpoint,这正是导致“network has active endpoints”错误的主要原因。

为什么 Endpoint 会影响网络删除?

Docker 设计上不允许删除仍存在连接的网络,这是为了防止破坏正在进行的通信或配置,避免数据丢失或系统不稳定。因此,当你尝试删除一个仍有 endpoint 的网络时,就会出现如下错误:

Error response from daemon: error while removing network: network my_bridge_net id <hash>: network has active endpoints

3. 根本原因分析

3.1. 错误信息解析

执行删除命令:

# docker network rm my_bridge_net

返回错误:

Error response from daemon:
error while removing network: network <network-name> id <hash>: network has active endpoints

说明:即使容器已经停止,只要它们仍连接到该网络,Docker 就不允许删除该网络。

常见原因包括:

  • 停止但未删除的容器
  • 使用 Docker Compose 时遗留的孤儿容器
  • 手动创建的容器连接到了共享网络上

3.2. 如何定位是哪些容器导致的?

使用 docker network inspect 查看网络连接的容器:

# docker network inspect \
  --format '{{range $cid,$v := .Containers}}{{printf "%s: %s\n" $cid $v.Name}}{{end}}' \
  my_bridge_net

e5f1a3c84b3b: my_app1
9d8c7b6a5f4e: my_app2

输出表明:my_app1my_app2 仍然连接在该网络上,这就是导致删除失败的原因。


4. 解决方案汇总

4.1. 停止并删除容器

最彻底的方式是停止并删除相关容器:

# docker container stop my_app1 my_app2
# docker container rm my_app1 my_app2
# docker network rm my_bridge_net

优点:彻底清除 endpoint,确保网络可删除
缺点:会丢失容器状态

4.2. 强制断开容器连接(保留容器)

如果你希望保留容器状态,可以选择断开其与网络的连接:

# docker network disconnect -f my_bridge_net my_app1
# docker network disconnect -f my_bridge_net my_app2
# docker network rm my_bridge_net

优点:不删除容器,仅移除 endpoint
缺点:需要手动逐个断开连接

4.3. 重启 Docker 服务(处理“幽灵”Endpoint)

在极少数情况下,即使容器已被删除,endpoint 仍可能残留。此时可尝试重启 Docker:

# Linux 系统下重启 Docker
$ sudo systemctl restart docker

# 验证服务是否恢复
$ docker info

# 再次尝试删除网络
$ docker network rm my_bridge_net

⚠️ 注意:此方法适用于调试,不建议频繁使用,可能会影响其他运行中的容器。


5. Docker Compose 相关问题处理

5.1. Docker Compose 网络泄漏问题

Docker Compose 会自动创建一个默认网络,如 <project>_default。通常我们使用:

# docker compose down

来清理环境。但有时这个命令并不会清理所有 endpoint。

解决方案:添加 --remove-orphans 参数:

# docker compose down --remove-orphans
# docker network rm <project>_default

⚠️ 注意:使用 --remove-orphans 时要小心,可能会误删其他项目中使用相同网络的容器。

5.2. Jenkins Pipeline 清理失败问题

在 CI/CD 流水线中,经常使用 Jenkins 脚本清理环境:

# docker compose down
# docker network rm my_bridge_net

如果报错,可以尝试:

# docker compose down --remove-orphans
# docker network rm my_bridge_net

此外,建议在删除网络前先检查其连接状态,确保清理过程可预测。


6. 预防措施

6.1. 避免 Docker Compose 管理共享网络

在某些 CI/CD 场景中,Docker Compose 可能会误操作共享网络。为避免此类问题,可以在 docker-compose.yml 中将网络声明为外部:

networks:
  my_bridge_net:
    external: true

优点:Composes 不会尝试创建或删除该网络,避免冲突

6.2. CI Pipeline 中避免网络重用

在并行执行的 CI 流水线中,多个任务共享同一个网络名会导致冲突。建议使用动态命名:

# network_name: myapp_${GIT_COMMIT}

优点:每个任务使用唯一网络名,避免重名和手动清理


7. 总结

本文详细解析了 Docker 删除网络时报 “network has active endpoints” 错误的原因,并介绍了多种解决方案,包括:

  • 停止并删除容器
  • 强制断开连接
  • 重启 Docker 服务(处理“幽灵”endpoint)

此外,还讨论了 Docker Compose 中常见的网络泄漏问题及 Jenkins Pipeline 中的清理失败问题,并给出了预防措施:

  • 将共享网络声明为 external
  • 使用动态网络命名避免冲突

掌握这些技巧后,你可以更高效地管理 Docker 网络资源,避免踩坑,提升 CI/CD 流程的稳定性。


原始标题:“Network Has Active Endpoints” Error While Removing Network in Docker