正井猫

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Dockerfile

一. Dockerfile是什么

    Dockerfile是docker中镜像文件的的描述文件,说的直白点就是镜像文件到底是由什么东西一步步构成的。例如我们在淘宝上买了一件商品,但是这个商品需要组装才能使用,于是卖家就给了你一张图纸,你就按照图纸一步一步的组装起来,然后就成了你所需要的样子。那么Dockerfile就是这张图纸,镜像文件就是你需要的商品。Dockerfile名字可以随便命名,但是不建议你这做,还是按照规范来使用,首字母要大写。下面给出我们前几个章节使用到的centos为例,来看看它的Dockerfile是怎么样的,如下图所示:     

                               

二. Dockerfile、镜像、容器

    Dockerfile:是镜像的构建文件,描述的镜像是一步步怎么来的。

  镜像:是通过Dockerfile做出来的,包含操作系统基础文件和软件运行环境,它使用分层的存储方式。

  容器:是运行起来的镜像,简单理解,Docker镜像相当于程序,容器相当于进程。

三. Dockerfile的基本语法及执行流程

3.1 Dockerfile的基本语法

   a.每个保留字必须放在每一行的开头,可以大写也可以小写,但是建议大写;

  b.指令按照顺序,从上往下依次执行;

  c.#表示注解;

  d.每条执行指令都会创建一个新的镜像,并且执行提交。

3.2 Dockerfile的执行流程

   a.docker从基础镜像中执行一个容器; 

   b.执行一条指令对镜像进行修改;

   c.执行docker commit命令,提交新的镜像;

   d.在基于刚刚提交的镜像运行一个新的容器;

   e.执行Dockerfile中的下一条指令,按照b、c、d依次循环下去,知道所有的指令执行完毕。

3.3 演示讲解

FROM centos                              #指定要生成的镜像的基础镜像,开头第一句话必须也只能是FROM
MAINTAINER  zhengjingmao@163.com         #指定作者是谁
RUN yum install -y vim                   #执行 yum install -y vim 命令,安装vim
RUN yum install -y net-tools             #执行 yum install -y net-tools, 安装net-tools工具
WORKDIR /dev/ #启动容器后,如果启动交互模式,直接进入到哪个目录 CMD [
"/bin/bash"] #启动容器的时候,进入到/bin/bash这种命令行

    如上代码所示,FROM、MAINTAINER、RUN、WORKDIR、CMD均为关键字,按照标准的规范需要大写;FROM centos表示我们的基础镜像是centos,然后会启动centos这个容器,执行第二行代码又会生成新的镜像文件,然后提交,周而复始。

四. Dockerfile关键字

关键字 作用
FROM 指定基础镜像
MAINTAINER 作者的信息
RUN 执行什么命令
EXPOSE 容器对外暴露的端口
WORKDIR 进入到容器后进入到哪个目录
ENV 配置环境变量
ADD 将文件拷贝到镜像中并解压
COPY 将文件拷贝到镜像中
VOLUME 配置数据卷
CMD 容器启动时候执行的命令
ENTRYPOINT 容器启动时候执行的命令

      a.ADD指令,我们现在定义这样一个Dockerfile,代码如下所示:

FROM centos
MAINTAINER  zhengjingmao@163.com
RUN mkdir /datas
ADD jdk-8u60-linux-x64.tar.gz /datas/
WORKDIR /datas/
CMD ["/bin/bash"]

     首先必须将jdk-8u60-linux-x64.tar.gz文件拷贝到Dockerfile同级目录下,如下图所示:

                                                        

     执行命令:docker build -t mycentos .  构建mycentos镜像,如下图所示:

                                                          

      然后启动容器,进入到 /datas/目录下,会发现 jdk1.8.0_60 目录,表示add命令还执行了解压命令,如下图所示:

                                                        

  b.COPY命令,我们定义一个Dockerfile, 代码如下:

FROM centos
MAINTAINER  zhengjingmao@163.com
RUN mkdir /datas
ADD jdk-8u60-linux-x64.tar.gz /datas/
WORKDIR /datas/
CMD ["/bin/bash"]

       执行命令:docker build -t mycentos .  构建mycentos镜像。

    然后启动容器,进入到 /datas/目录下,会看到jdk-8u60-linux-x64.tar.gz文件,并没有解压,如下图所示:

                                                       

   c.ENV命令,配置环境变量,我们还是用上面提到的jdk为例,做过Java开发的朋友都知道,jdk需要配置环境变量,Dockerfile的内容如下所示:

FROM centos                      
MAINTAINER  zhengjingmao@163.com   
RUN mkdir -p /datas/ 
ADD jdk-8u60-linux-x64.tar.gz /datas/
ENV JAVA_HOME=/datas/jdk1.8.0_60                    #配置JAVA_HOME
ENV PATH=$JAVA_HOME/bin:$PATH                       #配置PATH
CMD ["/bin/bash"]

            因为内容的重复性,在这里就不赘述了。当我们容器启动后,我们输入:java  -version命令,就能看到我们熟悉的内容了。

   d.CMD关键字,在镜像构建阶段不执行,在容器启动阶段执行(而我们的RUN关键字定义的指令在容器构建阶段就会执行,请记住它与CMD的区别)。如果一个Dockerfile中有多个CMD命令,后面的会覆盖前面的,说白了只有最后一个生效,如下代码和注释:

............省略............
CMD echo "<<<<<<<<<<<nice to meet you>>>>>>>>>>"
CMD /bin/bash
CMD echo "==========How are you?============="    #当容器启动的时候只有该行代码会执行,会将前两行代码覆盖

      CMD还有一个问题,就是当我们使用 docker run命令的时候,我们可以在整个docker命令的最后加上其他额外的命令,那么额外的命令会覆盖Dockerfile中所有的CMD命令,例如我们执行如下命令:docker run -it centos ls / -l,最终的结果如下图所示:  

                                                        

       e. ENTRYPOINT指令,和CMD命令差不多,如果一个Dockerfile中有多个ENTRYPOINT,只有最后一个生效。但是他们还是有区别的,如果ENTRYPOINT后面有CMD,当以exec的方式运行的时候,CMD的值会作为参数给ENTRYPOINT,可能很多人看到这句话不大理解,那么我们来两个例子:

  例一:  

FROM centos                      
MAINTAINER  zhengjingmao@163.com   
RUN mkdir -p /datas/ 
ENTRYPOINT ["echo", "hello"]
CMD ["world"]                           #会将world作为echo hello的参数,最后的命令其实为echo hello world 

                                                        

  例二:

FROM centos                      
MAINTAINER  zhengjingmao@163.com   
RUN mkdir -p /datas/ 
ENTRYPOINT ["echo", "hello"]

                                                       

  总结:当我们理解了CMD和ENTRYPOINT两个命令的区别后,以后在使用的过程中就不会出现各种问题了。

 

posted on 2019-07-01 00:54  正井猫  阅读(5136)  评论(0编辑  收藏  举报