简体   繁体   English

我应该最小化泊坞窗层的数量吗?

[英]Should I minimize the number of docker layers?

The documentation doesn't elaborate on the topic a lot. 文档没有详细说明该主题。 It says: 它说:

Minimize the number of layers 最小化层数

Prior to Docker 17.05, and even more, prior to Docker 1.10, it was important to minimize the number of layers in your image. 在Docker 17.05之前,甚至更多,在Docker 1.10之前,最大限度地减少图像中的图层数量非常重要。 The following improvements have mitigated this need: 以下改进减轻了这种需求:

In Docker 1.10 and higher, only RUN, COPY, and ADD instructions create layers. 在Docker 1.10及更高版本中,只有RUN,COPY和ADD指令可以创建图层。 Other instructions create temporary intermediate images, and no longer directly increase the size of the build. 其他指令创建临时中间图像,不再直接增加构建的大小。

Docker 17.05 and higher add support for multi-stage builds, which allow you to copy only the artifacts you need into the final image. Docker 17.05及更高版本增加了对多阶段构建的支持,允许您仅将所需的工件复制到最终图像中。 This allows you to include tools and debug information in your intermediate build stages without increasing the size of the final image. 这允许您在中间构建阶段中包含工具和调试信息,而不会增加最终图像的大小。

It looks like the latest Docker versions don't solve the problem of handling many layers. 看起来最新的Docker版本无法解决处理多个层的问题。 They rather strive to reduce their number in the final image. 他们宁愿努力减少最终图像中的数量。 Most importantly, the docs don't tell why many layers are bad. 最重要的是,文档并没有说明为什么很多层都不好。

I'm aware of the AUFS limit of 42 layers. 我知道42层的AUFS限制 It makes sense to keep the number of layers small for widely used images because it helps other images built on top of them fit the restriction. 对于广泛使用的图像,保持较小的层数是有意义的,因为它有助于构建在其上的其他图像符合限制。 However, there are another storage drivers and images for other purposes. 但是,还有其他存储驱动程序和图像用于其他目的。

It is also good to keep images small for an obvious reason - they take up disk space and network bandwidth. 保持图像较小也是一个明显的原因 - 它们占用磁盘空间和网络带宽。 However, I don't think that chaining RUN statements and thus squashing many layers into one helps in general. 但是,我不认为链接RUN语句并因此将多个层压缩为一个有助于一般。 In case different RUNs update different parts of the filesystem one layer and many layers together should be approximately the same in size. 如果不同的RUN更新文件系统的不同部分,则一层和多层的大小应该大致相同。

On the other hand, many layers allow to make use of cache and rebuild images faster. 另一方面,许多层允许更快地使用缓存和重建图像。 They are also pulled in parallel. 它们也是平行拉动的。

I work in a small team with a private Docker registry. 我在一个拥有私有Docker注册表的小团队中工作。 We won't ever meet the 42 layers restriction and care mostly about performance and development speed. 我们永远不会满足42层限制,主要关注性能和开发速度。

If so, should I minimize the number of docker layers? 如果是这样,我应该最小化泊坞窗层的数量吗?

I work in a small team with a private Docker registry. 我在一个拥有私有Docker注册表的小团队中工作。 We won't ever meet the 42 layers restriction and care mostly about performance and development speed. 我们永远不会满足42层限制,主要关注性能和开发速度。

If so, should I minimize the number of docker layers? 如果是这样,我应该最小化泊坞窗层的数量吗?

In your case, no. 在你的情况下,没有。
What needs to be minimized is the build time, which means: 需要最小化的是构建时间,这意味着:

  • making sure the most general steps, and the longest are first, that will then cached, allowing you to fiddle with the last lines of your Dockerfile (the most specific commands) while having a quick rebuild time. 确保最常用的步骤,最长的步骤,然后缓存,允许你在快速重建时间的同时摆弄Dockerfile的最后几行(最具体的命令)。
  • making sure the longest RUN command come first and in their own layer (again to be cached), instead of being chained with other RUN commands: if one of those fail, the long command will have to be re-executed. 确保最长的RUN命令首先出现在它们自己的层中(再次被缓存),而不是与其他RUN命令链接:如果其中一个失败,则必须重新执行long命令。 If that long command is isolated in its own (Dockerfile line)/layer, it will be cached. 如果该长命令在其自己的(Dockerfile行)/层中被隔离,则它将被缓存。

That being said, the documentation you mention comes from docker/docker.github.io , precisely PR 4992 and PR 4854 , after a docker build LABEL section . 话虽这么说, 你提到的文档来自docker/docker.github.io ,正好是PR 4992PR 4854 ,在docker/docker.github.io docker build LABEL部分之后
So this section comes after a similar remark about LABEL , and just emphasize the commands creating layers. 所以这一部分是在关于LABEL的类似评论之后,并强调创建图层的命令。
Again, in your case, that would not be important. 再次,在您的情况下,这不重要。

