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。