介绍

在我们多次构建中,构建过程中下载的文件如果存在差异,但又因Dockerfile内容一致,构建中无法识别差异性,而引用旧的镜像层。

$ docker build .
Sending build context to Docker daemon 2.56 kB
Sending build context to Docker daemon
Step 0 : FROM node
 ---> 91cbcf796c2c
Step 1 : MAINTAINER ian.miell@gmail.com
 ---> Using cache  ⇽--- 表明此次构建使用了缓存
 ---> 8f5a8a3d9240  ⇽--- 指定缓存的镜像/层ID
Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git
 ---> Using cache
 ---> 48db97331aa2
Step 3 : WORKDIR todo
 ---> Using cache
 ---> c5c85db751d6
Step 4 : RUN npm install > /dev/null
 ---> Using cache
 ---> be943c45c55b
Step 5 : EXPOSE 8000
 ---> Using cache
 ---> 805b18d28a65
Step 6 : CMD npm start
 ---> Using cache
 ---> 19525d4ec794
Successfully built 19525d4ec794  ⇽--- 最后镜像是“重新构建”了,但是实际上没有任何变动

为了避免这种打包错误,所以我们用了禁用缓存


1. 通过添加 --no-cache 参数禁用构建缓存

使用--no-cache参数来禁用构建缓存,禁止引用原有的镜像。

$ docker build --no-cache .
Sending build context to Docker daemon  2.56 kB
Sending build context to Docker daemon
Step 0 : FROM node
 ---> 91cbcf796c2c
Step 1 : MAINTAINER ian.miell@gmail.com
 ---> Running in ca243b77f6a1  ⇽--- 此时不再提示有缓存
  ---> 602f1294d7f1  ⇽--- 中间镜像的ID和之前列表里的有所不同
 Removing intermediate container ca243b77f6a1
Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git
 ---> Running in f2c0ac021247
 ---> 04ee24faaf18
Removing intermediate container f2c0ac021247
Step 3 : WORKDIR todo
 ---> Running in c2d9cd32c182
 ---> 4e0029de9074
Removing intermediate container c2d9cd32c182
Step 4 : RUN npm install > /dev/null
 ---> Running in 79122dbf9e52
npm WARN package.json todomvc-swarm@0.0.1 No repository field.
 ---> 9b6531f2036a
Removing intermediate container 79122dbf9e52
Step 5 : EXPOSE 8000
 ---> Running in d1d58e1c4b15
 ---> f7c1b9151108
Removing intermediate container d1d58e1c4b15
Step 6 : CMD npm start
 ---> Running in 697713ebb185
 ---> 74f9ad384859
Removing intermediate container 697713ebb185
Successfully built 74f9ad384859  ⇽--- 一个新的镜像构建出来了

2. 通过改变命令格式精细化禁用缓存

通过改变命令格式来禁用缓存 ,前面的镜像层依旧使用缓存,以减少构建时间。最后的CMD命令格式改变,从而构建一个新的镜像

$ docker build .   ⇽--- 一次“正常”的docker构建
Sending build context to Docker daemon  2.56 kB
Sending build context to Docker daemon
Step 0 : FROM node
 ---> 91cbcf796c2c
Step 1 : MAINTAINER ian.miell@gmail.com
 ---> Using cache
 ---> 8f5a8a3d9240
Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git
 ---> Using cache
 ---> 48db97331aa2
Step 3 : WORKDIR todo
 ---> Using cache
 ---> c5c85db751d6
Step 4 : RUN npm install
 ---> Using cache
 ---> be943c45c55b
Step 5 : EXPOSE 8000
 ---> Using cache  ⇽--- 到这里为止均是使用的缓存
 ---> 805b18d28a65
Step 6 : CMD ["npm","start"] #bust the cache  ⇽--- 缓存不再有效了,但是该命令实际上没有变化
 ---> Running in fc6c4cd487ce
 ---> d66d9572115e  ⇽--- 一个新的镜像被创建
Removing intermediate container fc6c4cd487ce
Successfully built d66d9572115e

3. 通过ARG随机生成值,来禁用缓存

$ docker build --build-arg CACHEBUST=${RANDOM} .

在构建过程中带上build-arg标志执行docker build,将CACHEBUST参数设置为一个由bash生成的伪随机数,或使用时间生成随机值

$ docker build --build-arg CACHEBUST=$(date +%s) .
Sending build context to Docker daemon 4.096 kB
Step 1/9 : FROM node
 ---> 53d4d5f3b46e
Step 2/9 : MAINTAINER ian.miell@gmail.com
 ---> Using cache
 ---> 3a252318543d
Step 3/9 : RUN git clone https://github.com/docker-in-practice/todo.git
 ---> Using cache
 ---> c0f682653a4a
Step 4/9 : WORKDIR todo
 ---> Using cache
 ---> bd54f5d70700
Step 5/9 : ARG CACHEBUST=no  ⇽--- 由于ARG CACHEBUST=no这一行本身没有变动,所以仍然使用了缓存
 ---> Using cache
 ---> 3229d52b7c33
Step 6/9 : RUN npm install  ⇽--- 由于CAHCEBUST参数被设置为之前未设定过的值,缓存被清除了,并且触发了再次执行npm install命令
 ---> Running in 42f9b1f37a50
npm info it worked if it ends with ok
npm info using npm@4.1.2
npm info using node@v7.7.2
npm info attempt registry request try #1 at 11:25:55 AM
npm http request GET https://registry.npmjs.org/compression
npm info attempt registry request try #1 at 11:25:55 AM
[...]
Step 9/9 : CMD npm start
 ---> Running in 19219fe5307b
 ---> 129bab5e908a
Removing intermediate container 19219fe5307b
Successfully built 129bab5e908a

4. 构建镜像时自动禁用缓存

使用ADD指令用于检测源文件是否已发生更改,当有提交新的commit时返回内容也会随之更改,如已发生更改,该层以下的镜像构建全部禁用缓存

FROM ubuntu:16.04
ADD https://api.github.com/repos/nodejs/node/commits /dev/null
RUN git clone https://github.com/nodejs/node  ⇽--- 只有存在更改时才会进行git clone
[...]
文章作者: hzbb
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 运维小记
云原生 Docker Docker
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