docker pull
对docker图像层的提取(无标记(必须按顺序进行还是可以并行进行?
示例
docker pull mirekphd/ml-cpu-r40-base
——由于构建性能的原因,它必须被拆分为50多个层——它包含大约4k个预编译为DEB的R包(整个CRAN任务视图内容(,如果不将这些包拆分为大小大致相等的多个层,就不可能在docker中构建,这将构建时间从一整天缩短到几分钟。提取阶段——如果并行化——可能会快50倍。。。
上下文
当您观察大型多层图像(GB大小(的docker pull
时,您会注意到每个层的下载可以分别并行执行。对于顺序执行的这些层中的每一层的后续提取(无标记(,情况并非如此。我们知道为什么吗?
根据我对如此大的图像的轶事观察,这将大大加快docker pull
操作的执行速度。
此外,如果将图像拆分为更多的层可以让您更快地启动容器,那么人们会开始编写可读性更强、对调试/测试和pull
/run
都更快的Dockerfile
,而不是试图将所有指令堆积在一个缓慢的块上,令人难以置信的复杂和破坏缓存的指令串只会节省几兆字节的额外层开销(这将很容易通过并行提取来弥补(。
来自https://github.com/moby/moby/issues/21814,层没有并行提取的主要原因有两个:
- 它不适用于所有存储驱动程序
- 它可能会使用大量的CPu
请参阅下面的相关评论:
请注意,并非所有存储驱动程序都能够支持并行提取。有些是快照文件系统,在应用下一层之前,必须提取并快照第一层。
@阿伦莱曼
我们也不希望
pull
操作在运行容器的主机上消耗大量CPU。@cpuguy83
关闭链接问题的用户写道:
由于技术原因,这种情况不会发生。这里没有辩论的余地。AUFS会支持这一点,但大多数其他存储驱动程序都不支持。这也需要有特定的代码来实现至少两个不同的代码路径:一个有这种并行提取,另一个没有
图像基本上类似于图A->B->C->D和大多数Docker存储驱动程序无法处理提取任何依赖于尚未提取的层的层。
如果您想加快docker的提取速度,您肯定需要更快的存储和更快的网络。一旦Go 1.7推出,我们开始使用它,Go本身将有助于提高性能。
我现在就要结束这篇文章了,因为从特定驱动程序的并行提取中获得的任何收益都不值得代码的复杂性、实现它所需的努力以及在未来维护它所需要的努力。
@清除