EROFS:过去、现在和未来¶
标题:EROFS: Past, Present, and Future
日期:2024/04/27
作者:Xiang Gao & Tianyi Tang
链接:https://www.youtube.com/watch?v=CmXyPz4UcDE
注意:此为 AI 翻译生成 的中文转录稿,详细说明请参阅仓库中的 README 文件。
备注:手动修复了人名。
大家好。感谢大家来听我们的主题。我是来自阿里云的高翔。今天我将与我的同事汤天一一起详细讲解EROFS。我们之前可能在LSF和其他一些内核峰会上做过一些分享,但我想在开源峰会上也对EROFS做一个概括性的简述,抱歉,是详细的回顾。
首先,对于从未听说过EROFS的人,让我再次简要介绍一下EROFS文件系统。那么,什么是EROFS?EROFS代表增强型只读文件系统 (Enhanced Read Only File System)。它始于2017年下半年,自Linux内核4.4版本起正式可用。它的目标是一个现代化的、灵活的、高性能的、基于块的、内部不可变的文件系统,并且得到了高度的维护。它是基于块的,但又不完全是基于块设备的,因为我们有其他的访问方式,比如FS缓存。并且其上的数据是严格块对齐的,没有额外的数据移动和I/O放大。对于未压缩的数据,我们支持FS-DAX和直接I/O。虽然它很简单,但它不仅仅是一种格式。我们从内核开发者的角度,尽可能地利用了内核中的许多可能性。
因此,一个最小的核心用途具有以下特性,例如未编码的数据、内置的UUID和卷标、直接I/O、一些块重复、扩展属性、ACL以及内置的分层支持。因此,我们可以拥有最少的元数据和许多数据块。我们还有FS-DAX支持,可以在主机和客户机之间共享缓存内存。以下是将EROFS作为其解决方案一部分的应用程序。然后是四个压缩支持的特性。这个特性你可以根据需要开启或关闭。首先是我们有一些透明压缩,但我们可以基于每个inode来选择是否启用。所以你可以压缩一些文件,也可以让一些文件保持未压缩。我们有基于滚动哈希的压缩数据去重。我们有尾部压缩数据去重,例如,抱歉,像片段,这很像SquashFS。我们还支持尾部压缩数据内联。因此,数据文件最尾部的部分将内联在索引节点中。我们称之为“尾部打包”。一个典型的应用压缩EROFS的例子是众所周知的Android项目。
这里是我们的开源社区。目前我们有几位维护者和审阅者负责我们的内核代码库。如你所见,这是一个相当开放的项目,涉及许多厂商。EROFS已集成到多个生态系统中。大多数Linux发行版。最近我们有Sintos Stream 9和几个引导加载程序。但Grub仍在进行中,等等。这里是我们的文档网站。请注意,它仍然不完整。我们将逐步完成这个网站。因此,虽然它仍然是一个小的开源社区,但目前已有几家公司参与EROFS的开发,如阿里巴巴集团、百度、Coppel、谷歌、华为、OPPO等。
那么,我们为什么要引入EROFS?历史背景是Android有几个只读分区,它们的行为就像系统固件,这意味着Android代码只能通过更新的方式更改。但它们的固件变得越来越大。因此,在我们全新的Android设备上,尤其是在低端设备上,需要更多的空闲空间。所以我们想做压缩。但在动态运行时性能方面,尤其是在低内存场景下,伴随着持续的高内存压力,这一点非常重要。但之前所有的方案都不能很好地满足我们作为市场上具有竞争力产品所需的性能。更多细节,你可以参考在ATC 19上发表的论文。我们的目标是从内核文件系统开发者的角度,设计一个简单但有效的方法来覆盖各种不同的用例。
那么,为什么使用EROFS?两个主要原因是安全性和简单性。它减少了磁盘上元数据的复杂性。因此,与通用文件系统如EXT4相比,它具有更快的构建性能。它的整体文件系统尺寸也更小。并且更容易从多个子镜像或其他数据集中合并文件系统。我们有一些读写分离。它避免了不必要的基于代码的耦合。因此,它有更少的复杂错误和更小的攻击面。它更能防止数据篡改。如果你研究一些通用文件系统如EXT4,许多系统调用问题可能源于精心构造的恶意镜像,并且对于磁盘上格式的可变镜像用例来说,它们兼容性较差或存在冗余,这会增加代码解耦的难度。结合以上因素,额外的写路径以及通常的挑战再次影响了整体稳定性。我不是说EROFS没有错误。但对于镜像用例,如果有错误,EROFS可以更容易修复,因为它不那么复杂。在底部,这里是一个恶意EXT4文件系统的概念验证,它可以使内核崩溃。我去年测试过它。
另一个原因是灵活性。我们同时拥有内核文件系统驱动和用户空间实现。它同时支持块设备和基于文件的部署。我们有按配置文件压缩。文件可以被压缩或未压缩。并且我们可以为每个文件使用不同的算法。文件系统大小可以动态调整。你可以直接追加元数据或数据。这使得更新镜像容易得多。对于大多数特性,我们还可以根据需要在磁盘格式上启用这些特性。同样,由于磁盘格式相当简单,你可以根据需要安排磁盘布局,只要元数据能被正确解析即可。
最后一个我认为是性能。更多细节,我仍然强烈建议阅读底部的链接。这里只是总结。首先,我们有块对齐数据。没有额外的浪费。其次,我们有固定大小的块压缩。这将带来更好的压缩率以及高效的I/O利用率。我们有一些用于解压的缓存I/O策略。我们最小化内存占用。我们支持原地解压。这是为了避免另一个压缩缓冲区,并尽可能地将指针指向缓存行。我们还有去重。以避免对去重数据进行I/O,从而进一步最小化镜像大小。我列出的性能测试可能是一个月前的了。但稍后我可能会在网站上建立一个CI来精确刷新测试结果。这是一个测试设置。如你所见,这里我只与SquashFS进行了比较。因为人们可能需要了解EROFS性能的大致情况。对于EROFS,我们的元数据始终是未压缩的。所以我关闭了SquashFS的元数据压缩。这是镜像大小的主要差异所在。你可以看到,如果使用几乎相同的配置,EROFS几乎总是有更小的镜像尺寸。这是我们的顺序访问。我认为未压缩数据访问可能有些噪音。但这没关系。对于压缩用例,你可以看到EROFS的随机访问性能更好。这是小随机访问和全随机访问。你可以看到EROFS几乎总是比SquashFS表现更好。另一个工作负载是我们对一个单一的大文件进行了基准测试。我们使用了fio
的c-cellular
工作负载。如你所见,我们可以… 我先展示镜像大小。EROFS也比SquashFS小。这是fio
的结果。因为只有一个文件。所以我用fio
测试了顺序I/O。你可以看到EROFS的表现优于SquashFS。这是小随机I/O和全随机I/O。
让我再谈谈EROFS核心的磁盘格式。我们的磁盘格式相当简单。因为…抱歉。几乎所有的EROFS磁盘结构都是良好对齐的。并且它位于单个文件系统块内。为了性能,它永远不会跨越两个块。在左边是磁盘上的超级块格式。它包含整个文件系统的状态和根索引节点的NID。这很像根索引节点号。每个EROFS索引节点都在一个索引节点槽中对齐。这样基本的索引节点信息可以在同一个块中,并且一次读取完成。在右边是EROFS磁盘上的索引节点格式。短扩展属性可以直接存放在核心磁盘索引节点旁边。同样还有一些索引,如块索引和压缩索引。以及剩余的内联数据。你可以看到我们的索引节点大小非常小,比如32字节或44字节。这是EROFS磁盘上的目录格式。EROFS目录由几个目录块组成。这也是为了随机访问。每个块包含两部分:称为grant部分和名称部分。通过这样的整体设计,EROFS可以使用二分查找进行名称查找。这使得EROFS比内核中其他只读文件系统更有效。但如你所见,它相当简单。你总是可以编写一个简单的实现。
以下是我们最近的功能。但这还不完整。第一个是EROFS支持两种模式的去重。例如,对于未压缩的文件,我们有基于块的数据去重。你可以以4K为单位对数据进行去重。红色的是全局压缩数据去重。如果数据被压缩了,你可以用这种方式在你的文件内或跨文件进行去重。这里有一些细节。但那是最终结果。在左边,我使用了维基百科的两个快照。是前100页。但相隔20天。未压缩大小是1.8 GB。所以你可以看到,与未去重的和未压缩的相比,EROFS有更好的结果。左边是Linux内核的测试结果。源代码测试结果。我们的第一个用例是在节点间共享磁盘。我们的观察是,每个容器镜像启动时按需拉取基础层很慢。而大多数底层基础层是公开可用的。比如一个存储包等。次要安全版本之间的差异非常小。我们的想法是引入一个共享磁盘镜像来存储最常见的基底层,并使用EROFS的压缩或未压缩去重来最小化镜像和I/O。左边是原始的容器启动流程。右边,我们为公共底层使用了共享的、去重的共享云盘。只有上层需要被拉取。这一层可以结合其他方式拉取,比如分层拉取和其他技术。这里是一个在稍有不同的小版本之间进行去重的测试结果。如你所见,与压缩器甚至压缩的OCI相比,EROFS可以拥有更小的尺寸。这样你可以在更大的磁盘上容纳更多版本。另一个是EROFS支持原生分层。你可以并行转换OCI层来获取每个数据块,然后你可以使用最后的命令来生成或最小化元数据,并使用这些数据块来合并成EROFS。结合overlayFS,你可以获得rootFS。
我们的第二个用例是层粒度的FS-DAX内存访问。首先,你可以为容器镜像使用dax=devdax
或dax=mmap
来完全消除客户机页缓存。但问题是,使用传统文件系统的小型快照式FS-DAX只能方便地进行镜像级去重。如果你看这三个虚拟机,它们的内存无法在热状态下共享。由于一些小的镜像更新,快照式FS-DAX内存将会有数倍的额外内存开销。为了修复这个问题,维护另一个4K映射表用于快照式FS-DAX内存访问将成为负担。我们的解决方案源于我们的子镜像合并。对于EROFS,它支持其技术,每个PMEM区域可以由多个子镜像形成。这样每个内存区域可以在主机上共享。因此,它将有更好的整体内存,在主机上更小的内存占用。最后一个用例是Run-C的页缓存共享。左边的问题与上一个相同。快照式方法也有同样的问题。右边,即使是overlayFS本身也无法在不同层访问同一文件时共享页缓存。我们的解决方案是EROFS有一个内部补丁。目前它有一个内部补丁来支持我们的页缓存共享,因为不太干净。在同一个节点上,对于每个唯一的文件,它只会有一份相同的页缓存。
最后,我想补充一些东西,比如加速器,因为新的Intel机器有一些IA加速器。它提供了非常高的压缩和解压缩吞吐量。但它利用了…它使用的算法是deflate。但它的滑动窗口要小得多,比如4KB。EROFS可以使用这项技术来卸载后台数据访问。目前,我用他们的用户空间库做了一些性能测试。但仍有一些问题需要解决,因为QAT驱动还没有集成到大多数发行版中。我们内核内的解压缩支持仍在进行中。这是与软件方法相比的测试结果。如你所见,IA和deflate加速器的性能非常接近更快的算法,如LZ4。但IA的镜像尺寸比LZ4小得多,应该说。这甚至非常接近这个标准。这是我们的测试命令。如你所见,我们可以从IA中获益。
接下来,我将把剩下的部分交给我的同事天一。
谢谢。谢谢。谢谢你的介绍。我的同事高翔已经介绍了EROFS的技术细节和一些功能、能力。我将介绍几个用例和端到端解决方案,在这些方案中我们必须充分利用EROFS的潜力和能力。
当我们谈论EROFS,这个只读文件系统时,很自然地会想到容器镜像。这是我们的第一个用例。在阿里云,我们针对这个用例的第一个解决方案是基于TAR的临时分片器。如我们所知,对于普通的OCI镜像,我们有TAR-GZ或TAR格式的它们。当拉取它们时,首先我们要从注册表获取整个数据块并存储到本地内容存储中。之后,我们会有一个自定义的、内置的应用器,即walking differ,用于解压文件,进行GUnzip和TAR操作。与其这样做,我们想将文件类型从EXT4改为EROFS。有几件事我们需要做。首先,我们需要改变解压内容的方式。为此,我们有一个远程differ来代替walking differ执行解包过程。所以,如你在此图中看到的,我们的输入原本是一个TAR-GZ流。在不修改containerd内部代码的情况下,我们有一个远程插件来处理解包过程。我们将执行mount.tar.erofs
,这是EROFS内核提供的一个助手。它的输出将是一个EROFS层格式的内容和一个循环设备,这有助于将流量重定向到该层。对每一层都这样做之后,我们将获得的第一个好处是,我们不再执行mounttar
操作了,这将大大减少我们首次启动镜像的时间。在我们拥有这一层之后,我们需要有能理解这一层的东西,即我们拥有的远程快照器,即TAR-FS快照器。这将利用EROFS层和循环设备来提供rootFS的合并视图,这是我们最终运行容器所需要的。在这里,由于我们现在还没有挂载助手,不仅仅是做一个简单的overlay挂载,我们将首先将这个overlay挂载的只读部分挂载到一个临时目录作为该层的只读部分,并最终为运行时执行overlay挂载。
这里,我将简要演示一下这个案例。好的,如我们所见,我在一台弹性计算机器上,这里有两个文件。它们只是一些非常简单的示例Pod和容器YAML。如你所见,只是一个WordPress镜像,这个Pod没什么特别的。我们将用kubectl
运行这个Pod。是的,需要一点时间。好的,现在它在启动了。这个过程正在进行中。有镜像在后台拉取,正如我们在containerd的日志中看到的。对于每一层,都有make-up.erofs
被调用来转换该层。在这个演示中,我们做了一点取巧的事情,因为就像overlay不必逐层解包一样,EROFS也不必,我们可以并行执行这个操作。所以我们对containerd做了一点修改,使这个解包过程并行化。这就是为什么我们可以看到多个make-up
进程在运行。在这个日志中,我们可以看到每一层都有一个循环设备。现在这个镜像解包好了,我们可以看到容器在运行。我们可以exec
进入这个容器,看到基础文件系统运行得很完美。是的,它在运行。如我们所见,我们最初在v2,所以我们可以看到pause进程。嗯,我不知道,好吧。是的,我们将查看挂载情况,因为它在运行,看看整个挂载发生在主机上。如我们所见,这个容器的rootfs只是一个overlay挂载,只有一个较低层是EROFS类型的挂载,它是只读的。它上面覆盖了另一个文件,你可以在上层做一些其他的扩展,因为我们保留了overlay结构。对于内容数据块,作为参考,我们会跟踪它。我们可以看到它仍然在内容存储中存储原始的数据块。所以如果你想将快照器切换回原始的overlay或devicemapper,或者其他任何东西,你仍然可以这样做,而无需重新拉取镜像。这就是这个解决方案的优势。而且,我不知道为什么我暂停了这么久。好的,是的。现在我们重定向到目录,看看实际解包的是什么类型的数据。如我们所见,对于每一层,只有一个loop文件。这个文件只存储设备名称。它只是一个普通文件。除此之外,我们有数据存储着该层的EROFS内容。对于最后一层,第25层是上层,它实际上是运行的。我们有一个临时目录,这个lower目录被挂载到EROFS。是的。是的。是的。我正重定向到这个目录,找到它们并展示这个。现在这正在发生。现在我们有两个上层,因为我们有一个用于沙箱的层。我跳过一点。是的。
现在我们将展示,我们刚刚停止了Pod,我们要更改containerd的配置。我们将把快照器切换回overlay,以展示不做任何修改,无需重新拉取镜像,在切换之后,我们只需重新运行相同的Pod。我们可以看到拉取过程应该非常快。我们将看到拉取过程会非常快,因为我们不需要从内容存储重新拉取整个内容。只是相同的目标被用另一种方式解包成overlay的效果。好的。就是这样。好的。我回到… 是的。
从这个解决方案来看,优缺点是显而易见的。第一个优点是:如果你不想做这个并行解包的事情,你不需要对containerd代码做任何取巧的修改。你只需部署你的远程快照器和远程differ就可以实现root FS的EROFS视图。这是第一个优点。第二个是,如果你想通过这种并行解包方式来加速启动时间,你可以这样做,因为EROFS不依赖于逐层解包。但缺点也很明显。第一个是,由于每一层都需要一个loop设备,将会创建多个设备。所以当你有多个镜像并行运行时,节点上会有大量的loop设备,在性能方面应该没问题,但在管理上仍然会很混乱。这是第一个缺点。第二个缺点是,这个解决方案不支持延迟加载,这是目前比较流行的做法。对于这两个缺点,我们通过引入Orpile ABD来提供解决方案。Orpile ABD也是一个解决方案。它是实现延迟加载的解决方案之一,但我们将用它来解决我提到的这两个缺点。简单介绍一下。Orpile ABD是一个用户空间服务。它是一个运行的后台守护进程,它将利用内核提供的TCMU模型。它会提供一个虚拟设备,用户的I/O请求发送到这个设备将被重定向回后台运行的Orpile ABD服务。它可以做任何你想做的事情。Orpile ABD要做的是,利用这个能力,提供延迟加载功能。它不会一次性从注册表获取所有数据或所有数据块。相反,它会在I/O请求到来时延迟加载对应的数据块。将Orpile ABD集成到我们刚刚介绍的解决方案中后,我们可以解决第一个问题。因为现在对于每个镜像,我们不需要每一层一个设备,而是可以为每个容器或每个镜像只使用一个设备。我们可以看一下这个解决方案的简短演示。
好的,现在我正在弹性计算机器上。抱歉。好的。现在我正在弹性计算机器上,准备运行两个简单的容器和Pod YAML。所以,我们准备运行两个简单的容器和Pod YAML。然后我们将使用同一种弹性计算机器。它只是一个WordPress镜像,就像我们刚才那样。这个镜像没什么特别的。在这个设置中,不同于我们之前的橙色方案,我们将有一个服务在后台运行。如你在这里所见,我们有服务正在运行。在这个设置中,我们将有一个自定义的overlay快照器,并在后台进行重定向。当我们解包这个镜像时,不同于… 我将回到这个。抱歉,稍等。所以,不同于传统的解包,我们将在本地生成元数据。所以,在我们已经从注册表获取了所有必要的blob之后,我们将把它们转换为我们想在本地运行EROFS所需的格式。是的。我将展示将要发生的事情。所以,我们有一个服务在这里运行。我们只需要运行这个容器。哦,是的。我将向你展示containerd的配置。如你所见,我们拥有的快照器只是overlayFS,这是内置的overlayFS快照器。所以我们将运行这个。从日志中我们可以看到,是的,启动了。如我们所见,容器已经正确启动。我们可以看到我们拥有这个。我们可以exec
进入这个容器。我们可以看到root文件系统的挂载。只是overlay。我们可以touch
文件。rm
文件。好的。回到主机,我们可以检查这个容器的挂载结构。就像我们刚才那样,对于TAR-FS快照器,我们将拥有一个单层overlay挂载。对于较低目录,它将被格式化为EROFS。但不同的是,现在不再为每一层使用一个设备,我们只为整个容器使用一个设备。现在我们有2个是因为我们有一个Pod。是的。所以,像这样,这个sdb
是为容器提供较低视图。这个sdb
是为沙箱提供视图。好的。但是,这里仍然有一个问题,因为它不提供延迟加载。由于OverlayBD原生具有延迟加载功能,我们希望将其包含进来。
所以,在执行我刚才提到的生成过程之后,如果这个过程发生在我们运行容器之前,我们先生成我们想要的东西并存储在注册表中。然后当我们运行容器时,我们将使用这些东西在本地提供一个视图。我们就可以拥有延迟加载功能。
但是,这会导致一个问题,因为这是许多延迟加载解决方案的一个痛点,就是你需要为你的延迟加载镜像使用一个单独的标签。比如,当你实际运行容器时,你必须有某个东西引用这个延迟加载清单。为了解决这个问题,我们使用了一个利用引用者API的解决方案,以最小化这个问题。这样当我们在生产环境中部署时,用户不必知道,嗯,它发生了吗?用户不必知道延迟加载正在发生。用户根本不需要知道任何事。用户只需要推送镜像。当他们在我们可以控制的集群中运行镜像时,它是延迟加载的。他们可以在不知道它发生的情况下利用这个功能。我们实现它的方式有点取巧。但是,我认为这与社区将要发展的正确趋势是一致的。
现在,在本地,我们只需要稍微改变一下配置。所以我们硬编码了一些构件,当从注册表获取内容时去寻找它们。如果我们在注册表中看到一个特定的构件,我们就认为它是原始清单的替代品。而这个清单将指向我们想要的延迟加载内容。现在,不做任何进一步的修改,我只更改了这个配置。我将停止Pod并移除我们在这个节点上运行的所有镜像。现在都是干净的。没有快照在后台运行。我们将再次运行相同的命令,不更改镜像的标签。抱歉。哦,是的,你说得对。是的,你说得对。好观点。我们确实有一个动态循环。我不想,嗯,太取巧。我再清理一次并重启。我打开了调试,所以日志在刷屏。是的,所以它现在启动了。看起来比我们刚才快得多。对于镜像,我们可以看到镜像大小减少到大约12 MB,这只是我们刚才的元数据。现在我们从这个向量拉取的blob只是来自延迟加载内容的元数据。我们可以访问容器内部,看到一切正常工作。这正在工作。我们可以touch
文件。对于我们在容器中看到的挂载结构,它将完全与我们刚才在本地转换时看到的一样。它将是一个单层overlay挂载,并且有一个临时目录挂载到EROFS,以提供该镜像的只读视图。所以,你可以在这里看到,我们有两个设备,一个用于沙箱,一个用于容器。并且它是只读挂载的。是的。好的。这就是我们的演示。好的。是的,这是我们为容器镜像部分准备的两种解决方案。
除此之外,我想稍微提一下我们如何实现你刚才看到的那个奇怪的事情。因为,我们为之前演示使用的快照器是overlay快照器。所以我们有一个新的RO驱动接口。我们在overlay快照器中包含了一个独立的RO驱动接口。我们将拥有这个overlay PD RO驱动,提供我们刚才看到的临时目录的overlay视图。但是,这个接口仍然需要一些工作。但那是我们拥有的原型。我们试图传达的概念是,你不需要一个单独的快照器。你不必做overlay的这个只读部分。因为最终你为容器看到的仍然是overlay挂载。这是我们将要遵循的正确趋势。好的。好的。关于容器镜像部分就这些。我们将深入一点,嗯,跳过运行时层面。深入到文件系统。所以,像ComposeFS也把EROFS作为其架构的核心构建结构。使用EROFS的主要好处是,当你运行多个使用ComposeFS的镜像时,即使它们有不同的EROFS元数据,当它们访问相同的文件时,你仍然可以重用相同的页缓存副本,因为它们共享相同的数据。这是它们将获得的主要好处。如果我们再深入一点或者换个角度,我们转到虚拟化部分。gVisor也将EROFS作为其核心功能包含在内,以在其虚拟机中提供容器镜像的视图。因为,像以前,当它们试图在虚拟机中访问容器镜像的文件系统时,它们必须有一个单独的进程,这里的Ransi-Goffer,它是基于RPC架构的。这很慢,并且在你首次启动容器时,在代码启动时间方面会非常糟糕。在切换到EROFS之后,你不需要这个单独的进程。你只需要使用虚拟内存,在我们需要在同一节点上同时启动大量容器的用例中,这将更快、更安全、更容易。最后,对于其他解决方案,如延迟加载,Nydus也把EROFS作为提供原始部分的构建解决方案。
好的,关于应用就讲这么多。我们来看看EROFS的路线图。首先,在未来,我们将为压缩数据完全启用大页支持。将构建初步的标准解压缩器和压缩器支持。上游Intel加速器支持将是我们正在努力的方向。上游的runc页缓存共享支持,我们也在努力中。关于在runc中进行内核适配的初步工作,有一组学生正在研究它。所以我们仍在思考如何推进这个特性。
好的,关于… 这就是我们今天要分享的全部内容。感谢大家的时间,有问题吗?
是的。谢谢。
提问者1: 当启用延迟加载时,如何管理数据完整性?我的意思是,当将单个文件延迟加载到节点时,运行时如何根据镜像清单的摘要检查内容确实是预期的内容?你知道,特别是,当前非延迟镜像已经使用摘要完全检查过所有内容。在使用EROFS的延迟加载中是如何完成的?
汤天一: 是的,我明白你的意思。我认为这是一个非常好的问题。我也有一个给你。你说,当你使用延迟加载时,如何检查你试图运行的内容是正确的数据。那么,当你不使用延迟加载时,你如何检查你运行的是正确的数据?因为,嗯,你检查数据的唯一时间是在解包数据的时候。解包数据之后,你就不再检查了。所以,在你部署一个镜像之后,它已经被解包了。然后你手动更改这个快照中的文件。然后你运行这个容器,它将被篡改。所以,这就是主要原因,为什么在当前的快照架构中,我们没有对容器镜像的这种完整性检查。因此,我们在这方面有很多功课要做。所以我认为这个问题将在未来得到解决,对吧?
高翔: 我可能需要补充一句。我认为数据完整性可能是一个次要问题,因为我们已经有一些技术,比如DM-Verity。或者在未来,也许EROFS会有自己的内置默克尔树。但这仍在进行中。另外,如果你不考虑延迟拉取,比如TAR-FS快照器,你可以拉取blob,转换成EROFS blob,然后你可以开启FS验证。或者使其成为不可变文件。所以我认为这是相对于overlayFS的一个优势。优势之一。另外,我想再说一点。因为一个blob对应一个loop设备。也许,这不准确。因为目前,对于每个loop设备,它只能附加一个文件。这是内核的限制。但这不是EROFS的限制。如果你考虑XFS或BtrFS或其他支持reflink的FS,你可以通过reflink合并这些文件。并使用一个大的合并文件附加到一个loop设备。这样你在这个文件系统上只有一个设备。但是,嗯,它不支持reflink。所以这是一个限制。但我认为这是loop设备的限制。所以我不确定内核社区是否会接受附加多个文件打开。但这是需求。所以,是的。那不是一个。所以,每个文件内容的摘要是如何链接到清单摘要中的?比如清单是否包含清单中所有文件内容的摘要?或者它们是通过一些其他文件元数据blob之类的东西链接的?
汤天一: 是的。镜像的布局架构仍然,嗯,和以前的OCI镜像完全一样。你仍然会为每一层拥有一个摘要。并且每一层的摘要都记录在清单中。所以当你在拉取镜像时,你仍然会使用清单和层中记录的摘要来检查完整性。哦,谢谢。是的。是的。
谢谢。
提问者2: 在你们的一张幻灯片上,有一个偏移量,在开始处,用于引导加载程序。还有tar。我认为那是超级块的格式。是的。是否可能,也许这更多是一个学术问题而不是它是否是个好主意。但是,你能取一个tar文件,然后将eroffs文件系统附加到这个tar文件的末尾吗?然后要么进行偏移挂载,要么在超级块中有某种指针,这样你就可以同时拥有一个tar文件和一个附加到一个巨大文件中的eroffs文件。你是指tar头在前面,然后你的数据有一个偏移量。
提问者2: 是的,就像,因为如果你把它给一个,嗯,一个简单的tar程序,它只会解包成tar,但如果你有…
高翔: 我不确定loop设备是否支持这个特性。但我想我们和SquashFS是一样的。对于SquashFS,我认为那可能是loop设备的功能。你可以查一下。你可以查一下带偏移量的loop。
提问者2: 是的,你完全可以对SquashFS这样做,你执行一个挂载,并给它一个挂载选项作为偏移量。
高翔: 是的,但我认为那不是SquashFS的特性,而是loop设备的。
提问者2: 太棒了。好的,酷。你可以挂载进去。我会试试看。是的。
高翔: 谢谢。还有更多问题吗?
提问者3: 是的。所以,Nydus有EROFS加上FUSE支持,而OverlayBD使用TCMU。那么,这些方法之间有什么优缺点?
汤天一: 嗯,是的,有优点也有缺点。首先,对于OverlayBD,它基于TCMU,这是当前的一个模块,整个I/O过程发生在… 我认为这不是技术问题。嗯,有点是。但是,嗯,仍然,当你的第一个文件服务器宕机时,你会陷入进程的这个阶段。但如果它是基于块设备,你有一个设备,嗯,你的进程似乎没问题。谢谢。但是,嗯,是的,有很多原因,因为…
提问者3: 还有Nydus也支持NBD,对吧?
高翔: 是的。NBD是用于… 是的。
汤天一: 是的。并且,最近,我们也有一个用户空间虚拟块设备驱动程序叫UBlock。我们也支持它。但是,但是,但是,那是,我的意思是,那只是用户空间的实现。所以那与EROFS无关。EROFS可以使用任何用户块驱动程序,如果你想实现的话。
主持人/提问者4: 有个问题。谢谢你们的演讲。嗯,我有个问题,考虑到嵌入式用例,你们有没有在内存和CPU使用方面做过基准测试?
提问者4: 嵌入式用例,你是指可用性场景?所以,在嵌入式设备上使用EROFS,比如在eMMC上。
高翔: 好的。是的。让,让,让我来回答这个问题。嗯,如果你考虑嵌入式设备,我们有一篇论文。我们有一篇论文详细描述了CPU消耗和内存。因为,嗯,最初的,你的用户场景是Android。所以,所以,所以我们的关键API是应用启动,比如在内存压力大的情况下启动相机。你可以查看那篇论文,会有详细的数据。所以,但,嗯,我想说的是,大多数Android设备,如三星、华为、嗯,其他,OPPO、vivo和其他厂商,嗯,目前都在使用EROFS。所以,就是这样。
汤天一: 关于Nydus问题再补充一点。嗯,所以像,对于延迟加载,现在有多个解决方案,比如Stargz、Nydus和OverlayBD。我认为,我认为主要概念是相似的。我们试图实现的主要目标是,嗯,减少容器启动时间。所以,我认为这种多样性对于推动这一进程绝对是件好事。
高翔: 哦,任何,嗯,我需要补充一句。除了块设备接口,我们还有FS缓存。但,嗯,OverlayBD不支持FS缓存。所以,所以我们只使用了块设备接口。嗯,但对于FS缓存,你可以查看更多细节,我们在本次主题中没有涉及。是的。
提问者5: 是的。我只是想问,你们在哪里发布?我看到你,你可以问,就像,你把你的功能放在那里,但你提到了所有东西。在哪里?你们发布在哪里?
汤天一: 发布?像,项目?在哪里?
提问者5: 哪个项目?像,你,你,你是指应用程序项目?应用程序项目还是EROFS?
汤天一: 应用程序项目。
提问者5: 应用程序项目。
汤天一: 对于TAR-FS快照器,我们在社区有一个正在进行的PR。对于第二个实现,嗯,像这个场景,它还没有,我们没有正在进行的PR,因为嗯,仍在跟踪这种新的OCI格式将如何发展,我们将相应地调整。但在这种新的OCI镜像格式,或者,或者像,一种更好的方式来跟踪这些层或索引的东西有了更可靠的结论之后,我们将为此提交一个可工作的PR。