zoukankan      html  css  js  c++  java
  • docker build 不使用缓存重建镜像

    cache 机制注意事项

    可以说,cache 机制很大程度上做到了镜像的复用,降低存储空间的同时,还大大缩短了构建时间。然而,不得不说的是,想要用好 cache 机制,那就必须了解利用 cache 机制时的一些注意事项。

    1. ADD 命令与 COPY 命令:Dockerfile 没有发生任何改变,但是命令ADD run.sh / 中 Dockerfile 当前目录下的 run.sh 却发生了变化,从而将直接导致镜像层文件系统内容的更新,原则上不应该再使用 cache。那么,判断 ADD 命令或者 COPY 命令后紧接的文件是否发生变化,则成为是否延用 cache 的重要依据。Docker 采取的策略是:获取 Dockerfile 下内容(包括文件的部分 inode 信息),计算出一个唯一的 hash 值,若 hash 值未发生变化,则可以认为文件内容没有发生变化,可以使用 cache 机制;反之亦然。

    2. RUN 命令存在外部依赖:一旦 RUN 命令存在外部依赖,如RUN apt-get update,那么随着时间的推移,基于同一个基础镜像,一年的 apt-get update 和一年后的 apt-get update, 由于软件源软件的更新,从而导致产生的镜像理论上应该不同。如果继续使用 cache 机制,将存在不满足用户需求的情况。Docker 一开始的设计既考虑了外部依赖的问题,用户可以使用参数 --no-cache 确保获取最新的外部依赖,命令为docker build --no-cache -t="my_new_image" .

    3. 树状的镜像关系决定了,一次新镜像的成功构建将导致后续的 cache 机制全部失效:这一点很好理解,一旦产生一个新的镜像,同时意味着产生一个新的镜像 ID,而当前宿主机环境中肯定不会存在一个镜像,此镜像 ID 的父镜像 ID 是新产生镜像的ID。这也是为什么,书写 Dockerfile 时,应该将更多静态的安装、配置命令尽可能地放在 Dockerfile 的较前位置。

    使用Dockerfile构建镜像可以利用它的缓存功能:只有在命令已更改的情况下,才会重建已构建的步骤。下面是重新构建之前涉及到的to-do app的示例:

    1. $ docker build .
    2. Sending build context to Docker daemon  2.56 kB
    3. Sending build context to Docker daemon
    4. Step 0 : FROM node
    5.   ---> 91cbcf796c2c
    6. Step 1 : MAINTAINER ian.miell@gmail.com
    7.  ---> Using cache
    8. Indicates you’re using the cache
    9. Specifies the cached image/layer ID
    10.    ---> 8f5a8a3d9240
    11. Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git
    12.  ---> Using cache
    13.  ---> 48db97331aa2
    14. Step 3 : WORKDIR todo
    15.  ---> Using cache
    16.  ---> c5c85db751d6
    17. Step 4 : RUN npm install > /dev/null
    18.  ---> Using cache
    19.  ---> be943c45c55b
    20. Step 5 : EXPOSE 8000
    21.  ---> Using cache
    22.  ---> 805b18d28a65
    23. Step 6 : CMD npm start
    24.  ---> Using cache
    25.  ---> 19525d4ec794
    26. Successfully built 19525d4ec794

    缓存非常有用并且省时间,不过有时候docker缓存的行为不都能达到你的期望。
    用以上Dockerfile作为示例,假设你更改了代码并push到Git仓库。新代码不会check out下来,因为git clone命令没有更改。在Docker看来git clone的步骤一样,所以使用了缓存。
    在这种情况下,你可能不想开启docker的缓存了。

    问题

    你想不用缓存重建Dockerfile。

    解决方法

    构建镜像时使用–no-cache参数。

    讨论

    为了强制docker构建镜像时不用缓存,执行带–no-cache参数的docker build命令。下面的示例是使用了–no-cache构建镜像。

    1. $ docker build --no-cache .
    2. Sending build context to Docker daemon  2.56 kB
    3. Sending build context to Docker daemon
    4. Step 0 : FROM node
    5.  ---> 91cbcf796c2c
    6. Step 1 : MAINTAINER ian.miell@gmail.com
    7.  ---> Running in ca243b77f6a1
    8.  ---> 602f1294d7f1
    9. Removing intermediate container ca243b77f6a1
    10. Step 2 : RUN git clone -q https://github.com/docker-in-practice/todo.git
    11.  ---> Running in f2c0ac021247
    12.  ---> 04ee24faaf18
    13. Removing intermediate container f2c0ac021247
    14. Step 3 : WORKDIR todo
    15.  ---> Running in c2d9cd32c182
    16.  ---> 4e0029de9074
    17. Removing intermediate container c2d9cd32c182
    18. Step 4 : RUN npm install > /dev/null
    19.  ---> Running in 79122dbf9e52
    20. npm WARN package.json todomvc-swarm@0.0.1 No repository field.
    21.  ---> 9b6531f2036a
    22. Removing intermediate container 79122dbf9e52
    23. Step 5 : EXPOSE 8000
    24.  ---> Running in d1d58e1c4b15
    25.  ---> f7c1b9151108
    26. Removing intermediate container d1d58e1c4b15
    27. Step 6 : CMD npm start
    28.  ---> Running in 697713ebb185
    29.  ---> 74f9ad384859
    30. Removing intermediate container 697713ebb185
    31. Successfully built 74f9ad384859

    以上的构建镜像步骤没有使用到缓存,每一层的镜像ID都与之间的不同。

  • 相关阅读:
    tracert命令与tracert (IP地址)-d有什么区别?
    linux下通过进程名查看其占用端口
    Union和Union All的区别
    外连接、内连接
    Linux 删除文件夹和文件的命令(强制删除包括非空文件)
    linux查看当前目录
    Linux chmod命令及权限含义
    MySQL的if,case语句
    case when
    java生成验证码图片
  • 原文地址:https://www.cnblogs.com/ExMan/p/13040240.html
Copyright © 2011-2022 走看看