Docker buildx层缓存哈希值是如何计算的?



我正在深入研究Docker buildx的缓存,试图调试一个问题。我试图弄清楚如何,确切地说,buildx检查一个层是否在本地缓存中可用。虽然我已经搜索了相当广泛,但我似乎找不到任何关于这方面的文档。

查看本地缓存文件本身,我看到了一堆带有散列名称的文件。我的假设是它的工作方式如下(假设使用type=local,mode=max):

  1. 对于Dockerfile中的每一行,它使用一些参数组合来计算SHA哈希值。
  2. 它在--cache-from目录中检查是否存在以该哈希作为名称的文件
  3. 如果它存在,它使用该文件作为层,不重新构建任何东西(并将该文件复制到--cache-to目录)。
  4. 如果存在,则构建该层并将其保存为文件,以该散列作为名称保存在--cache-to目录中。
  5. 这将导致Dockerfile中每行有一个输出缓存。

我的问题是:

  1. 我对这个过程的理解是否正确?我是否遗漏了什么关键元素?
  2. 对于上面的步骤(1),"参数"是什么?它用来计算哈希值的?我认为这是行本身的字符串值,加上由行复制的任何文件的值(例如ADD),但它是否使用其他任何东西?例如,它复制的任何文件的最后修改时间戳?
  1. 我对这个过程的理解是否正确?我是否遗漏了什么关键元素?

我的理解大致是这样的。我需要亲自检查代码以了解细节。

  1. 对于上面的步骤(1),"参数"是什么?它用来计算哈希值的?我认为这是行本身的字符串值,加上由行复制的任何文件的值(例如ADD),但它是否使用其他任何东西?例如,它复制的任何文件的最后修改时间戳?

一般来说,缓存Dockerfile步骤使用以下方法(这早于buildkit):

  • 对于ADD/COPY步骤,源文件的散列。该散列包括文件所有权和权限。快速测试表明修改时间戳不包括在其中(在我触摸正在复制的文件后仍然使用缓存)。
  • 对于RUN步骤,包括任何ENV或ARG键/值对,因为它们会修改环境以及正在运行的命令的文本。Docker没有从外部资源中提取命令的概念,也不知道哪些环境变量的变化会影响任何特定的命令。
  • 对于所有步骤,缓存要求前一步的结果加上当前步骤的匹配(新的COPY --link可能是一个例外)。因此,如果您将新文件复制到映像中,那么该构建阶段的所有剩余步骤都不会在缓存中找到,docker无法一般地知道特定文件不会影响某些RUN步骤。

最新更新