☰
Weave Net 多子网自动分配(Multi-Subnet IPAM):用 WEAVE_CIDR 与 --ipalloc-default-subnet 实现跨子网寻址与隔离
2026/10/9 1:31:59 网站建设 项目流程
  • 网络
  • 云原生

【免费下载链接】weave

Simple, resilient multi-host containers networking and more.

项目地址:https://gitcode.com/gh_mirrors/weave4/weave
点击查看免费下载

本文聚焦 Weave Net(当前仓库weave4/weave)的 IPAM 核心能力之一——自动地址分配跨越多个子网。默认情况下 Weave Net 会把所有容器放入覆盖整个分配范围的单一子网,而通过WEAVE_CIDR环境变量、--ipalloc-default-subnet启动参数,你可以让容器按需落在不同子网,实现基于子网的网络隔离,并在同一分配范围内混合使用自动分配与手工指定地址。读完本文,你将掌握多子网分配的完整配置语法、默认子网约束技巧,以及底层weave脚本与weaver主程序的实现逻辑。

为什么需要多子网分配

IP 子网(subnet)在 Weave Net 中用来定义或限制路由范围。默认情况下,Weave Net 将全部容器放入一个横跨整个分配范围(universe)的子网,使得每一个接入 Weave 的容器都能与其它容器互通。这一点在 Allocating IP Addresses(IPAM 总览) 中也有说明:默认分配范围为10.32.0.0/12。

当你需要应用隔离时,可以让不同应用的容器运行在不同的子网上:同一应用内的容器互通,不同应用的容器彼此隔离。这正是“isolation-through-subnets”策略的基础——把传统物理网络的子网隔离手法原样搬到容器网络上。

用 WEAVE_CIDR 指定容器所属子网

要在创建容器时请求某个特定子网中的地址,只需在docker run时设置环境变量WEAVE_CIDR,取值形如net:<subnet>:

host1$ docker run -e WEAVE_CIDR=net:10.2.7.0/24 -ti weaveworks/ubuntu

这里net:前缀告诉 Weave Net:请从10.2.7.0/24这个子网里自动分配一个地址(地址仍由 IPAM 自动挑选,只是限定在指定子网内)。

一次请求多个子网地址 + 手工地址

WEAVE_CIDR可以一次给出多个以空格分隔的地址请求,支持:

  • net:<subnet>:从指定子网自动分配一个地址;
  • ip:<cidr>:手工指定一个具体地址(该地址必须在自动分配范围之外,或在自动分配范围中由你预留的部分);
  • net:default:从默认子网自动分配地址(详见下文)。

例如,下面的命令让容器同时获得10.2.7.0/24、10.2.8.0/24两个子网中各一个自动分配的地址,再手工挂上一个10.3.9.1/24的地址:

host1$ docker run -e WEAVE_CIDR="net:10.2.7.0/24 net:10.2.8.0/24 ip:10.3.9.1/24" -ti weaveworks/ubuntu

注意:每个子网的.0(网络地址)与.-1(广播地址)不会被分配使用,这符合 RFC 1122 对主机寻址的要求。

从脚本源码看 WEAVE_CIDR 的解析路径

仓库根目录的 weave 脚本是weave命令的实际入口,多子网参数在collect_cidr_args()(weave 脚本 L875-L883)中解析:

collect_cidr_args() { CIDR_ARGS="" CIDR_ARG_COUNT=0 while [ "$1" = "net:default" ] || is_cidr "$1" || is_cidr "${1#ip:}" || is_cidr "${1#net:}" ; do CIDR_ARGS="$CIDR_ARGS ${1#ip:}" CIDR_ARG_COUNT=$((CIDR_ARG_COUNT + 1)) shift 1 done }

可以看到脚本接受三种参数形态:裸 CIDR(如10.3.9.1/24)、ip:前缀、net:前缀,以及特殊的net:default。随后ipam_cidrs()(weave 脚本 L900-L952)分派它们:

  • 带net:前缀的参数走IPAM 自动分配:net:default映射到POST /ip/<container_id>(即默认子网),net:<subnet>映射到POST /ip/<container_id>/<subnet>;
  • 裸地址 /ip:参数走手工指定:执行PUT /ip/<container_id>/<cidr>,若与已有地址冲突会告警但继续执行;
  • 若完全没有传入地址,脚本默认退化为net:default(weave 脚本 L925),即“不指定子网就分配默认子网地址”。

需要说明的是,WEAVE_CIDR机制依赖 Weave 的 Docker proxy/plugin 拦截容器创建流程,将环境变量中的 CIDR 参数注入上述分配逻辑;若使用 CNI 插件,则请参考 手动指定 IP 地址 中的 static allocator 方案。

约束默认子网:--ipalloc-range 与 --ipalloc-default-subnet

当网络里有多个子网时,通常需要约束默认子网——即不提供WEAVE_CIDR时分配器挑选的子网——使其不与其它子网重叠。这通过--ipalloc-default-subnet完成:

host1$ weave launch --ipalloc-range 10.2.0.0/16 --ipalloc-default-subnet 10.2.3.0/24

