正如许多公司一样,我们为产品中的所有组件构建 Docker 镜像。随着时间的推移,一些镜像变得越来越大,持续集成(CI)构建时间也越来越长。我的目标是让 CI 构建不超过 5 分钟。这个想法来自于这是一个理想的咖啡休息时间。当构建时间超过这个时限时,它会降低开发人员的工作效率。
造成生产力下降的原因有两个:
开发人员开始新任务后再回来,这需要更多的上下文切换,通常也会导致效率低下。
在这篇文章中,我想展示我们实施的两个小改变,这些改变显著压缩了我们的构建时间。在关注这些改进之前,请确保你已经遵循了编写 Dockerfile 的最佳实践,如:
……
#1
让我们首先解释一下 Buildkit 和 Buildx,这两个术语经常被混用,但它们并不相同。在写这篇文章之前,我也没有完全理解它们之间的区别。
Builkit
Buildkit 是用来替代传统 Docker 构建器的改进后端。它自 2018 年起就被打包在 Docker 中,并从 Docker Engine 23.0 版开始成为默认构建器。
它提供了许多有趣的特性:
延迟加载基础镜像(从 Buildkit 0.9 版开始)
当使用 Buildkit 时,你会注意到 docker build 命令的输出看起来更清晰、更结构化。
DOCKER_BUILDKIT=1 docker build --platform linux/amd64 . -t someImage:someVersion
DOCKER_BUILDKIT=1 docker push someImage:someVersion
Buildx 是 Docker 的一个插件,它使你能够充分利用 Buildkit 在 Docker 中的潜力。它之所以被创造,是因为 Buildkit 支持许多新的配置选项,这些选项不能都以向后兼容的方式集成到 docker build 命令中。
除了构建镜像,Buildx 还支持管理多个构建器。这在 CI 中非常有用,可以定义具有不同配置的作用域环境,因为它们不会修改共享的 Docker daemon。
docker buildx create --bootstrap --name builder
docker buildx use builder
#2
docker pull someImage:latest || true
docker build --platform linux/amd64 . \
-t someImage:someVersion \
-f Dockerfile \
--cache-from someImage:latest
使用 Buildx,你可以将缓存信息存储在远程位置(例如 container registry、Blob 存储等)。构建器会检查给定层是否已存在,如果是,它将重用它而不是重新创建。这甚至可以在不拉取该层到本地的情况下完成。为了利用这种机制,我们重新编写了前面的命令:
docker buildx build --platform linux/amd64 . \
-t someImage:someVersion - push \
--cache-to type=registry,ref=someCachedImage:someVersion,mode=max
--cache-from type=registry,ref=someCachedImage:someVersion
docker buildx build - platform linux/amd64 . \
-t someImage:someVersion --push \
--cache-to type=inline,mode=max \
--cache-from someImage:somePreviousVersion
Docker 引入了它的 dockerfile 写作语法的新版本:#syntax=docker/dockerfile:1.4。它为 COPY 和 ADD 命令支持了额外的链接选项。
FROM baseImage:version
COPY binary /opt/
使用新语法的示例:
# syntax=docker/dockerfile:1.4
FROM baseImage:version
COPY [--chown=<user>:<group>] [--chmod=<perms>] --link binary /opt/
#4
这篇博客文章描述了我们在优化 CI pipeline 后获得的一些新见解。我讨论了两个小改动,使我们整体 Docker 构建时间减少了 40%:
在向 Docker 镜像添加、复制文件时使用链接选项。
《Docker中Image、Container与Volume的迁移》
免责声明:本文内容来源于网络,所载内容仅供参考。转载仅为学习和交流之目的,如无意中侵犯您的合法权益,请及时联系Docker中文社区!