documentation没有详细说明这个话题。它说:
最小化图层数
在Docker 17.05之前,甚至更多,之前 Docker 1.10,最大限度地减少你的层数 图片。以下改进减轻了这种需求:
在Docker 1.10及更高版本中,仅创建RUN,COPY和ADD指令 层。其他指令创建临时中间图像,和 不再直接增加构建的大小。
Docker 17.05及更高版本增加了对多阶段构建的支持 允许您仅将所需的工件复制到最终图像中。 这允许您在工具中包含工具和调试信息 中间构建阶段而不增加最终的大小 图像。
看起来最新的Docker版本无法解决处理多个层的问题。他们宁愿努力减少最终图像中的数量。最重要的是,文档并没有告诉为什么很多层都不好。
我知道42层的AUFS limit。对于广泛使用的图像,保持较小的层数是有意义的,因为它有助于构建在其上的其他图像符合限制。但是,还有其他存储驱动程序和图像用于其他目的。
将图像保持在一个明显的原因也很好 - 它们会占用磁盘空间和网络带宽。但是,我不认为chaining RUN statements并因此将多层压缩为一层有助于一般。如果不同的RUN更新文件系统的不同部分,则一层和多层的大小应该大致相同。
另一方面,许多层允许更快地使用缓存和重建图像。它们也是并行的。
我在一个拥有私有Docker注册表的小团队中工作。我们永远不会满足42层限制,主要关注性能和开发速度。
如果是这样,我应该最小化泊坞窗层的数量吗?
答案 0 :(得分:20)
我在一个拥有私有Docker注册表的小团队中工作。我们永远不会满足42层限制,主要关注性能和开发速度。
如果是这样,我应该最小化泊坞窗层的数量吗?
在你的情况下,没有。
需要最小化的是构建时间,这意味着:
话虽如此,the documentation you mention来自docker/docker.github.io
,正好是PR 4992和PR 4854,来自docker build LABEL
section。
所以这一部分是在关于LABEL
的类似评论之后发生的,只是强调了创建图层的命令
同样,在您的情况下,这不重要。
答案 1 :(得分:16)
我只想看看2个图像的区别是什么,一个是用多个RUN构建的,另一个是用一个RUN连接命令构建的。
在第一种情况下,图像正在进行简单的操作(创建和删除文件)。
"单身"的内容图层图片:
FROM busybox
RUN echo This is the 1 > 1 \
&& rm -f 1 \
&& echo This is the 2 > 2 \
&& rm -f 2 \
# ... for about 70 commands
多层图片的内容:
FROM busybox
RUN echo This is the 1 > 1
RUN rm -f 1
RUN echo This is the 2 > 2
RUN rm -f 2
# ... for about 70 layers
构建时间非常不同(倍数:0m34,973s,单数:0m0,568s)。容器启动时间也不同但不太明显(多个:0m0,435s,单数:0m0,378s)。我在图像上运行的时间不同,但时间并没有那么大的改变。
关于空间,我已经考虑了多层情况下最坏情况的目的,正如预期的那样,多层图像比单层更大。
在另一个测试中,我连接了仅向图像添加内容的图层。构建时间与前一种情况相比没有变化,但运行时情况显示略有不同:多层图像的启动速度比单层图像快。关于空间,相同的结果。
我不认为这证明了什么,但我很乐意这样做:P
答案 2 :(得分:7)
减少层数本身就不是一个目标。相反,您需要关注的是缩短构建时间并减少图像尺寸。
通过保留Dockerfile顶部或基本映像中很少更改的公共图层,可以减少构建时间。这允许在以后的构建中缓存和重用该层。这不是关于减少层数,而是关于更好地排序图层。
缩小映像大小有助于减少注册表服务器上的磁盘使用量,这会在为CI系统上的每个构建存储映像时看到磁盘大量命中。它还减少了传输图像的网络时间。如果您有一个下载大型临时文件的图层并将其删除到另一个图层中,则会导致该文件保留在第一层,通过网络发送并存储在磁盘上,即使它在内部不可见你的容器。更改文件的权限还会导致文件被复制到具有新权限的当前层,从而使该文件的磁盘空间和网络带宽加倍。
在上述场景中减少图像大小的标准解决方案是链接RUN
命令,以便临时文件永远不会存储到图像层。这具有减少图像层数的副作用。
还有最后一个问题,即过度缓存。这在Debian图像中的apt-get update
和apt-get install ...
命令中很常见。如果不将这些命令链接在一起,则apt-get install
命令的更新将重用前一层apt-get update
命令中可能过时的缓存,并且在几个月后无法找到所需的包时将失败。因此,您应该链接这些命令,即使它会增加构建时间,因为另一个选项是将来会出现构建失败。
因此,减少你想要的层的副作用更多,不一定是为了减少层数而减少层数。