Docker镜像的构建过程,大量应用了镜像间的父子关系。即下层镜像是作为上层镜像的父镜像出现的,下层镜像是作为上层镜像的输入出现。上层镜像是在下层镜像的基础之上变化而来。
FROM指令是Dockerfile中唯一不可缺少的命令,它为最终构建出的镜像设定了一个基础镜像。该语句并不会产生新的镜像层,它是使用指定的镜像作为基础镜像层。docker build命令解析 Dockerfile的FROM指令时,可以立即获悉在哪一个镜像基础上完成下一条指令镜像层构建。
对于FROM centos:7来说,Docker Daemon首先从centos:7镜像的文件系统获取到该镜像的ID,然后再根据镜像ID提取出该镜像的json文件内容,以备下一条指令镜像层构建时使用。
LABEL指令仅修改上一步中提取出的镜像json文件内容,在json中添加LABEL auth=“Tom”,无需更新镜像文件系统。但也会生成一个新的镜像层,只不过该镜像层中只记录了json文件内容的修改变化,没有文件系统的变化。
如果该指令就是最后一条指令,那么此时形成大的镜像和文件系统其实就是原来FROM后指定镜像的文件系统,只是json文件发生了变化。但由于json文件内容发生了变化,所以产生了新的镜像层。
COPY指令会将宿主机中的指定文件复制到容器的指定目录,所以会改变该镜像层文件系统大小,并生成新的镜像层文件系统内容。所以json文件中的镜像ID也就发生了变化,产生了新的镜像层。
RUN指令本身并不会改变镜像层文件系统大小,但由于其RUN的命令是yum install,而该命令运行的结果就是下载并安装一个工具,所以导致RUN命令最后也改变了镜像层文件系统大小,所以也就生成了新的镜像层文件系统内容。所以json文件中的镜像ID也就发生了变化,产生了新的镜像层。
对于CMD或ENTRYPOINT指令,其是不会改变镜像层文件系统大小的,因为其不会再docker build过程中执行。所以该条指令没有改变镜像层文件系统大小。
但是对于CMD或者ENTRYPOINT指令,由于是等容器启动之后再执行的命令,所以会将其写入到json文件中,会引起json文件的改变。所以json文件中的镜像ID也就发生了变化,产生了新的镜像层。
Docker Daemnon 通过 Dockerfile 构建镜像时,当发现即将新构建出的镜像(层)与本地
已存在的某镜像(层)重复时,默认会复用已存在镜像(层)而不是重新构建新的镜像(层),这种
机制称为 docker build cache 机制。该机制不仅加快了镜像的构建过程,同时也大量节省了
Docker 宿主机的空间。
docker build cache 并不是占用内存的 cache,而是一种对磁盘中相应镜像层的检索、复
用机制。所以,无论是关闭 Docker 引擎,还是重启 Docker 宿主机,只要该镜像(层)存在于
本地,那么就会复用。
当 Dockerfile 文件中某个指令内容发生变化,那么从发生变化的这个指令层开始的所有
镜像层 cache 全部失效。即从该指令行开始的镜像层将构建出新的镜像层,而不再使用 buildcache,即使后面的指令并未发生变化。因为镜像关系本质上是一种树状关系,只要其上层
节点变了,那么该发生变化节点的所有下层节点也就全部变化了。
FROM centos:7
LABEL auto="Hayaizo"
COPY hello.log /var/log/
RUN yum install -y vim
CMD ["/bin/bash"]
EXPOSE 9000
修改为
FROM centos:7
LABEL auto="Hayaizo"
COPY hello.log /usr/local/
RUN yum install -y vim
CMD ["/bin/bash"]
EXPOSE 9000
COPY这一行发生了改变,那么从COPY这一层开始的镜像cache全部失效。
Dockerfile 文件内容没有变化,但 ADD 或 COPY 指令所复制的文件内容发生了变化,同
样会使从该指令镜像层开始的后面所有镜像层的 build cache 失效。
echo "hi Jerry" >> hello.log
又开始重新安装了。
与 ADD/COPY 指令相似。Dockerfile 文件内容没有变化,但 RUN 命令的外部依赖发生了
变化,例如本例中要安装的 vim 软件源发生了变更(版本变化、下载地址变化等),那么从发
生变化的这个指令层开始的所有镜像层 cache 全部失效。
有些时候为了确保在镜像构建过程中使用到新的数据,在镜像构建 docker build 时,通
过–no-cache 选项指定不使用 build cache。
dangling build cache,即悬虚 build cache,指的是无法使用的 build cache。一般为悬虚镜
像 dangling image 所产生的 build cache。通过 docker system prune 命令可以清除。
也可以使用docker system prune来清理: