我正在尝试改善CI / CD性能,其中一部分是改善Docker构建的缓存行为。我发现自己正在尝试调试使缓存完全无效的内容。有什么方法可以查询Docker构建过程以获取比“已缓存”和“未缓存”更多的信息?例如,在某个时候,我添加了一个大目录,据我所知,该目录并未更改,但是破坏了缓存。我想找出是什么原因造成的。

评论

调试技巧-您可以使用tar -cf-<目录或文件> |来检查是否等效(内容,日期,所有者和权限)。 md5sum。我进行了两次构建,然后从jenkins工作区的顶层目录开始,一直进行下去,直到找到哈希开始匹配的位置,然后再进行工作,直到发现不匹配的哈希为止。就我而言,我必须设置几个git目录的上次修改时间。

#1 楼

泊坞窗缓存需要以下内容:


构建先前已在同一泊坞窗主机上运行(或者您已显式添加标志以信任提取的映像),并且仍位于构建主机上(未修剪),并且
相同的上一层,并且正在运行相同的命令(包括相同的环境/ args)或
文件上的相同哈希正在复制

如果您看到缓存在COPYADD命令而不是上一步中被破坏,那么您需要查看正在生成的哈希。所有文件都必须相同,文件名,大小写,文件权限,文件所有者相同,内容也要一点一点相同。您可以通过运行docker image history命令查看此哈希的结果校验和,例如:上图中与您的问题相关的关键数据是在--no-trunc步骤中,您会看到ADD。如果在两个映像构建之间该校验和发生更改,则缓存将崩溃,您将开始一组新的层。

#2 楼

根据Docker文档搜索:“利用构建缓存”,在目录上计算出校验和-有关详细信息,请参阅本文。

我建议的是多阶段构建。

如果目录具有静态内容,则可以使用其内容创建容器/图像。然后,我们可以使用FROM作为构建阶段,而不是使用Docker复制,然后将该目录复制到一个新层中,这实际上将重用该层。
这是基于我们没有在目录(文件可以更改属性(如上次访问时间)的时间)。

基础Dockerfile

FROM alpine:latest  
COPY /myDirectory .


那么您可以将此容器标记为存储基础
O

MultiStage Dockerfile

FROM storage-base AS storage

FROM alpine:latest  
RUN a command 
WORKDIR /root/
COPY --from=storage /myDirectory .


请在此处查看更多参考:Docker Multistage Build

编辑


只有在目录内容将更改时(由知道数据已更改的触发器),才应重新创建在步骤1中创建的图像/容器,这意味着将不会在每个版本上都创建它。
那么我们使用一次创建的图像(并重复使用该层)

我刚刚创建了一个简单的示例来表达我的想法-Git repo-运行build-docker.sh脚本

我发现在重新启动时Docker会重新创建缓存而不是重新使用缓存,但是它只需要几分钟,并不重要。

评论


不幸的是,这根本没有帮助我。我确实在自己的研究中看过这篇文章。它没有提供任何细节,也没有帮助调试为什么不缓存按位相同的目录。将构建分为多个部分也无济于事,因为第一阶段将使缓存失效,从而触发所有随后的阶段也被取消缓存:(

–扭矩
19年8月1日在14:07

@Torque,请看我的编辑,因为我的想法不好。

–profesor79
19年8月1日在17:03

尽管我感谢您付出的努力,但实际上并不能解决问题-编写您自己的程序或脚本来解决Dockers缓存中的错误并不是一种明智的方法。 Docker已经具备了此功能,我正在寻找方法来调试为什么它无法按定义工作,而不是破解它。此外,就像我说的那样,我们在CI / CD中使用此文件,因此不会有旧文件,它始终是新签出的文件。最后,缓存失效使我们的构建花费了一个多小时的编译时间,而不是几分钟。

–扭矩
19年8月2日在7:14

@Torque感谢您的评论。您的构建系统是否重新启动?

–profesor79
19年8月2日在8:05

重新启动不是使缓存无效的(如果您要这样做)。

–扭矩
19年8月2日在9:19

#3 楼

我必须处理相同的问题,主要问题不是缓存本身是进行构建所花费的时间,而是确保您对要构建的映像进行正确更改的问题。

我可以为您推荐可以单独或一起使用的一些不同选项:这样一来,您一定会确保每周都有新鲜的图像,并且每天构建的缓存都具有良好的性能,唯一需要花费更多时间的是刷新后的第一个构建。
制作自己的具有您知道的所有内容的基本映像,您不会经常更改,因为您可以在项目上拥有多个Dockerfile,并在上一步刷新后启动基本映像的构建过程,以确保您拥有新鲜图像的最新更改
使用多阶段构建或构建模式以在构建结束时获得良好的尺寸图像。


评论


您的推荐正是我们的工作。问题出在我的最后两句话中-很少更改的内容不会更改,但是缓存仍然无效,这就是我要调试的内容。

–扭矩
19年8月2日在7:16