本文主要讲解了Dockerfile的概念及其构建过程,详细讲解了Dockerfile保留字指令的含义和实际案例。使用实例形象的区分CMD和ENTRYPOINT两个易混淆指令并通过案例讲解ONBUILD父镜像和子镜像的关联方式。
一、是什么
1.Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。其主要由以下三个步骤构建完成(联想第八节我们探讨的使用Dockerfile的方式添加数据卷):
=>编写Dockerfile文件:手动编写一个dockerfile文件,当然,文件必须符合file的规范
=>Docker build:有了这个文件后,直接docker build命令支持,获得一个自定义的镜像
=>Docker run:run
2.以我们熟悉的centos的Dockerfile文件为例,因其最后一行添加了CMD[“/bin/bash”],所以在启动centos容器时,()中的内容可以省略:docker run -it centos (/bin/bash):
scratch:所有镜像的祖先类,原镜像
MAINTAINER:作者加邮箱
二、Dockerfile构建过程解析
1.Docker内容基础知识
=>每条保留字指令都必须为大写且后面要跟随至少一个参数,例如cenos镜像的Dockerfile文件中的FROM、MAINTAINER等
=>指令按照从上到下,顺序执行
=>每条指令都会创建一个新的镜像层,并对镜像层进行提交,可以联想第八节中,用Dockerfile新建数据卷,在docker bilud的过程中返回了四个镜像层ID
2.Docker执行Dockerfile的大致流程
(1)docker从基础镜像运行一个容器
(2)执行一条指令并对容器作出修改
(3)执行类似docker commit的操作提交一个新的镜像层
(4)docker再基于刚提交的镜像运行一个新容器
(5)执行dockerfile中的下一条指令直到所有指令都执行完成
=>一层一层执行完毕完毕后,生成我们自定义的docker镜像
补充:
三、Docker保留字指令
FROM:基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER:镜像维护者的姓名和邮箱地址
RUN:容器构建时需要运行的命令,如在redies的dockerfile中用RUN新建了用户组和用户
EXPOSE:当前容器对外暴露出的端口,暴露出该镜像变成实例对外启动后,其服务的端口号
WORKDIR:指定在创建容器后,终端默认登陆的工作目录,一个落脚点。如下图,规定容器登陆在根目录还是tmp目录上面
ENV:用来构建镜像过程中设置环境变量
如下图,规定了环境是MY_PATH,路径是/usr/mytest,WORKDIR是$MY_PATH,那么默认的登陆目录是/usr/mytest
ADD:将宿主机目录下的文件拷贝进镜像,ADD命令会自动处理URL和解压tar压缩包,ADD是拷贝加解压缩
COPY:类似ADD,拷贝文件和目录到镜像中,将从构建上下文目录中<源路径>的文件或目录复制到新的一层的镜像内的<目标路径>位置,COPY是直接拷贝,有两种写法:
shell脚本写法:COPY <源路径> <目标路径>
类似jason串的写法:COPY[“<源路径>”,“<目标路径>”]
VOLUME:容器数据卷,保存数据和持久化工作,如第八节里的新建两个容器卷
CMD:指定一个容器启动时要运行的命令,Dockerflie中可以有多个CMD指令,之前的CMD指令会执行(输出语句可以出结果),但只有最后一个生效。
ENTRYPOINT:指定一个容器启动时要运行的命令,ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数。ENTRYPOINT承认所有的命令,新增的命令会被看作为追加,CMD与ENTRYPOINT的区别下文会用案例解释
ONBUILD:当构建一个被继承的Dockerflie时运行命令,父镜像在被子继承后父镜像的ONBUILD被触发,类似于触发器
总结:Dockerfile中主流的构成镜像命令
四、用案例加深对保留字指令的理解
1.Base镜像(scratch):Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的
2.自定义镜像mycentos
(1)编写
Hub默认的CentOS镜像什么情况
准备编写Dockerfile文件,我们需要据此运行的容器具有以下功能:
对应的DockerFile内容如下:
FROM centos
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "success-----------ok"
CMD /bin/bash
(2)构建:docker build -t 新镜像名字:TAG . (别忘了build最后有个点)
(3)运行
(4)列出镜像的变更历史
docker history mycentos:1.3
顺着加载,倒着执行,有点像栈
3.CMD/ENTRYPOINT 通过镜像案例区分
Dockerfile中使用CMD,在容器run的时候后面加了参数 -i,相当于在Dockerfile文件中加了CMD -i(如下图),此时会把Dockerfile中最后一条CMD命令覆盖,因此报错:
如果将上面的CMD改成EN,就不会报错了,新的参数以追加的形式添加到上一条命令中
4.ONBUILD镜像案例
新建一个Dockerfile文件,在文件中添加ONBUILD命令如下图,基于这个Dockerfile新建一个镜像myip_father
再新建一个Dockerfile5文件如下图,第一行规定基于myip_father镜像
在基于Dockerfile5新建镜像的时候,会触发myip_father的ONBUILD命令,打印出“father images onbuild-----------886”这句话。图中的红色字样为执行了一个触发器,子类在创建的时候,父类的ONBUILD就像个倒钩刺一样,会被触发
参考资料:尚硅谷Docker视频教学