文件系统共享(osxfs)
预计阅读时间: 14分钟osxfs
是新的共享文件系统解决方案,仅适用于Mac的Docker Desktop。 osxfs
提供了接近本机的用户体验,用于将安装的macOS文件系统树绑定到Docker容器中。为此, osxfs
具有许多独特的功能,并且与传统的Linux文件系统有所不同。
区分大小写
使用适用于Mac的Docker桌面,文件系统在容器中的运行方式与在macOS中的运行方式相同。如果macOS上的文件系统不区分大小写,则该行为将由从macOS到容器的任何绑定安装共享。
在macOS Sierra及更低版本上,默认文件系统为HFS + 。在macOS High Sierra上,默认文件系统为APFS 。两者默认情况下都不区分大小写,但在区分大小写和不区分大小写的变体中可用。
要获得区分大小写的行为,请将绑定安装中使用的卷格式化为区分大小写的HFS +或APFS。请参阅APFS常见问题解答 。
不建议重新格式化您的根分区,因为某些Mac软件依赖于大小写不敏感的功能。
访问控制
osxfs
以及Docker只能访问Docker Desktop for Mac用户有权访问的那些文件系统资源。 osxfs
不能以root
osxfs
运行。如果macOS用户是管理员,则osxfs
继承那些管理员特权。我们仍在评估在文件系统过程中应放弃哪些特权,以平衡安全性和易用性。 osxfs
执行任何其他权限检查,并且对通过它进行的访问不执行任何额外的访问控制。容器中的所有进程可以以与启动容器的Docker用户相同的方式访问相同的对象。
命名空间
使用-v
绑定安装语法,容器也可以使用用户可访问的许多macOS文件系统。以下命令从名为r-base
的映像运行容器,并在容器中以/Desktop
共享macOS用户的~/Desktop/
目录。
$ docker run -it -v ~/Desktop:/Desktop r-base bash
用户的~/Desktop/
目录现已在容器作为下一个目录可见/
。
root@2h30fa0c600e:/# ls
Desktop boot etc lib lib64 media opt root sbin sys usr
bin dev home lib32 libx32 mnt proc run srv tmp var
默认情况下,您可以直接在/Users/
, /Volumes/
, /private/
和/tmp
共享文件。要添加或删除导出到Docker的目录树,请使用Docker首选项中的File Sharing选项卡 -> 首选项 -> 文件共享 。(请参阅首选项 。)
-v
绑定装入中使用的所有其他路径均来自运行Docker容器的Moby Linux VM,因此-v /var/run/docker.sock:/var/run/docker.sock
参数应能正常工作。如果未共享macOS路径并且VM中不存在macOS路径,则尝试绑定安装失败,而不是在VM中创建它。 VM中已存在并包含文件的路径已由Docker保留,无法从macOS导出。
请参阅针对卷装载(共享文件系统)的性能调整,以了解Docker 17.04 CE Edge发行版中可用的新配置选项。
所有权
最初,任何请求对象所有权元数据的容器化过程都被告uid
和gid
拥有该对象。当任何容器化进程更改共享文件系统对象的所有权时(例如通过使用chown
命令),新的所有权信息将com.docker.owner
在对象的com.docker.owner
扩展属性中。后续对所有权元数据的请求将返回先前设置的值。基于所有权的权限仅在macOS文件系统级别上强制执行,所有访问进程的行为均与运行Docker的用户相同。如果用户无权读取对象的扩展属性(例如,该对象的权限为0000
),则osxfs
尝试添加访问控制列表(ACL)条目,以允许用户读取和写入扩展属性。如果此尝试失败,则对象似乎由访问它的进程所拥有,直到再次读取扩展属性为止。
文件系统事件
绑定安装支持大多数inotify
事件,并且还可能支持dnotify
和fanotify
(尽管它们尚未经过测试)。这意味着来自macOS的文件系统事件将发送到容器中,并在其中触发所有侦听进程。
以下是受支持的文件系统事件 :
- 创建
- 修改
- 属性变更
- 删除中
- 目录更改
以下是部分受支持的文件系统事件 :
- 移动事件在重命名的源上触发
IN_DELETE
,在重命名的目标上触发IN_MODIFY
以下是不受支持的文件系统事件 :
- 打开
- 访问
- 结束活动
- 卸载事件(请参阅安装 )
某些事件可能会多次发送。这些限制不适用于容器之间的事件,仅适用于源自macOS的那些事件。
坐骑
macOS装载结构在共享卷中不可见,但卷内容可见。卷内容与共享文件系统的其余部分显示在同一文件系统中。绑定绑定安装到容器中的macOS卷的安装/卸载可能会导致这些容器出现意外行为。不支持卸载事件。计划增加出口支持,但仍在开发中。
符号链接
符号链接是未经修改的共享。当符号链接包含依赖于默认macOS文件系统的默认不区分大小写的路径时,这可能会导致问题。
文件类型
支持符号链接,硬链接,套接字文件,命名管道,常规文件和目录。套接字文件和命名管道仅在容器之间以及在macOS进程之间传输-尚不支持在虚拟机管理程序之间进行传输。不支持字符和块设备文件。
扩展属性
尚不支持扩展属性。
技术
osxfs
不使用OSXFUSE。 osxfs
不在macOS用户空间进程与macOS内核之间,之内或之间运行。
性能问题,解决方案和路线图
请参阅针对卷装载(共享文件系统)的性能调整,以了解Docker 17.04 CE Edge发行版中可用的新配置选项。
关于已报告的性能问题( GitHub问题77:已装载卷中的文件访问非常慢 ),以及有关Docker Desktop for Mac论坛上的类似主题:主题:已装载卷中的文件访问非常慢 ,该主题提供了有关问题的说明,解决这些问题方面的最新进展,社区如何为我们提供帮助以及您未来的期望。该解释来自Docker开发团队的David Sheets(@dsheets)撰写的有关了解性能的帖子 ,该帖子针对上述论坛主题。我们希望在文档中对其进行更广泛的介绍。
了解表现
也许最重要的了解是共享文件系统的性能是多维的。这意味着,根据您的工作量,使用osxfs
(适用于Mac的Docker桌面)中的文件系统服务器时,您可能会遇到异常,适当或较差的性能。文件系统API非常广泛(20-40种消息类型),具有许多复杂的语义,涉及磁盘状态,内存中的缓存状态以及多个进程的并发访问。此外, osxfs
集成了macOS的FSEvents API和Linux的inotify
API之间的映射,该映射是在文件系统本身内部实现的,这使事情进一步复杂化(尤其是缓存行为)。
在最高级别上,文件系统性能有两个维度:吞吐量(读/写IO)和延迟(往返时间)。在现代SSD上的传统文件系统中,应用程序通常可以期望几GB / s的吞吐量。借助大量的顺序IO操作, osxfs
可以实现约250 MB / s的吞吐量,尽管不是本机速度,但对于大多数在HDD上可以令人满意地执行的应用程序来说,这并不是瓶颈。
延迟是文件系统调用完成所花费的时间。例如,线程在容器中发出写入操作与恢复写入的字节数之间的时间。对于经典的基于块的文件系统,此延迟通常在10μs(微秒)以下。使用osxfs
,目前大多数操作的延迟大约为130μs或慢13倍。对于需要多次顺序往返的工作负载,这会导致明显的可观察到的减速。减少等待时间需要缩短从Linux系统调用到macOS并再次返回的数据路径。这需要依次调整数据路径中的每个组件-其中一些需要大量的工程工作。即使我们将往返时间的延迟大幅降低了65μs,我们仍然只能“看到”性能翻倍。这是性能工程的典型特征,需要大量的精力来分析性能下降并开发优化的组件。我们知道一些可能减少往返时间的方法,但我们还没有(更多关于这下面实现的所有这些改进还可以做什么 )。
提高性能的第二种方法是通过缓存数据来减少往返次数。适用于Mac的Docker桌面的最新版本(自17.04起)包括缓存支持,为许多应用程序带来了显着(2-4倍)的改进。osxfs的大部分开销来自保持文件系统的容器视图和主机视图的一致性的要求,但是并非所有应用程序都具有完全一致性,并且放宽约束为改善性能提供了许多机会。
当前,支持读取缓存,通过该缓存,文件系统的容器视图可以暂时偏离主机上的权威视图。计划进一步的缓存开发,包括对写缓存的支持。提供了各种缓存配置中行为的详细说明 。
我们在做什么
我们将继续积极致力于增加缓存并减少文件系统数据路径延迟。这要求对文件系统跟踪进行大量分析,并对系统改进进行推测性开发,以尝试解决特定的性能问题。也许令人惊讶的是,应用程序工作负载会对性能产生巨大影响。作为示例,以下是在论坛主题上提供的两个不同的用例,以及它们的性能因延迟,缓存和连贯性而有所不同和受到影响的情况:
-
出现了一个rake示例(请参阅下文),尝试访问共享卷上不存在的37000+个不同文件。即使通过减少等待时间将速度提高了2倍,该用例仍然显得“缓慢”。启用缓存后,性能会提高3.5倍左右,如用户指导的缓存文章中所述 。我们期望通过“负dcache”看到rake的进一步性能提高,该负跟踪可以在Linux内核本身中跟踪不存在的文件。但是,对于首次在共享目录上运行rake而言,这还不够。为了处理这种情况,我们实际上需要开发一个Linux内核补丁,该补丁会否定地缓存所有不在指定集中的目录条目-并且必须在macOS文件系统状态下实时保持该缓存的最新状态。是否缺少macOS FSEvents消息,因此如果macOS报告事件传递失败,则必须使之无效。
-
在共享文件系统中运行
ember build
导致ember创建许多不同的临时目录并在其中执行许多中间活动。一个空的余烬项目超过300MB。这种使用模式不需要Linux和macOS之间的一致性,并且通过写入缓存得到了显着改善。
这两个示例来自用户提供的性能用例,它们在确定文件系统性能方面的改进方面非常有用。我们正在开发统计文件系统跟踪分析工具,以更轻松地表征性能缓慢的工作负载,从而决定下一步该做什么。
正在开发中,我们有:
-
现实中用例不断增长的性能测试套件(有关更多信息,请参见下文)
-
进一步的缓存改进,包括否定,结构和回写缓存以及惰性缓存无效。
-
一个Linux内核补丁,可将数据路径延迟减少2/7副本和2/5上下文切换
-
增加的macOS集成以减少虚拟机监控程序和文件系统服务器之间的延迟
你可以做什么
当您报告共享文件系统性能问题时,最好包括一个最小的Real World复制测试用例,以证明性能不佳。
没有复制品,对于我们来说很难分析您的用例并确定哪些改进可以加速它。当您不提供复制品时,我们其中之一需要弄清楚您正在使用的特定软件,并猜测并希望我们以典型的方式或性能较差的方式对其进行配置。这通常需要1-4个小时,具体取决于您的用例,一旦完成,我们就必须确定正常的性能是什么样的,以及用例的速度变慢。在某些情况下,在您特定的开发工作流程中哪项操作的速度甚至还很慢,这并不明显。重现问题的其他设置意味着我们有更少的时间来修复错误,开发分析工具或提高性能。因此,包括简单,即时的性能问题再现测试案例。论坛主题中显示的@hirowatari的rake复制案例是一个很好的例子。
该示例最初提供:
-
版本控制的存储库,因此可以轻松跟踪对测试用例的任何更改/改进。
-
一个Dockerfile构造要运行的确切映像
-
有关如何启动容器的命令行调用
-
衡量用例性能的简单方法
-
有关如何运行测试用例的清晰说明(自述文件)
您能期待什么
我们将继续努力在Docker Desktop for Mac的Edge通道上优化共享文件系统的实现。
您可以预期,上面提到的一些性能改进工作将在接下来的发行周期中到达Edge渠道。
我们计划最终开放所有共享文件系统组件的源代码。到那时,我们将非常高兴与您合作改善osxfs
和相关软件的实施。
我们还计划在Docker博客上撰写和发布共享文件系统性能分析和改进的更多详细信息。寻找或轻推有关这些文章的@dsheets,它们应该作为了解系统,对其进行评估或做出贡献的起点。
包起来
我们希望这可以使您对osxfs
性能的osxfs
和发展方向有一个大概的了解。我们将良好的性能视为文件系统共享组件的重中之重,并且我们正在通过多种途径积极地对其进行改进。osxfs项目于12月开始
- 自2016年2月首次集成到Mac的Docker桌面以来,我们已将许多工作负载的性能提高了50倍或更多,同时实现了几乎完全的POSIX合规性且不影响一致性(它是共享的而不是简单地同步的)。当然,一开始有很多悬而未决的成果,现在许多剩余的性能改进都需要对定制的低级组件进行大量的工程工作。
感谢您在我们继续开发产品并致力于各种性能方面的理解。我们希望继续与社区合作,因此在发现问题时继续报告问题。我们期待与您就想法和源代码本身进行合作。
mac , osxfs