1     简介

docker image,即镜像,是docker的关键元素,它是一个可读的文件系统,又是一个多层的文件系统,可以导出成一个tar包文件,也可以上传到镜像仓库供其他人下载使用。

2     制作镜像

2.1    基本原理

docker镜像是一个多层的文件系统,制作镜像使用的Dockerfile每一行可以看作一层。

所有的镜像必须基于一个最基础的镜像,目前所有镜像都是基于base-ubuntu:latest这个镜像。

2.2    初步制作

2.2.1  Dockerfile

制作镜像的输入文件,以下文件是base-ubuntu:latest镜像的Dockerfile,

FROM ubuntu:16.04

 

MAINTAINER dongquan_wang"dongquan_wang@maxnetsys.com.cn"

 

ADD sources.list/etc/apt/sources.list

可以看到base-ubuntu这个镜像是以ubuntu:16.04为基础镜像的,同时更换了sources.list文件,ubuntu:16.04为从DockerHub下载的一个ubuntu的基础镜像,它的sources.list文件的源用的是国外的,故下载软件时比较慢,所以换成了国内的源,故更换sources.list。

2.2.2  命令

在当前Dockerfile所在的目录,只需要一条命令,docker  build -t   image_name   .

注意末尾必须要有一个点号,否则会报错误,此点号是为docker制作镜像时使用。

2.2.3  查看

使用命令docker  images 查看,可以看到自己制作的镜像的名字。所有的镜像默认都存储在宿主机的/var/lib/docker目录下,一个镜像不是一个文件,其中的存储机制非常复杂,建议初学者不要深究。

2.3    制作详解

2.3.1  命令描述

(1)  FROM,基础镜像名称,比如django镜像就是以python3镜像为基础的

(2)  MAINTAINER,维护人员,只起描述作用,私有镜像仓库无用

(3)  ADD,文件添加到镜像,如果文件为压缩格式,(.gz,.tar.gz,.tgz),会自动解压缩

(4)  COPY,文件添加到镜像,但不作解压缩动作

(5)  RUN,用得最多的指令,在镜像中执行命令,多用于apt-get(pip)安装软件

(6)  WORKDIR,指定该镜像启动的容器中的当前目录,对于基于django的镜像,会指定为工程的目录。

(7)  ENTRYPOINT,指定该镜像启动的容器的首个进程,注意此进程必须是挂住终端不能退出的,即不能为后台进程。可以指定参数。

(8)  CMD,指定命令参数,如果ENTRYPOINT不存在,则使用shell进程,否则直接将此命令作为首个进程启动。如果ENTRYPOINT存在,则将此参数附着其后形成真正的命令启动。

(9)  VOLUME,指定数据卷,表明该镜像启动的容器中,此目录为数据卷,即使容器停止并删除,数据卷的内容仍然存在。

 

注意以上的命令中,ENTRYPOINT、CMD、 VOLUMES指令只和容器相关,当容器启动前可以指定参数覆盖,即只有此镜像启动后才有意义,其他指令会直接作用于镜像。

2.3.2  镜像体积

为确保镜像体积足够小,在制作镜像过程结束后必须删除无用的文件,这些文件包括apt-get下载的文件包,可以使用命令RUN   rm -rf /var/lib/apt/lists/*;也可以包括为编译安装的某些软件比如gcc、make等,可以在结束前通过命令apt-get purge -y --auto-remove 删除。

在apt-get install时,系统会推荐安装某些附带软件,请务必使用--no-install-recommends --no-install-suggests忽略这些附带软件。

2.3.3  安装交互

apt-get安装时会有交互,使用参数-y表示全部选择yes;在安装mysql等软件时会有配置,比如用户名密码,请务必在apt-get之前添加前缀DEBIAN_FRONTEND=noninteractive,表示不进入交互环境,如此才可以安装成功。

2.3.4  镜像层级和cache

Dockerfile的一行(除MAINTAINER外)对应镜像的一层,为使层数足够小,故可以将类似的命令串起来,比如RUN 指令,可以使用&&连接多个指令,如此也只有一层。

制作镜像一次成功后,后续再使用同样的Dockerfile制作镜像会非常快,这是由于cache的原因,因此在书写Dockerfile时必须将经常变化的行放置到最后,如此前面的行就不需要再编译了。举例来说,对于django的工程镜像,最后一条指令就是币制当前的工程目录内容到镜像中,如此后续再编译镜像时可以加快镜像编译过程。

3     官方镜像

在制作标准软件的镜像时,比如mysql、nginx、redis,均可以参考github的官方Dockerfile,目前也是如此,比如mysql的Dockerfile取自https://github.com/docker-library/mysql.git,所有存在于docker-library的docker官方软件均可以下载它们的Dockerfile。