I just wanted to see what were the differences of 2 images, one built with multiple RUNs and the other built with one RUN concatenating commands. 我只是想看看2个图像的区别是什么,一个是用多个RUN构建的,另一个是用一个RUN连接命令构建的。

In the first case, the images are doing trivial operations (creating and deleting files). 在第一种情况下,图像正在进行简单的操作(创建和删除文件)。

Content of the "single" layer image: “单个”图层图像的内容:

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

Content of the multiple layers image: 多层图像的内容:

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

The build time is very different (multiple: 0m34,973s, singular: 0m0,568s). 构建时间非常不同(多个:0m34,973s,单数:0m0,568s)。 The container start-up time is also different but less noticeable (multiple: 0m0,435s, singular: 0m0,378s). 容器启动时间也不同但不太明显(多个:0m0,435s,单数:0m0,378s)。 I've run different times the images but the times do not change that much. 我运行的图像时间不同,但时间并没有那么大。

Concerning the space, I've looked on purpose for the worst case for the multiple layer case and as expected the multiple layer image is bigger than the single layer. 关于这个空间,我看了多层情况下最坏情况的目的,正如预期的那样,多层图像比单层更大。

In another test, I concatenated layers that only add content to the image. 在另一个测试中,我连接了仅向图像添加内容的图层。 The build time does not change from the previous case but the run-time case shows something a little different: the multi layer image is faster to start-up than the single layer image. 构建时间与前一种情况相比没有变化,但运行时情况显示略有不同:多层图像的启动速度比单层图像快。 Concerning the space, same results. 关于空间,同样的结果。

I don't think this proves anything but I had fun in doing it :P 我不认为这证明了什么,但我很乐意这样做:P

Reducing the number of layers is less of a goal itself. 减少层数本身就不是目标。 Rather what you need to focus on is reducing build time and also reducing image size. 相反,您需要关注的是减少构建时间并减少图像大小。

Build time is reduced by keeping common layers that rarely change at the top of your Dockerfile, or in a base image. 通过保留Dockerfile顶部或基本映像中很少更改的公共层来减少构建时间。 This allows the layer to be cached and reused in later builds. 这允许在以后的构建中缓存和重用该层。 This is less about reducing the number of layers, and more about ordering your layers well. 这不是关于减少层数,而是关于更好地排序层。

Reducing image size helps reduce the disk usage on registry servers, which see a large hit to the disk when images are stored for each build on a CI system. 减小映像大小有助于减少注册表服务器上的磁盘使用量,这会在为CI系统上的每个构建存储映像时对磁盘造成大量影响。 It also reduces the network time to transfer the image. 它还减少了传输图像的网络时间。 When you have one layer that downloads a large temporary file and you delete it in another layer, that has the result of leaving the file in the first layer, where it gets sent over the network and stored on disk, even when it's not visible inside your container. 如果您有一个下载大型临时文件的图层并将其删除到另一个图层中,则会导致该文件保留在第一层,通过网络发送并存储在磁盘上,即使它在内部不可见你的容器。 Changing permissions on a file also results in the file being copied to the current layer with the new permissions, doubling the disk space and network bandwidth for that file. 更改文件的权限还会导致使用新权限将文件复制到当前层,从而使该文件的磁盘空间和网络带宽加倍。

The standard solution to reduce the image size in the above scenarios is to chain the RUN commands so that temporary files are never stored to an image layer. 在上述场景中减小图像大小的标准解决方案是链接RUN命令,以便临时文件永远不会存储到图像层。 This has the side effect of reducing the number of image layers. 这具有减少图像层数量的副作用。

There's one last issue, which is excessive caching. 还有最后一个问题,即过度缓存。 This is commonly seen with the apt-get update and apt-get install ... commands in Debian images. 这在Debian图像中的apt-get updateapt-get install ...命令中很常见。 If you do not chain these commands together, an update to the apt-get install command will reused a possibly stale cache from the previous layers apt-get update command, and will fail months later when it cannot find the needed packages. 如果不将这些命令链接在一起,则对apt-get install命令的更新将重用前一层apt-get update命令中可能过时的缓存,并且在几个月后无法找到所需的包时将失败。 Therefore, you should chain these commands even though it will increase build time, because the other option is to have build failures in the future. 因此,您应该链接这些命令,即使它会增加构建时间,因为另一个选项是将来会出现构建失败。

Therefore, it's more the side effects of reducing layers that you want, not necessarily reducing the layers for the sake of reducing layers. 因此,减少所需的层的副作用更多,不一定是为了减少层而减少层数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM