关注了就能看到更多这么棒的文章哦~
iproute2 and libbpf: vendoring on the small scale
By Jonathan Corbet
November 12, 2020
DeepL assisted translation
https://lwn.net/Articles/836911/
LWN 最近关于 Debian 中的 Kubernetes 的文章中(https://lwn.net/Articles/835599/),介绍了要把一个有数百个依赖包的大型项目打包发布,是一件多么有挑战的事情。然而,其中出现的许多问题并不局限于这类大规模的项目。本文讨论的问题,就是是否在发布网络工具 iproute2 工具集的同时,是否应该附带 libbpf library 的一份副本。可以看出,这些快速发展的项目,似乎仍然觉得受到了 Linux 分发方式的限制。
iproute2, 是一个几乎在任何 Linux 系统上都能找到的网络配置工具集合。它包括 arpd、ip(老前辈们在输入 ifconfig 时其实应该要用 ip 命令了)、ss 和 tc 等实用工具。特别是最后一个命令,是用来配置流量控制子系统(traffic-control subsystem)的,供系统管理员来管理、优先处理流经其系统的网络数据。流量控制这个子系统,在几年前就已经具备了加载和运行 BPF program 的能力,用 BPF,既可以对数据包进行分类,也可以决策应该放到哪个队列里。这种机制使管理员在管理网络流量方面拥有很大的灵活性。
不过,在 iproute2 中处理 BPF program 的代码已经很老了,而且缺乏对过去几年中添加到 BPF 中的许多新功能的支持。自从这里这段老代码被写出来后,BPF 社区又开发出了 libbpf(合入了 kernel source tree),这是处理 BPF program 并将它们加载到内核中的首选方法。这个工作可不是一个小任务,libbpf 必须对 BPF program 可执行程序中写在一个特殊 ELF p 的指令代码进行解释执行,并在需要时调用功能繁杂的 bpf() 系统调用。这部分工作还包括创建 BPF maps,"relocating " structure offset 从而匹配当前运行的 kernel 里真实的偏移量,还有包括加载 program,并将其挂载到内核中适当的钩子上。Libbpf 和其他的 BPF 生态系统一起经历了迅速地成长。
要在 iproute2 中添加对最新的 BPF 特性的支持的话,显然,最直接的方法是抛弃它使用的旧代码,转而使用 libbpf;从 10 月底开始,Hangbin Liu 已经提出了这方面的 patch。此后不久,iproute2 的维护者之一 David Ahern 指出,发布的补丁无法在 Ubuntu 20.10 系统上成功编译,刘航斌的回应是:Ahern 需要更新到较新版本的 libbpf。libbpf 开发者 Andrii Nakryiko 建议将 libbpf 作为 iproute2 的一个子模块(submodule)。麻烦就开始了:Ahern 认为 libbpf 是由 Linux 发行版提供的,iproute2 需要和现有的版本能配合一起工作。Nakryiko 则认为,libbpf 是 "现在正在经历快速变化的函数库",将其与 iproute2 打包在一起是 "更加实际的做法"。不用说,这种观点并没有得到广泛认同。当我们发布新版本的 libbpf 时,它会经过严格的测试。bpftool 也会有很多测试覆盖率。iproute2 与共享的 libbpf 将一无所获。这就像随机掷骰子一样。新的 libbpf 可能会破坏 iproute2,也可能不会。这真是可怕的用户体验。之前已经有很多次提出反对意见,不支持像这样来发布函数库(类似这次的 libbpf),这次 libbpf 也碰到了同样的问题。Jesper Dangaard Brouer 重复了人们通常使用的安全这个角度的论点:藏在其他软件包中的 library 文件副本很难被人们注意到,如果出现了问题也很难更新。Jiri Benc 补充说,这个过程的最终结果将是导致大量的依赖库被捆绑发布,这 "对发行版和用户来说都是噩梦"。发行版长期以来一直反对以这种方式捆绑依赖关系,而 iproute2 开发者认为没有任何理由在 libbpf 上违背这一政策。
BPF 的开发者们却有不同的看法,毫不羞涩地把自己的观点大声说了出来。Alexei Starovoitov 称 Ahern "对技术争论充耳不闻",并提出了把 iproute2 拉个 branch 出来管理的想法作为回应。后来他说,使用发行版提供的 libbpf 会比完全不用 libbpf 更糟糕,如果他能从 iproute2 中删除现有的 bpf 支持,他会很愿意这么做。事情到了 Toke Høiland-Jørgensen 要求他 "停止这种类似'不走我的路就去走高速公路'的敲诈行径",否则讨论就无法取得任何进展。
将 libbpf 与 iproute2 捆绑在一起的争论,似乎主要来源于人们对发行版提供商发布的 libbpf 的不信任。这里其实有两个方面,一个是 iproute2 可能最终会链接执行一个带有 bug 的 libbpf 版本,正如 Starovoitov 所说:
当我们发布新版本的 libbpf 时,它会经过严格的测试。bpftool 也会有很多测试覆盖。iproute2 使用公共的 libbpf 并没有什么好处。这就像随机掷骰子一样。新的 libbpf 可能会破坏 iproute2,也可能不会。这真是可怕的用户体验。
Benc 不同意这个观点:
只有在 libbpf 在保持向后兼容性方面做得非常糟糕的情况下才能算是“随机掷筛子”。根据我的经验来看,libbpf 向后兼容性方面做得很不错。
在讨论的另一封邮件中,Starovoitov 赞扬了 libbpf 版本的兼容性,说 "用户可以随时升级和降级 libbpf 版本"。其他人也认为,libbpf 版本管理得很好,不会产生兼容性问题。所以,其实并不清楚这里有什么好担忧的。
不过这里还是有个相关的问题,也就是担心使用发行版提供的 libbpf 会导致各系统之间的缺乏一致性,用户无法通过查看他们正在运行的 iproute2 版本就知道它支持哪些功能。除此之外,bpf 开发者还担心发行版提供商会坚持使用旧的 libbpf,使用户即使拥有最新版本的 iproute2 也无法使用最新的功能。Nakryiko 表示,用户确实希望得到 libbpf 支持的新功能,但 bpf 维护者 Daniel Borkman 一再声称,发行商不可能跟上 libbpf 的发布。有人认为,这将导致 iproute2 用户体验不佳。将一个特定版本的 libbpf 与每个 iproute2 版本绑定,反而会让使用体验更加一致。
不过 Ahern 并不完全相信这种说法:
用户体验一直被提及,但我也一直读到这样的观点:BPF 的用户不能期望有一致的体验,除非他们一直追着使用与 BPF 相关的所有软件的最新最好版本。这对用户来说不现实。发行版的存在是有其价值的,它们解决了打包问题让其变得可行。
这引出了一些其他开发者,他们抱怨需要保持多个依赖软件都要在最新的版本才能正常工作起来。例如,Edward Cree 就抱怨这个互操作性问题一直缺乏重视:
bpf 的开发者似乎认为既然他们控制了 clang, libbpf 和 kernel, 他们就可以在这三个软件中随意修改,而根本不管那些能让其他工具可以互相配合操作的规范。
Starovoitov 实际上也同意这种情况总有一天需要改善。"BPF 生态系统最终会形成固定的文件格式、linker 规范和 1000 页 psABI 文档。" 不过,他补充说,现在事情发展得太快了。
最后,Nakryiko 建议说,如果发行商们注意更新 libbpf,并将 iproute2 的依赖关系设置为需要进行更新的版本,那么就可以解决大多数问题了。Benc 回答说,至少 Red Hat 现在是这样做的,因此 Nakryiko 回答说,这 "实际上已经足够了"。Starovoitov 仍然认为 iproute2 需要在每个发布版本中列明所依赖的 libbpf 最少需要哪个版本 ,随着新版本的发布而持续更新,这样 iproute2 和 libbpf 版本之间至少会有一些关联。Stephen Hemminger,也是 iproute2 的维护者,则不愿意强加这样的要求。
最后,似乎 iproute2 将会像所有其他 Linux 工具一样被打包,将会使用发行版所提供的 libbpf 版本,而不是提供自己的版本。发行商只需要确保 libbpf 与其他内核衍生的工具保持一致,这是他们早就知道了的。
不过,围绕着快速发展的 bpf 子系统的紧张关系似乎不太可能消失。有一群用户已经在依赖基于 bpf 的工具,而开发者则继续匆忙地发展整个生态系统。Ahern 这样描述这种情况。"相关的软件在发布 2-3 个月后就过时的趋势,可以看出 bpf 还不稳定、尚未准备好让发行版来开始使用和支持"。不过,这也应该是一个容易解决的问题,毕竟近 30 年来,Linux 作为一个整体,一直在支持用户,同时也在不断地进行修改。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~