docker系列七之Dockerfile


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兩個命令的區別后,以后在使用的過程中就不會出現各種問題了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM