故障很具体:Docker 找不到可用于新桥接网络的自动子网。这并不表示机器的地址已经用完,也不表示 VPN 出了故障。诊断取决于两个问题:守护进程能看到哪些候选网段,以及分配器在此环境中排除了其中哪些。请按这个顺序处理,因为在第一个问题有答案之前,第二个问题没有意义。

在改动任何东西之前,先确认到底哪里失败

请在运行守护进程的那台主机上执行下面的步骤。连接远程上下文的 shell 描述的是另一台机器,仅这一个错误就可能浪费一小时。

同时把 Engine 版本记进工单。本手册余下部分的每一条经验规则都受版本限制,没有版本的说法只是传闻。

清点你已经拥有的分配

先列出网络,再检查重要的那些:docker network ls,随后是 docker network inspect NETWORK_NAME。读取它们的 IPAM 子网以及各自挂载的容器。多个 Compose 项目消耗的网段比其容器数量看上去更多,因为每个项目往往会创建自己的默认网络。已停止的容器不会释放其所属网络的分配。

也要检查地址池配置,因为默认池有基础范围以及每个网络的掩码长度。每个网络的分配越大,可用网段耗尽得越快,这是容量事实,而不是路由问题。

把数量记下来。它就是判断下一次改动是否有效的基线。

对比守护进程看到的路由

VPN 会影响候选网段的挑选,但具体如何取决于实现。在 Linux 上的 Moby 28.2.2 中,InferReservedNetworks 会收集域名服务器地址以及某些 on-link IPv4 路由,它并不是简单地把每张表里的每条路由都保留下来。收集到的链路路由还会排除未指定的目标地址,因此单凭一条 0.0.0.0/1 路由并不会保留所有地址。另一条较宽的 on-link 前缀,例如 128.0.0.0/1,就可能与常见的 172 和 192 候选网段相交。

在守护进程所在主机上,对比 VPN 连接前后的 ip -4 route show table all。差异就是证据,而版本是结论的适用范围。

不要把某个版本的经验规则推广到所有版本。论坛答案变成策略变更,走的正是这条路。

选择能奏效的最小修复

如果某个已确认闲置的网络占着你需要的网段,请与所有者一起规划定向下线,而不是大范围剪枝。对新网络而言,经明确评审的闲置子网可以完全避开对自动选择的依赖。该子网仍须避开真实的 Docker、LAN 以及必需的 VPN 目标,因为私有并不等于安全。为真实远端子网配置路由,只会把分配报错换成访问中断。

修改 default-address-pools 是关乎未来分配的更广策略。请选择不冲突的基础网段与合适的分配长度,把它与现有的守护进程设置合并,并规划文档中说明的重启影响。现有网络不会被悄悄重新编号。

不要为了分配成功而关闭公司路由推送。明确的地址规划通常能在不削弱强制策略的前提下解决本地问题。

把分配与路由分开验收

改动之后,检查 Docker 实际创建的子网,并测试应用对 VPN 与本地资源的依赖。分配成功与运行时路由正确是两项不同的验收检查,通过前者并不能证明后者。如果应用无法访问隧道后的资源,说明存在被地址池报错掩盖的路由问题。把两项结果都记录进工单。

把路由差异与地址池数量随变更记录一起保存,因为下一次 VPN 客户端更新可能在不改动 Docker 的情况下改变前者。

当其他人能够重复这两项检查并得到相同答案时,这本手册才算完整。

相关文章