超薄Docker容器-减少Docker镜像大小的指南( 二 )


注意:使用您不想更改的第三方Dockerfile时 , 一种最小化任何可能浪费空间的快速简便方法是使用--squash构建它 。您可以使用潜水工具检查图像的最终效率 。
命令合并您是否见过带有RUN指令非常长的Dockerfile , 其中多个Shell命令与&&聚合在一起? 命令合并 。
通过合并命令 , 我们实际上是根据此单个long命令的结果创建了一个单独的层 。由于不存在用于添加文件并随后在另一层中删除文件的中间层 , 因此最后一层将不会为此类幻影文件使用任何空间 。让我们通过修改上述Dockerfile来了解这一点:

FROM alpineRUN wget http://xcal1.vodafone.co.uk/10MB.zip -P /tmp && rm /tmp/10MB.zip
现在我们有了一个优化的镜像:
超薄Docker容器-减少Docker镜像大小的指南

文章插图
A 100% optimised image with commands merge (Image by the author)
当您完成构建Dockerfile时 , 请检查它以查看是否可以合并命令以减少可能的浪费空间 。
标准化镜像层如果基础存储驱动程序支持 , 则镜像可以具有的最大层数为127 。如果确实需要 , 可以增加此限制 , 但是随后您可以缩小构建该映像的位置的选择(即 , 您需要在类似修改的基础内核上运行的Docker引擎) 。
正如上面有关Docker镜像层的部分中所讨论的 , 由于UnionFS , 进入层的任何文件资源都保留在该层中 , 即使您在后一层中管理该文件也是如此 。我们来看一个示例Dockerfile:
FROM alpineRUN wget http://xcal1.vodafone.co.uk/10MB.zip -P /tmpRUN rm /tmp/10MB.zip
构建以上镜像:
超薄Docker容器-减少Docker镜像大小的指南

文章插图
Building a sample image with wasted space (Image by the author)
并进行潜水检查:
超薄Docker容器-减少Docker镜像大小的指南

文章插图
Image is only 34% efficient (Image by the author)
效率为34%表示图像中浪费了很多空间 。这将导致更长的图像获取时间 , 额外的带宽消耗和更慢的启动时间 。
我们如何摆脱这个浪费的空间?
删除缓存通常 , 当我们将应用程序容器化时 , 我们需要使用软件包管理器(例如apk , yum或apt)在生成的映像上提供额外的工具 , 库或实用程序 。
当我们通过缓存先前获取的软件包来安装软件包时 , 软件包管理器试图为我们节省时间和带宽 。为了使生成的Docker映像的尺寸尽可能小 , 我们不需要保留程序包管理器缓存 。毕竟 , 如果我们的容器需要其他映像 , 我们总是可以使用更新的Dockerfile重建映像 。
要删除上述三个流行的软件包管理器的软件包管理器缓存 , 我们可以在聚合(即命令合并)命令的末尾添加以下命令 , 例如:
APK: ... && rm -rf /etc/apk/cacheYUM: ... && rm -rf /var/cache/yumAPT: ... && rm -rf /var/cache/apt
 
注意:在最终确定Docker镜像之前 , 请不要忘记删除构建期间使用的所有缓存以及容器正常运行所不需要的任何其他临时文件 。
选择基础镜像每个Dockerfile都以FROM指令开头 。在此定义我们将在其上创建自己的图像的基础图像 。
如Docker文档中所述:
" FROM指令初始化一个新的构建阶段 , 并为后续指令设置基础映像 。因此 , 有效的Dockerfile必须以FROM指令开头 。该图像可以是任何有效的图像-从公共存储库中提取图像特别容易 。"
显然 , 有很多不同的基础图像可供选择 , 每个基础图像都有自己的优势和功能 。当涉及到您自己的Docker映像的最终大小时 , 选择一个足以提供应用程序运行所需的工具和环境的映像至关重要 。
正如您所期望的那样 , 不同的流行基本镜像的大小差异很大:
超薄Docker容器-减少Docker镜像大小的指南

文章插图
Popular Docker base images size (Image by the author)
实际上 , 使用Ubuntu 19.10基本映像对应用程序进行容器化将至少增加73 MB , 而使用Alpine 3.10.3基本映像的完全相同的应用程序只会使大小增加6 MB 。随着Docker缓存图像层 , 下载/带宽损失仅在您第一次使用该图像启动容器时适用(或者简单地 , 在拉取图像时) 。但是 , 增加的大小仍然存在 。


推荐阅读