☰
libnetwork 演进全览:从 CNM 容器网络模型到嵌入式 DNS(v0.3.0 – v0.5.6)
2026/10/7 16:06:10 网站建设 项目流程
  • 操作系统
  • 云原生
  • 容器运行时

【免费下载链接】os

Tiny Linux distro that runs the entire OS as Docker containers

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

本文以仓库内 vendor/github.com/docker/libnetwork/CHANGELOG.md 为骨架,系统梳理 libnetwork 从 0.3.0 到 0.5.6 的关键版本演进:CNM(Container Networking Model)的引入、IPAM 驱动的诞生、嵌入式 DNS 对 /etc/hosts 服务发现的取代,以及 libnetwork 在本仓库(RancherOS)中被实际消费的方式(v0.5.6 版本锁定与 resolvconf 子包的应用)。读完本文,你将掌握 libnetwork 各版本的里程碑特性、底层调用链原理,以及如何在该仓库中找到对应的真实配置与源码证据。

libnetwork 是什么:以驱动/插件模型抽象容器网络

libnetwork 是 Docker 官方提供的、用于连接容器的原生 Go 网络库。正如其 README.md 所述,它的目标是交付一个健壮的 Container Network Model(CNM),为应用提供一致的编程接口与所需的网络抽象。

libnetwork 采用驱动/插件模型:网络实现(bridge、overlay、远程插件等)通过驱动注入,而对外暴露统一、简单的 Network Model。其核心编程接口从 README 的示例代码中可以完整看到:

// 1. 创建 controller(选择并配置网络驱动) networkType := "bridge" controller, err := libnetwork.New(config.OptionDriverConfig(networkType, genericOption)) // 2. 创建网络 network, err := controller.NewNetwork(networkType, "network1") // 3. 为每个容器分配 IP 与接口,创建 endpoint ep, err := network.CreateEndpoint("Endpoint1") // 4. 创建容器 sandbox sbx, err := controller.NewSandbox("container1", libnetwork.OptionHostname("test"), libnetwork.OptionDomainname("docker.io")) // 5. sandbox 通过 join API 加入 endpoint err = ep.Join(sbx) // 6. 通过 Info() API 查询 endpoint 运行数据(如 MAC 地址) epInfo, err := ep.DriverInfo()

这条调用链(New → NewNetwork → CreateEndpoint → NewSandbox → Join → DriverInfo)构成了 CNM 的"控制器-网络-端点-沙箱"四层抽象,也是后续所有版本特性(IPAM、别名、服务发现)生长的地基。其长期目标在 ROADMAP.md 中表述为:将 Docker Engine 与 libcontainer 中的网络逻辑模块化为单一可复用库,支持本地与远程驱动,并提供独立的dnet管理与测试工具(Makefile 中build-local目标正是产出bin/dnet二进制)。

0.3.0(2015-05-27):CNM 诞生,Docker 网络被整体替换

CHANGELOG 记录的第一个正式版本做了两件奠基性的事:

  • 引入 CNM(Container Networking Model):确立控制器、网络、端点、沙箱四类对象的标准模型与编程接口;
  • 用 CNM + Bridge 驱动替换原有 Docker 网络实现:即 ROADMAP.md 中"Replace the networking subsystem of Docker Engine, with libnetwork"的落地。

从此,Docker 的网络栈从内部自研实现转向一个可独立演进、可插拔驱动的库。

0.4.0(2015-07-24):实验特性密集落地

0.4.0 是一个"实验功能铺路"版本,一次引入了四条新战线:

  • Overlay 驱动的实验版本:为后续多主机组网(multi-host networking)做铺垫;
  • 网络插件(network plugins)的实验版本:验证驱动/插件模型的可扩展性;
  • 网络与服务的实验性 UX;
  • 基于 /etc/hosts 的服务发现(实验性):这是服务发现功能的第一代形态,后来的嵌入式 DNS 正是它的替代者。

工程层面同时完成两件事:集成 libkv(为分布式键值存储接入做准备,服务于 overlay 网络的元数据同步),以及修复 osl(网络命名空间管理)的一批问题,并整体提升测试覆盖率——这与 Makefile 中run-tests目标对每个包含 Go 文件的目录并行执行带覆盖率收集的go test的做法一脉相承。

0.5.0(2015-10-30):多主机组网转正,IPAM 正式登场

