LWN:针对命名空间的文件系统!
共 2871字,需浏览 6分钟
·
2021-12-22 20:39
关注了就能看到更多这么棒的文章哦~
A filesystem for namespaces
By Jonathan Corbet
December 3, 2021
DeepL assisted translation
https://lwn.net/Articles/877308/
在观察内核开发过程时,很自然地会关注到最终被接受并成为未来内核一部分的那些 patch。但是,其他那些没有被接受的工作也是很有用处的。这些 patch 的失败往往揭示了内核、以及内核社区的一些特性。Yordan Karadzhov 最近发布的概念验证性的 namespacefs 这组 patch 就是这种情况了。在未来的内核中应该不会看到 namespacefs 了,但是,这项工作明明是针对一个有效的使用场景的,它为什么没能在内核中解决这个场景的问题呢?
Namespacefs 很明显是一个由内核来实现的虚拟文件系统,用来展示系统中运行的各个 namespace 的层次结构。这些信息反映了正在运行的容器(container)的层次结构。管理员通过 namespacefs 可以更容易地看到他们的系统中正在发生哪些事情。它也可以在今后用在一些复杂的用例中,比如跟踪多个容器并观察它们是如何交互的。
最初实现的版本只限于 PID 和 time 这两个命名空间。人们就可以遍历 PID 命名空间的层次结构(time 命名空间是没有层次的),取得每个命名空间中运行的进程列表。其他类型的命名空间在这组 patch 中尚未支持,但如果 namespacefs 得到大家的赞同可以作为解决这个问题的正确方案的话,今后肯定会在未来的版本中增加相应的支持。
正如 Karadzhov 所说:
能够看到命名空间的结构,在容器化的 workload 场景下可以是非常有用的。这将为检测(detecting)、检查(examining)和监控(monitoring)系统上运行的各种容器提供一个通用的方法,而不需要依靠某种特定的用户空间软件了。
其中大部分信息现在都可以在用户空间中从 /proc 下的各个目录来获取,但还有一些缺失的部分,而且这些信息的组织方式没有根据实际的命名空间层次来展示。当然,容器的编排工具也可以展示它们所管理的这些容器,但它们并没有一个统一的解决方案。命名空间的目的是希望使这些信息能够随时可用,无论使用的是哪种容器编排系统。
人们对这项工作提出了一些反对意见,首先是命名空间在 namespacefs 中的条目需要有一个 name。目前还没有跟命名空间相关的 name,所以 namespacefs 使用的是在内核内每个命名空间的 inode 编号。Eric Biederman 很快就批评了这种做法,他说。"使用 inode 编号作为命名空间的实际名称是个错误做法"。他接着说道,确实也没有什么其他东西可以作为命名空间的名称,这里的整个方案其实是不可行的。
看来,使用 inode 号作为命名空间的名称有几个问题。其中一个问题,Biederman 后来详细解释了一下,就是无法在今后用相同的名字来重新创建出命名空间的层次结构。他说,这会导致很多问题,比如实时迁移(live-migration scheme)中使用了 CRIU 来抓取快照(checkpoint)和重启容器的方案就会出问题。他说,正确处理这个问题的唯一方法就是为命名空间的名称来创建一个命名空间,而这在过去的讨论中已被证明是一个很困难的问题。
只有在使用了 checkpoint 的容器中也在使用 namespacefs 的情况下,CRIU 的问题才会出现。正如 Karadzhov 和 Steve Rostedt 所指出的,这是一个不可能的组合情况。使用 namespacefs 的意义在于能用它来展示某个特定机器上的情况。任何人都没有理由会需要在不同的机器之间移动 namespacefs,也不会需要移动那些使用了 namespacefs 的容器,甚至都不会去想要对它做 checkpoint。当然,不应该假设未来没有人想以某种方式使用我们的功能,但是,除非有什么非常出乎意料的使用案例,那么其实这里的起名问题在实际使用中可能并不需要担心。
不过,还有一个更深层次的问题,那就是命名空间可以被看作是在内核中识别容器的一种尝试方案,但是内核天生设计上就是没有 "container" 的概念的。相反,内核是提供了若干个子功能,供用户空间的容器系统来使用来组装成不同类型的 container。namespacefs 这组 patch 使用了 PID 命名空间作为建立层次结构的对象,完全忽略了 user 命名空间。Biederman 在他最初的回复中就批评了这个决定,他说 "没有 user 名字空间的话,肯定没有一个有意义的层次结构"。不过,并不是所有的容器都使用了 user 命名空间,而且这些命名空间中也缺乏 Karadzhov 的 patch 中希望使用的 PID 信息。
但是,正如 James Bottomley 所指出的,也不是所有的容器都使用了 PID 命名空间的。试图在 namespacefs 中来识别那些没有 PID 命名空间的容器的话就什么信息都看不到了。
最终的结果看来是除非引入某种容器的概念,否则很难在内核中实现类似命名空间的东西。比起过去几年,现在更少有人愿意这样做了,内核中缺乏容器抽象概念这一点,人们认为其反而引出了用户空间方面的大量创新。仅仅因为这个原因,就很难在内核社区推销命名空间这个做法了。
不过,似乎也可以通过分析许多 /proc 文件从而完全在用户空间来获得所需的信息。如果有缺失的信息的话,可以继续在 /proc 中添加进去,而不是引入一个全新的文件系统。因此 Karadzhov 打算后续采用这个方法来解决问题。他正在准备另一个概念验证性的改动希望给大家展示这个方案。
如果这个实现后续被证明是很困难的、或无法有效地做到的,那么可能就有理由要重新考虑命名空间方案了。除非走到了这一天,否则像 namespacefs 这样的机制似乎不太可能进入内核。这个具体方案虽然没有能够直接实现目标,但是它确实引出了一个讨论,提炼出了一个看起来更加好的解决方案。并且在这个过程中,也突出了内核缺乏容器概念所带来的一些限制。“尽量不去实现(reluctance to implement)”的这种做法通常是个好的做法好事,但它最终会使用户碰到一些更难解决的问题。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~