如何调试导致不同工作站上相同代码库构建的层不同的原因?

问题描述

在我们的开发工作流程中,我们构建镜像,将它们推送到注册中心,然后在临时集群中部署来自它们的服务。由于在不同工作站上从完全相同的代码库构建的层往往最终具有不同的哈希值,因此工作流程因大量图像推送而严重陷入困境。我们确实了解 docker 的工作原理(即一点改变,层改变;一层改变,所有后续层也改变),但我们仍然相信有很多层失效正在发生,我们所做的任何事情都无法解释到我们的代码库或依赖项,并且完全是由于在不同机器上执行的构建。我们的构建原则上不是非常依赖平台(我们不会将任何东西编译成机器码),而且机器反正都是 x86_64 linux 机器。

有哪些工具、策略和最佳实践可以帮助我们调试发生这种情况的原因并可能缓解这种情况?

(重要提示:我们目前绝对负担不起的一个已知最佳实践是将构建过程转移到一台专用机器上,可能在云端。请不要建议此解决方案)。

解决方法

有哪些工具、策略和最佳实践可以帮助我们调试发生这种情况的原因并可能缓解这种情况?

您已经提到了一些您正在处理的事情,这些事情已经指出了这一点:

您想要的是可重现的构建。也就是说,相同的 VCS 修订版正在创建相同的映像(假设基础映像也是相同的)。

  • 检查正在使用的基本映像是否稳定(例如,您可以固定它们,并且它们不会在每个构建中更改,只是在打算更改它们时)。
  • 时间戳。检查您放入的文件不仅是与存储库中相同的二进制文件,还包括元数据。
  • 时间戳。在 docker 容器内。立即冻结以进行构建。不知道,这在很大程度上取决于构建中的内容。

您可以通过比较 tarball 来尽早验证。例如。从 VCS 导出 tarball 以进行构建,稍后从图像导出并查看发生了什么变化。使用 tar 比较文件列表很容易,而且您通常会保留工件,因此比较多次运行/修订/构建也很容易。

我不知道 Docker/Docker 中有任何专门用于可重现构建的特定工具,因此我无法在这里提出任何建议。

我猜 Google 的构建工具应该支持可重现的构建,但我不知道是否。我知道他们有一个构建工具(已发布)。

,

您可以使用 Dive (https://github.com/wagoodman/dive/) 等工具来检查图层。

除此之外 - 除非我看到 Dockerfiles,否则无济于事。

对我来说是个好习惯 - 在 Docker 中使用 Docker 来构建你的镜像。 通常类似的流程就足够了:

  1. 创建一个 docker:dind 容器
  2. 在其中克隆您的存储库
  3. 构建您的项目
  4. 运行 docker build(在我的 Dockerfile 中,我确保只复制运行时需要的文件 - 您也可以查找多阶段 Dockerfile)

一般的想法是始终从“干净的盘子”开始,一旦完成 - 销毁“盘子”并在下一次构建中重复。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...