写点什么

如何将 Docker 的构建时间减少 40%

作者:高端章鱼哥
  • 2023-11-21
    福建
  • 本文字数:1816 字

    阅读完需:约 6 分钟

如何将Docker的构建时间减少40%

与许多公司类似,我们为产品中使用的所有组件构建 docker 映像。随着时间的推移,其中一些映像变得越来越大,我们的 CI 构建花费的时间也越来越长。我的目标是 CI 构建不超过 5 分钟——差不多是喝杯咖啡休息的理想时间。如果构建花费的时间超过这个时间,就会降低开发人员的工作效率。


造成生产力损失的原因是:

1、开发人员需要等待构建完成,从而浪费时间。

2、开发人员开始做一些新的东西,并在晚些时候再回来做。切换必然耗时,这通常也会导致效率低下。


图片


在这篇文章中,我想说明我们应用的 2 个小变化,两者极大地改善了我们的构建时间。当然,在关注这些改进之前,请确保你已经遵循编写 dockerfile 的最佳实践,比如尽量减少层数;使用多级构建;使用最小的基础图像等等。

1、Buildkit vs Buildx  


让我们从解释 Buildkit 和 Buildx 开始,因为这两个术语经常互换使用,但它们并不相同。

Builkit

Buildkit 是经过改进的后端,用来取代旧的 Docker 构建器。它在 2018 年打包在 Docker 中,并成为 docker engine 23.0 的默认构建器。   


它提供了许多有趣的功能:

  • 改进的缓存功能

  • 并行构建不同的层

  • 延迟拉取基础镜像(≥Buildkit 0.9)

在使用 Buildkit 时,你很快就会注意到 docker 构建命令的输出看起来更清晰、更结构化。


在 docker 版本低于 23.0 的情况下使用 Buildkit 的典型方法是设置 Buildkit 参数。如下所示:


DOCKER_BUILDKIT=1 docker build --platform linux/amd64 . -t someImage:someVersionDOCKER_BUILDKIT=1 docker push someImage:someVersion
复制代码

Buildx

Buildx 是 Docker 的一个插件,它使你能够在 Docker 中使用 Buildkit 的全部潜力。之所以创建它,是因为 Buildkit 支持许多新的配置选项,这些选项不能全部以向后兼容的方式集成到 docker 构建命令中。


除了构建镜像之外,Buildx 还支持管理多个构建器。在 CI 中,这对于定义具有不同配置的作用域环境非常有用,因为它们不会修改共享 Docker 守护进程。


你可以像下面这样开始使用 Buildx:


docker buildx create --bootstrap --name builderdocker buildx use builder
复制代码

2、受益于远程缓存


加快构建速度的第一种方法是在远程注册表中缓存镜像。这样,即使在不同的机器上执行构建,也可以从构建缓存中获益,这是 CI 中的典型情况。作为一种解决方法,许多人在构建新映像版本之前提取了映像的最新版本。这样做的好处是,你可以缓存未更改的图层,而代价是最初提取完整的图像。拉取完整的图像可能需要一段时间,但也不能保证图层可以被重用。为了说明这一点,我们使用了以下命令:


图片


使用 Buildx,你可以将缓存信息存储在远程位置(例如容器注册表、blob 存储等)。构建器检查给定层是否已经存在,如果是这种情况,它将重用它而不是再次创建它。这甚至可以在不拉动本地图层的情况下完成。为了从这个机制中受益,我们将之前的命令修改为:   


图片


模式“max”意味着我们将存储每一层的构建信息,甚至是生成图像中未使用的层(例如,当使用多阶段构建时)。默认模式下使用“min”,它只存储最终映像中存在的层的构建信息。


缓存的一个特殊情况是“内联”存储缓存数据,这意味着它将与图像一起缓存。当使用 Buildkit 而不使用 Buildx 时,也支持此选项。它是最容易开始的,但在使用多阶段构建时就比较棘手了,而且它没有在工件输出和缓存之间提供明确的分离。内联存储缓存数据的命令如下:


图片

3、添加文件到 Docker 镜像的新方法


Docker 引入了新的 dockerfile 编写语法,即:

#syntax= docker /dockerfile:1.4。它支持 COPY 和 ADD 命令的额外链接选项。


以前,当你使用 COPY 或 ADD 命令时,构建器会创建一个新快照,它将新文件与现有文件系统合并。其结果是,在执行此操作之前,父层都需要存在,否则目标目录可能还不存在。最后,你的映像(构建命令的结果)将由每个层的 tarball 组成,其中包含各个快照之间的差异。


图片


当使用 link 选项时,新文件将被放入它们自己的快照中,而不依赖于以前的层。链接的文件存储在它们自己的 tarball 中,不同的 tarball 被链接在一起,不依赖于现有的文件系统,如下图所示。


图片

https://www.docker.com/blog/image-rebase-and-improved-remote-cache-support-in-new-buildkit/


图片


主要优点是文件不再依赖于以前的层。只要文件没有改变,即使父层改变了,层也可以被重用。

此外,这还可以提高构建的速度,因为现在可以并行执行多层复制数据。

4、结论


本文描述了我们在优化 CI 管道后获得的一些新见解。我讨论了 2 个小的变化,导致我们的整体 docker 构建时间减少了 40%:其一,远程存储构建缓存信息;其二,在添加、复制文件到 docker 镜像时使用 link 选项。

发布于: 刚刚阅读数: 5
用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
如何将Docker的构建时间减少40%_Docker 镜像_高端章鱼哥_InfoQ写作社区