> 技术文档 > docker swarm_docker swarm 网段

docker swarm_docker swarm 网段

你遇到的问题是 Docker Swarm 的节点 IP 地址与 Ingress 网络地址段冲突,导致网络通信异常、服务无法正常删除或更新,并出现大量 NetworkDB DeleteEntry failedactive attachments 等警告日志。


🔍 问题分析

你提供的信息中关键点如下:

  • Docker 默认 IP 段10.20.0.0/16
  • Swarm Ingress 网络使用段10.20.0.0/18

注意:10.20.0.0/1810.20.0.0/16 的子集!

这意味着:

  • Docker 分配给容器的 IP 地址范围(10.20.0.0/16包含了 Ingress 网络使用的子网10.20.0.0 - 10.20.63.255)。
  • 当 Ingress 网络尝试分配 IP 或进行 VXLAN 路由时,会与已有的容器网络或主机路由发生冲突。
  • 这会导致:
    • 网络策略混乱
    • 容器间通信失败
    • Ingress 流量无法正确转发
    • 网络资源无法释放(如你看到的“should be removed but still has active attachments”)
    • NetworkDB 报错(分布式数据库状态不一致)

🚨 日志解读

这些日志都指向网络清理失败和资源残留:

network qv0kgb2839wrc6tqv6jh7zpcd should be removed, but still has active attachments

→ 网络还在被使用,但应该被删了。可能是容器没干净退出。

deleteServiceInfoFromCluster NetworkDB DeleteEntry failed for ... does not exist or is already being deleted

→ 多个节点并发操作同一个网络条目,说明状态不一致 —— 常见于网络冲突或脑裂。

rmServiceBinding ... aborted c.serviceBindings[skey] !ok

→ 服务绑定删除失败,可能因为元数据错乱。

error while deleting neighbor entry: no such file or directory

→ ARP/邻居表项删除失败,底层网络设备或命名空间已消失。

这些错误 根本原因就是网络地址空间冲突 + 分布式状态不一致


✅ 解决方案

✅ 步骤 1:避免 IP 地址段重叠(最重要)

你需要 将 Docker 默认 IP 池 和 Ingress 网络隔离,建议调整如下:

✅ 推荐配置:
网络类型 子网 说明 Docker 默认网桥(--bip10.20.128.0/1710.20.128.1 ~ 10.20.255.254 Ingress 网络 10.20.0.0/1810.20.0.1 ~ 10.20.63.254 其他自定义网络 避开以上两个范围

这样两者完全不重叠,避免冲突。


✅ 步骤 2:修改 Docker 默认 IP 段(可选)

如果你使用 dockerd 手动管理网络,可以通过配置 daemon.json 修改默认网桥:

{ \"bip\": \"10.20.128.1/17\", \"default-address-pools\": [ { \"base\": \"10.20.128.0/17\", \"size\": 24 } ]}

修改后需重启所有节点上的 Docker 服务:

sudo systemctl restart docker

⚠️ 注意:这会影响新创建的容器网络,旧容器需要重新创建。


✅ 步骤 3:重建 Ingress 网络(强烈建议)

默认的 ingress 网络一旦创建就很难修改 IP 段。你需要手动删除并重建它。

1. 查看当前 ingress 网络:
docker network inspect ingress
2. 删除默认 ingress(在 manager 节点执行):
docker network rm ingress

⚠️ 必须先停止所有使用 ingress 的服务(如 mode=replicated, 发布了端口的服务)。

3. 重建 ingress 网络(指定子网):
docker network create \\ --driver overlay \\ --ingress \\ --subnet=10.20.0.0/18 \\ --gateway=10.20.0.1 \\ --opt com.docker.network.driver.overlay.vxlanid_list=4096 \\ ingress

注意:vxlanid_list 可避免 VXLAN ID 冲突,推荐固定。

4. 重新部署你的服务

✅ 步骤 4:清理残留网络资源(重要)

有时旧网络未完全清理,导致后续问题。

1. 查看所有 overlay 网络:
docker network ls --filter driver=overlay
2. 删除无用网络(确认无容器使用后再删):
docker network rm <network-id>
3. 清理未使用的网络资源:
docker system prune -adocker network prune

⚠️ prune -a 会删所有未使用资源,请谨慎操作。


✅ 步骤 5:验证通信

  1. 启动一个测试服务:

    docker service create --name test-web --publish 8080:80 nginx
  2. 检查是否可以从任意节点访问 http://:8080

  3. 检查容器 IP 是否在预期范围内:

    docker exec <container> ip addr
  4. 检查 Ingress 网络 IP:

    docker network inspect ingress | grep Subnet

🛡️ 最佳实践建议

项目 建议 Docker 默认网段 10.20.128.0/17 Ingress 网络 10.20.0.0/18 其他业务网络 10.20.64.0/18 开始分段 VXLAN ID 固定设置,避免自动分配冲突 防火墙 开放端口:7946 (tcp/udp), 4789 (udp), 2377 (tcp)

🧰 补充:检查端口和防火墙

确保以下端口在所有 Swarm 节点之间互通:

  • 2377/tcp – 集群管理通信
  • 7946/tcp,udp – 节点通信(gossip)
  • 4789/udp – VXLAN(overlay 网络流量)
# 检查端口监听ss -tulnp | grep -E \'(2377|7946|4789)\'

✅ 总结

问题 原因 解决方法 Ingress 与 Docker IP 冲突 10.20.0.0/18 属于 10.20.0.0/16 分离地址段 网络无法删除 地址冲突 + 残留 attachment 重建 ingress NetworkDB 错误 分布式状态不一致 重启节点、重建网络 服务绑定失败 元数据错乱 清理并重建服务

最终建议操作顺序

  1. 停止所有服务
  2. 删除并重建 ingress 网络(使用独立子网)
  3. 修改 daemon.json 设置 bipdefault-address-pools 避开 10.20.0.0/18
  4. 重启 Docker 服务
  5. 重新部署服务
  6. 验证跨节点访问

如果你提供 docker infodocker network ls 输出,我可以进一步帮你设计更优的 IP 规划。

需要我帮你写一份完整的 daemon.json 和重建 ingress 的脚本吗?