Docker构建镜像的方式有多种,先介绍下最常用的两种,上面这两种方法中,镜像构建的底层原理是相同的,都是通过下面 3 个步骤来构建镜像:,下面,具体了解这两种构建 Docker 镜像的方式。,通过docker commit来构建一个镜像,命令的格式为docker commit [选项] [<仓库名>[:<标签>]]。,
,具体步骤如下:,这种镜像构建方式通常用在下面两个场景中:,除了这两种场景,不建议你使用docker commit来构建生产现网环境的镜像。,主要原因有两个:,docker build命令会读取Dockerfile的内容,并将Dockerfile的内容发送给 Docker 引擎,最终 Docker 引擎会解析Dockerfile中的每一条指令,构建出需要的镜像。,docker build的命令格式为
docker build [OPTIONS] PATH | URL | -
。PATH、URL、
-
指出了构建镜像的上下文(context),context 中包含了构建镜像需要的Dockerfile文件和其他文件。默认情况下,Docker 构建引擎会查找 context 中名为Dockerfile的文件,但你可以通过
-f
,
--file
选项,手动指定Dockerfile文件。例如:,使用 Dockerfile 构建镜像,本质上也是通过镜像创建容器,并在容器中执行相应的指令,然后停止容器,提交存储层的文件变更。和用
docker commit
构建镜像的方式相比,它有三个好处:,
执行docker build后的构建流程为:,第一步,docker build会将 context 中的文件打包传给 Docker daemon。如果 context 中有
.dockerignore
文件,则会从上传列表中删除满足
.dockerignore
规则的文件。,第二步,
docker build
命令向
Docker server
发送 HTTP 请求,请求
Docker server
构建镜像,请求中包含了需要的 context 信息。,第三步,
Docker server
接收到构建请求之后,会执行以下流程来构建镜像:,为了提高构建效率,
docker build
默认会缓存已有的镜像层。如果构建镜像时发现某个镜像层已经被缓存,就会直接使用该缓存镜像,而不用重新构建。如果不希望使用缓存的镜像,可以在执行
docker build
命令时,指定
--no-cache=true
参数。,Docker 匹配缓存镜像的规则为:遍历缓存中的基础镜像及其子镜像,检查这些镜像的构建指令是否和当前指令完全一致,如果不一样,则说明缓存不匹配。对于
ADD
、
COPY
指令,还会根据文件的校验和(checksum)来判断添加到镜像中的文件是否相同,如果不相同,则说明缓存不匹配。,这里要注意,缓存匹配检查不会检查容器中的文件。比如,当使用
RUN apt-get -y update
命令更新了容器中的文件时,缓存策略并不会检查这些文件,来判断缓存是否匹配。,最后,可以通过
docker history
命令来查看镜像的构建历史,如下图所示:,
,docker save用来将镜像保存为一个 tar 文件,docker load用来将 tar 格式的镜像文件加载到当前机器上,例如:,通过上面的命令,我们就在机器 B 上创建了nginx镜像。,通过docker export 保存容器的镜像,再通过docker import 加载镜像,具体命令如下:,通过
docker export
导出的镜像和通过
docker save
保存的镜像相比,会丢失掉所有的镜像构建历史。在实际生产环境中,我不建议你通过docker save和docker export这两种方式来创建镜像。,较推荐的方式是:在 A 机器上将镜像 push 到镜像仓库,在 B 机器上从镜像仓库 pull 该镜像。