这里:

  • --ipalloc-range 10.2.0.0/16:声明整个分配范围(universe),即将来所有自动分配都发生在10.2.0.0/16内,且该值必须与网络内所有主机一致(参考 Choosing an Allocation Range);
  • --ipalloc-default-subnet 10.2.3.0/24:当没有显式指定子网时,分配器默认从10.2.3.0/24里挑地址。

于是你可以放心地把其它子网(如10.2.7.0/24、10.2.8.0/24)留给需要隔离的应用,默认容器都落在10.2.3.0/24,互不干扰。

符号写法 net:default

在指定地址时,默认子网可以用net:default符号表示。例如下面这条命令会让容器同时获得默认子网与10.2.2.0/24子网中的地址:

host1$ docker run -e WEAVE_CIDR="net:default net:10.2.2.0/24" -ti weaveworks/ubuntu

这在 Isolating Applications on a Weave Network 中也被用于“多子网 + 默认子网”的组合分配。

源码级约束检查

--ipalloc-default-subnet与--ipalloc-range的强耦合关系,在 prog/weaver/main.go 中有清晰的校验逻辑:

  • 参数定义(main.go L195-L197):--ipalloc-range为 “IP address range reserved for automatic allocation, in CIDR notation”,--ipalloc-default-subnet为 “subnet to allocate within by default, in CIDR notation”;
  • 前置条件(main.go L62-L83):若设置了--ipalloc-default-subnet却没有--ipalloc-range,Enabled()直接Log.Fatal("--ipalloc-default-subnet specified without --ipalloc-range.")——两者必须成对出现;
  • 重叠校验(main.go L643-L653):在createAllocator中,默认子网经ipam.ParseCIDRSubnet解析后,必须与分配范围Overlaps,否则直接退出:"IP address allocation default subnet %s does not overlap with allocation range %s"。

也就是说,默认子网必须是分配范围的子集,不能越界——这从实现层面保证了“默认子网一定落在 universe 内”。

混合自动分配与手工分配:用范围差预留地址段

容器可以在同一范围内混合使用“自动分配的地址”和“手工挑选的地址”。不过你会遇到一个实际问题:自动分配器可能已经把你想要的具体地址占用了。

解决办法是:让--ipalloc-range小于--ipalloc-default-subnet,从而在默认子网中留出一段“自动分配器永远不会碰”的地址空间。官方示例:

host1$ weave launch --ipalloc-range 10.9.0.0/17 --ipalloc-default-subnet 10.9.0.0/16

配合这一配置,所有容器都在10.9.0.0/16子网内运行,但:

  • 自动分配只使用10.9.0.0/16的低半段(10.9.0.0/17,即分配范围 universe 所覆盖的部分);
  • 上半段(10.9.128.0/17,位于默认子网内但在分配范围外)留给手工分配,自动分配器绝不会踏足。

随后你既可以直接docker run(自动拿到低半段地址),也可以docker run -e WEAVE_CIDR=ip:10.9.200.1/16 ...(手工指定上半段地址)。注意ip:手工指定走的是PUT /ip/<container_id>/<cidr>路径,且脚本会对冲突地址给出告警(weave 脚本 L943-L949)。

多子网分配的实践要点

  1. 同一分配范围、多个默认子网:要隔离应用,先在每个主机上用相同参数启动:weave launch --ipalloc-range 10.2.0.0/16 --ipalloc-default-subnet 10.2.1.0/24,然后不同应用分别用WEAVE_CIDR=net:<子网>启动(完整 ping 验证示例见 Isolating Applications on a Weave Network);
  2. 默认子网必须在分配范围内:这是weaver启动时的硬性校验,规划网段时务必让--ipalloc-default-subnet⊆--ipalloc-range;
  3. net:依赖 IPAM 开启:从脚本实现看,若 IPAM 未启用却使用net:请求分配,会返回错误提示 “IP address allocation must be enabled to use 'net:'”(weave 脚本 L935-L938);
  4. 地址保留:每个子网的网络地址(.0)与广播地址(.255等.-1)不会被分配;
  5. 不要与 AWS VPC 模式混用:脚本在 AWSVPC 模式下禁止为容器指定具体 IP 或子网(weave 脚本 L910-L913)。

延伸阅读

  • Allocating IP Addresses(IPAM 总览):初始化策略(seed/consensus/observer)、quorum 机制、分配范围选择与数据持久化;
  • Isolating Applications on a Weave Network:基于多子网的完整应用隔离实操(含 ping 验证输出);
  • Manually Specifying the IP Address of a Container:ip:手工指定地址在 proxy / plugin / CNI 三种接入方式下的用法;
  • IP addresses and routes:CIDR 记法与路由基础;
  • Starting, Stopping and Removing Peers:多主机网络扩容与维护。
  • 网络
  • 云原生

【免费下载链接】weave

Simple, resilient multi-host containers networking and more.

项目地址:https://gitcode.com/gh_mirrors/weave4/weave
点击查看免费下载
上一篇:RPG Maker MV/MZ插件生态:从性能优化到动态系统的技术实践
下一篇:如何用llama-cpp-python轻松部署本地AI大语言模型

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询