0.5.0 是第一个里程碑式"转正"版本:

  • Docker 多主机网络(multi-host networking)退出实验通道:overlay 驱动经过 0.4.0 的孵化后正式可用;
  • 引入 IP Address Management(IPAM)与 IPAM 驱动:IP 地址的分配/回收从具体网络驱动中剥离出来,形成独立子模型——这是 0.5.1 允许用户自定 IP、0.5.2 支持 IPAM 驱动选项的前提;
  • 弃用默认 bridge 网络上的服务发现:服务发现职责开始从网络层向 DNS 层迁移;
  • 引入新的网络 UX;
  • bridge 驱动支持多网络;
  • 使用 boltdb 实现本地持久化:网络/端点元数据落盘,为跨重启的自我修复(见 0.5.5)打下基础。

0.5.1(2015-12-07):允许用户为容器指定 IP 地址

0.5.1 的核心用户能力是允许用户自行分配容器 IP 地址,并修复了 docker/docker#18214、#18380 两个上游问题。该能力由 0.5.0 引入的 IPAM 子模型承载:用户指定的地址经 IPAM 校验并纳入分配池,而不是由驱动任意分配。

0.5.2(2015-01-08):嵌入式 DNS 取代 /etc/hosts 服务发现

0.5.2 是本 CHANGELOG 中功能密度最高的版本之一,服务发现架构在此完成换代:

  • 嵌入式 DNS(Embedded DNS)取代基于 /etc/hosts 的服务发现:DNS 解析能力内嵌进 libnetwork,容器内通过内嵌 DNS 解析服务名与别名,替代此前向 /etc/hosts 追加条目再分发的方式;
  • 容器本地别名(container local alias)与网络级别名(network-scoped alias)支持:同一容器可在不同网络中使用不同别名,别名作用域区分容器与网络两个层级;
  • 内部网络模式的后端支持:对应 0.5.3 中 bridge 驱动暴露的internal网络选项,内部网络不提供出站网关/端口发布,用于隔离;
  • 支持 IPAM 驱动选项:IPAM 驱动可以接收自定义配置参数;
  • 修复 overlay veth 清理问题(docker/docker#18814)与 docker/docker#19139;
  • 禁用 IPv6 重复地址检测(DAD):规避 IPv6 环境下地址探测带来的延迟与冲突。

0.5.3 – 0.5.6(2015-12 ~ 2016-01):稳定化与针对性修复

进入 2016 年,版本节奏转为"小步快跑 + 精准修复":

0.5.3(2016-01-12)

  • bridge 驱动支持internal网络选项:将 0.5.2 的后端支持开放为 driver 可见的配置项;
  • 后端实现force选项以支持强制断开网络(network disconnect --force);
  • 修复 etchosts 包中的一处正则问题(docker/docker#19080)。

0.5.4(2016-01-12)

  • 用户强制删除 endpoint 时移除 isNodeAlive 保护:当用户显式强制删除端点时不再因节点活性检查而阻塞,保证强删语义。

0.5.5(2016-01-14)

  • 允许网络级别名解析到匿名 endpoint:此前别名解析要求端点具备名称,现在匿名端点同样可被网络级别名命中;
  • 自我修复损坏的 IP 数据库:针对 1.9.0/1.9.1 中可能出现的 IP 分配记录损坏,libnetwork 在启动时自动修复(依赖 0.5.0 引入的 boltdb 持久化与 0.5.1 的 IPAM 分配校验);
  • 设置--iptables=false时跳过 IPTables 清理(修复 docker/docker#19063):避免在用户显式禁用 iptables 的场景下仍执行规则清理导致异常。

0.5.6(2016-01-14)

  • 容器重启时正确重建嵌入式 DNS 服务器(修复 docker/docker#19354):这是嵌入式 DNS 生命周期管理的补齐——重启后的容器同样获得可用的内嵌 DNS 服务。

版本时间线速览

版本日期核心主题
0.3.02015-05-27引入 CNM,以 CNM+Bridge 替换 Docker 原有网络
0.4.02015-07-24实验性 Overlay、网络插件、/etc/hosts 服务发现;集成 libkv
0.5.02015-10-30多主机网络转正;IPAM 与 IPAM 驱动;boltdb 持久化
0.5.12015-12-07允许用户为容器指定 IP
0.5.22016-01-08嵌入式 DNS 取代 /etc/hosts;别名;内部网络后端;IPAM 驱动选项
0.5.32016-01-12bridgeinternal选项;强制断开网络
0.5.42016-01-12强删 endpoint 时移除 isNodeAlive 保护
0.5.52016-01-14匿名端点别名解析;IP 数据库自修复;--iptables=false 跳过清理
0.5.62016-01-14容器重启时正确重建嵌入式 DNS

本仓库中的实际落地:RancherOS 锁定 v0.5.6 并消费 resolvconf 子包

CHANGELOG 所记录的演进并非孤立历史——本仓库(RancherOS)正是 libnetwork v0.5.6 的实际使用者,证据链完整:

1. 版本锁定。trash.conf 第 14 行记录github.com/docker/libnetwork v0.5.6,即本仓库 vendor 目录恰好停留在 CHANGELOG 的最终版本上。

2. resolvconf 子包的引入。虽然本仓库没有 vendor libnetwork 的主库(netlink、sandbox 等),但单独消费了其resolvconf子包:cmd/network/network.go 第 19 行"github.com/docker/libnetwork/resolvconf"导入了该包,并在第 85、93 行调用resolvconf.Build("/etc/resolv.conf", ...)直接生成系统 DNS 配置文件。这正是 0.5.2"嵌入式 DNS 取代 /etc/hosts"之外,libnetwork 在 DNS 领域留下的另一条可复用能力——读写 resolv.conf 的工具集。

3. resolvconf 包的实现细节。resolvconf/resolvconf.go 完整保留了该子包的设计:

  • Build(path, dns, dnsSearch, dnsOptions):按search/nameserver/options顺序生成标准 resolv.conf 内容并原子写盘;
  • Get()/GetSpecific()/GetIfChanged()/GetLastModified():读取当前或指定路径的 resolv.conf,并以 SHA-256 哈希跟踪变化(GetIfChanged供容器的 resolv.conf 更新器使用);
  • FilterResolvDNS():清理 localhost(127.*/::1)nameserver,IPv6 未启用时剔除 IPv6 nameserver,若清理后无可用 nameserver 则回填默认外部 DNS(IPv4 默认8.8.8.8/8.8.4.4,IPv6 默认2001:4860:4860::8888/2001:4860:4860::8844,即 Google Public DNS);
  • 配套解析函数GetNameservers/GetNameserversAsCIDR/GetSearchDomains/GetOptions使用精心构造的 IPv4/IPv6 正则解析条目。

4. 在 RancherOS 网络配置中的真实调用。cmd/network/network.go 的ApplyNetworkConfig展示了 resolvconf 与云配置的协作逻辑:用户未显式设置 DNS 且 DHCP 未下发 DNS 时,以cfg.Rancher.Defaults.Network.DNS.Nameservers兜底调用resolvconf.Build写入/etc/resolv.conf("Writing default resolv.conf - no user setting, and no DHCP setting"分支);用户显式设置了rancher.network.dns时则以用户值为准。对应的默认值定义在 os-config.tpl.yml 第 17-20 行:network.dhcp_timeout: 10、dns.nameservers: [8.8.8.8, 8.8.4.4]——与 resolvconf 包内置的 IPv4 默认解析器完全一致。

小结:一条从 CNM 到嵌入式 DNS 的完整演进线

透过 CHANGELOG 可以看到 libnetwork 的清晰演进脉络:0.3.0 用 CNM 统一编程模型 → 0.4.0 以实验特性铺路(Overlay、插件、libkv)→ 0.5.0 完成多主机组网转正并沉淀 IPAM 与持久化 → 0.5.2 以嵌入式 DNS 完成服务发现架构换代 → 0.5.3~0.5.6 集中补齐内部网络、强制断开、自修复与重启生命周期。而本仓库以 v0.5.6 为锚点、以 resolvconf 子包为接口,恰好为这份历史提供了"生产环境消费者"的实证注脚。

  • 操作系统
  • 云原生
  • 容器运行时

【免费下载链接】os

Tiny Linux distro that runs the entire OS as Docker containers

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

相关推荐

上一篇:PaddleHub PPLCNet_x0_75 图像分类模型实战:安装、API 预测与 Serving 部署指南
下一篇:如何用PhotoView解决Android图片浏览的三大痛点

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

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

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

立即咨询