我对Docker的层缓存表现出色感到惊讶,但我也想知道它如何确定是否可以使用缓存的层。
让我们以这些构建步骤为例:
Step 4 : RUN npm install -g node-gyp ---> Using cache ---> 3fc59f47f6aa Step 5 : WORKDIR /src ---> Using cache ---> 5c6956ba5856 Step 6 : COPY package.json . ---> d82099966d6a Removing intermediate container eb7ecb8d3ec7 Step 7 : RUN npm install ---> Running in b960cf0fdd0a
例如,它如何知道可以使用缓存的层,npm install -g node-gyp但可以为其创建新层npm install呢?
npm install -g node-gyp
npm install
在Dockerfile最佳实践构建缓存部分中相当详尽地解释了构建缓存过程。
* 从缓存中已存在的基本映像开始,将下一条指令与从该基本映像派生的所有子映像进行比较,以查看是否其中一个是使用完全相同的指令构建的。如果不是,则高速缓存无效。 在大多数情况下,只需将中的指令Dockerfile与子图像之一进行比较就足够了。但是,某些说明需要更多检查和解释。 * 对于ADD和COPY指令,将检查图像中文件的内容,并为每个文件计算一个校验和。在这些校验和中不考虑文件的最后修改时间和最后访问时间。在高速缓存查找期间,将校验和与现有映像中的校验和进行比较。如果文件中的任何内容(例如内容和元数据)发生了更改,则缓存将无效。 除了ADD和COPY命令外,缓存检查不会查看容器中的文件来确定缓存是否匹配。例如,在处理RUN apt-get -y update命令时,将不检查容器中更新的文件以确定是否存在缓存命中。在这种情况下,仅命令字符串本身将用于查找匹配项。 一旦缓存无效,所有后续Dockerfile命令将生成新映像,并且将不使用缓存。
* 从缓存中已存在的基本映像开始,将下一条指令与从该基本映像派生的所有子映像进行比较,以查看是否其中一个是使用完全相同的指令构建的。如果不是,则高速缓存无效。
Dockerfile
* 对于ADD和COPY指令,将检查图像中文件的内容,并为每个文件计算一个校验和。在这些校验和中不考虑文件的最后修改时间和最后访问时间。在高速缓存查找期间,将校验和与现有映像中的校验和进行比较。如果文件中的任何内容(例如内容和元数据)发生了更改,则缓存将无效。
ADD
COPY
RUN apt-get -y update
一旦缓存无效,所有后续Dockerfile命令将生成新映像,并且将不使用缓存。
您将遇到将OS软件包,NPM软件包或Git存储库更新为较新版本(例如中的~2.3semver package.json)的情况,但是由于您未更新Dockerfile或未package.json更新,docker将继续使用缓存。
~2.3
package.json
Dockerfile通过修改某些更智能的检查(例如,从回购中检索最新的git分支shasum以便在克隆指令中使用),可以以编程方式生成破坏缓存的a。您也可以定期运行构建--no- cache=true以强制执行更新。
--no- cache=true