- 操作系统
- 云原生
- 容器运行时
【免费下载链接】os
Tiny Linux distro that runs the entire OS as Docker containers
本文以仓库内 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.0 | 2015-05-27 | 引入 CNM,以 CNM+Bridge 替换 Docker 原有网络 |
| 0.4.0 | 2015-07-24 | 实验性 Overlay、网络插件、/etc/hosts 服务发现;集成 libkv |
| 0.5.0 | 2015-10-30 | 多主机网络转正;IPAM 与 IPAM 驱动;boltdb 持久化 |
| 0.5.1 | 2015-12-07 | 允许用户为容器指定 IP |
| 0.5.2 | 2016-01-08 | 嵌入式 DNS 取代 /etc/hosts;别名;内部网络后端;IPAM 驱动选项 |
| 0.5.3 | 2016-01-12 | bridgeinternal选项;强制断开网络 |
| 0.5.4 | 2016-01-12 | 强删 endpoint 时移除 isNodeAlive 保护 |
| 0.5.5 | 2016-01-14 | 匿名端点别名解析;IP 数据库自修复;--iptables=false 跳过清理 |
| 0.5.6 | 2016-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
相关推荐
libnetwork 深入解读:用 Go 构建容器网络模型(CNM)的驱动化网络库
libnetwork 深入解读:用 Go 构建容器网络模型(CNM)的驱动化网络库 导读 libnetwork 是 Docker 生态中负责容器网络连接的原生
操作系统云原生容器运行时Moby libnetwork 容器网络模型(CNM)设计解析:Sandbox、Endpoint、Network 与 Driver 扩展机制
Moby libnetwork 容器网络模型(CNM)设计解析:Sandbox、Endpoint、Network 与 Driver 扩展机制 本文以 Moby
云原生容器运行时虚拟化容器编排RancherOS 内嵌 libnetwork 路线图全解:容器网络模型、驱动架构与 dnet 工具链
RancherOS 内嵌 libnetwork 路线图全解:容器网络模型、驱动架构与 dnet 工具链 本篇文章围绕当前仓库 vendor/github.com
操作系统云原生容器运行时
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考