Dockerfile是为快速构建docker image而设计的,当你使用docker build命令的时候,docker 会读取当前目录下的命名为Dockerfile(首字母大写)的纯文本文件并执行里面的指令构建出一个docker image。这比SaltStack的配置管理要简单的多,不过还是要掌握一些简单的指令。
Dockerfile 由一行行命令语句组成,并且支持以#开头的注释行。指令是不区分大小写的,但是通常我们都大写。
Nginx Dockerfile实战
注意:第一个指令必须是FROM。
[root@linux-node1 ~]# mkdir -p opt/dockerfile/mynginx[root@linux-node1 ~]# cd opt/dockerfile/mynginx/[root@test-node1 nginx]# vim Dockerfile# This docker file uses the centos image# VERSION 1# Author: Jason Zhao# Base imageFROM centos# MaintainerMAINTAINER shundong.zhao zhaoshundong@gmail.com#Commands to update the imageRUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpmRUN yum install -y nginx --enablerepo=epelADD index.html usr/share/nginx/html/index.htmlRUN echo "daemon off;" >> etc/nginx/nginx.confEXPOSE 80CMD ["nginx"]
Dockerfile 一般情况下分为四部分:
基础镜像信息
维护者信息
镜像操作指令
容器启动时执行指令
常用指令的介绍
构建Dockerfile
注意:ADD index.html就是放一个文件进去:
[root@linux-node1 mynginx]# echo "nginx in docker test" > index.html
使用dokcer build命令构建镜像,最后的.表示当前路径
[root@linux-node1 mynginx]# docker build -t mynginx:v2 .
构建完毕之后,我们就可以Run起来。
[root@linux-node1 ~]# docker run -d -p 92:80 mynginx:v2 nginx
测试访问
[root@linux-node1 mynginx]# curl http://192.168.56.11:92nginx in docker test
Dockerfile命令详解
下面我们来分别介绍下上面使用到的命令:
FROM
格式:FROM 或FROM :
MAINTAINER
格式:MAINTAINER
RUN
格式:RUN 或 RUN ["executable", "param1", "param2"]。解释:运行命令,命令较长使可以使用来换行。推荐使用上面数组的格式
CMD
格式:
CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;CMD command param1 param2 在 bin/sh 中执行,提供给需要交互的应用;CMD ["param1","param2"] 提供给ENTRYPOINT的默认参数;
解释:
CMD指定容器启动是执行的命令,每个Dockerfile只能有一条CMD命令,如果指定了多条,只有最后一条会被执行。如果你在启动容器的时候也指定的命令,那么会覆盖Dockerfile构建的镜像里面的CMD命令。
ENTRYPOINT
格式:
ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2(shell中执行)。解释:和CMD类似都是配置容器启动后执行的命令,并且不可被 docker run提供的参数覆盖。
每个 Dockerfile 中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效。ENTRYPOINT没有CMD的可替换特性,也就是你启动容器的时候增加运行的命令不会覆盖ENTRYPOINT指定的命令。
所以生产实践中我们可以同时使用ENTRYPOINT和CMD,例如:
ENTRYPOINT ["/usr/bin/rethinkdb"]CMD ["--help"]
USER
格式:USER daemon 解释:指定运行容器时的用户名和UID,后续的RUN指令也会使用这里指定的用户。
EXPOSE
格式:EXPOSE
ENV
格式:ENV
ADD
格式:ADD
所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0
如果文件是可识别的压缩格式,则docker会帮忙解压缩
VOLUME
格式:VOLUME ["/data"] 解释:可以将本地文件夹或者其他container的文件夹挂载到container中。
WORKDIR
格式:WORKDIR path/to/workdir 解释:切换目录,为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录。可以多次切换(相当于cd命令),也可以使用多个 WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:
WORKDIR aWORKDIR bWORKDIR cRUN pwd
则最终路径为 a/b/c。
ONBUILD
ONBUILD 指定的命令在构建镜像时并不执行,而是在它的子镜像中执行
ARG
格式:ARG
Docker镜像生产实践
现在我们学会了如何使用Dockerfile来构建镜像,没错,真正生产环境我们也是大规模的使用Dockerfile。那么我们应该如何入手呢?
首先我们需要参考一些别人编写的Dockerfile,学习一些规范和技巧,可以来这里找找答案:https://github.com/dockerfile。
可以参考网友编写的Dockerfile的技巧和方法,那么真正的生产环境,肯定要根据自己公司或者团队的技术栈来构建不同的Docker镜像。
Docker镜像分层构建
根据Docker镜像的分层观念,我们可以在这个基础上对我们的镜像进行分层。
系统层
运行环境层
应用服务层
示例如下:
[root@linux-node1 ~]# mkdir /opt/dockerfile[root@linux-node1 ~]# cd /opt/dockerfile/[root@linux-node1 dockerfile]# mkdir system runtime app[root@linux-node1 dockerfile]# tree.├── app├── runtime└── system
Docker镜像预热
在分层构建的基础上,在执行docker pull获取一个镜像的时候,只会下载不存在的Dokcer Image Layer,可以节约下载的时间。在实际生产工作中,一般会将通用的镜像构建完毕后,使用自动化运维工具,或者编写Shell脚本,在所有Docker节点上提前执行docker pull命令,提前把镜像下载到本地,实现镜像预热。




