1. 程式人生 > >Docker基礎 6.DockerFile

Docker基礎 6.DockerFile

Docker基礎

@Author:hanguixian
@Email:[email protected]

Docker文件:https://docs.docker.com/

Dcker中文文件:https://docs.docker-cn.com/


六.DockerFile

1.是什麼

  • Dockerfile是用來構建Docker映象的構建檔案, 是由一系列命令和引數構成的指令碼。

  • 構建三步驟

    • 1.編寫DokcerFile檔案
    • 2.docker build
    • 3.docker run
  • 檔案什麼樣?

    FROM scratch
    MAINTAINER https://github.com/CentOS/sig-cloud-instance-images
    ADD centos-7-docker.tar.xz /
    
    LABEL name="CentOS Base Image" \
      vendor="CentOS" \
      license="GPLv2" \
      build-date="20161214"
    
    CMD ["/bin/bash"]

2.DockerFile構建過程解析

  • Dockerfile內容基礎知識

    • 每條保留字指令都必須為大寫字母且後面要跟隨至少一個引數\
    • 指令按照從上到下,順序執行
    • #表示註釋
    • 每條指令都會建立一個新的映象層,並對映象進行提交
  • docker執行Dockerfile的大致流程

    • (1) docker從基礎映象執行一個容器
    • (2)執行一條指令並對容器作出修改
    • (3) 執行類似docker commit的操作提交一個新的映象層
    • (4) docker再基於剛提交的映象執行一個新容器
    • (5) 執行dockerfile中的下一條指令直到所有指令都執行完成
  • 總結

    • 從應用軟體的角度來看,Dockerfile、 Docker映象與Docker容器分別代表軟體的三個不同階段

    • Dockerfile是軟體的原材料Docker映象是軟體的交付品

    • Docker容器則可以認為是軟體的執行態。

    • Dockerfile面向開發,Docker映象成為交付標準,Docker容器則涉及部署與運維,三者缺一不可,合力充當Docker體系的基石。

      dockerfile1

    • 1 Dockerfile, 需要定義一個Dockerfile, Dockerfile定義了程序需要的一切東西。Dockerfile涉及的內容包括執行程式碼或者是檔案、環境變數、依賴包、執行時環境、動態連結庫、作業系統的發行版、服務程序和核心程序(當應用程序需要和系統服務和核心程序打交道,這時需要考慮如何設計namespace的許可權控制)等等;

    • 2 Docker映象,在用Dockerfile定義一個檔案之後,docker build時會產生一個Docker映象, 當執行Docker映象時,會真正開始提供服務;
    • 3 Docker容器,容器是直接提供服務的。

3.DockerFile體系結構(保留字指令)

  • FROM 基礎映象,當前新映象是基於哪個映象的

  • MAINTAINER 映象維護者的姓名和郵箱地址

  • RUN 容器構建時需要執行的命令

  • EXPOSE 當前容器對外暴露出的埠

  • WORKDIR 指定在建立容器後,終端預設登陸的進來工作目錄,一個落腳點

  • ENV 用來在構建映象過程中設定環境變數口

    • ENV MY_ PATH /usr/mytest 這個環境變數可以在後續的任何RUN指令中使用,這就如同在命令前面指定了環境變數字首一樣; 也可以在其它指令中直接使用這些環境變數, 比如: WORKDIR $MY_ PATH
  • ADD 將宿主機目錄下的檔案拷貝進映象且ADD命令會自動處理URL和解壓tar壓縮包

  • COPY

    • 類似ADD,拷貝檔案和目錄到映象中。
    • 將從構建上下文目錄中<源路徑>的檔案/目錄複製到新的一層的映象內的<目標路徑>位置
      • COPY src dest COPY
      • COPY [“sre”, “dest”]
  • VOLUME 容器資料卷,用於資料儲存和持久化工作

  • CMD

    • 指定一個容器啟動時要執行的命令
    • CMD容器啟動命令:CMD指令的格式和RUN相似,也是兩種格式
      • shell 格式: CMD<命令>
      • exec 格式: CMD [“可執行檔案”,”引數1”,”引數2”,…]
      • 引數列表: CMD [“引數1”,”引數2”,..] ,在指定了ENTRYPOINT指令後,用CMD指定具體的引數
    • Dockerfile中可以有多個CMD指令,但只有最後一個生效,CMD會被docker run之後的引數替換
  • ENTRYPOINT

    • 指定一個容器啟動時要執行的命令
    • ENTRYPOINT的目的和CMD一樣,都是在指定容器啟動程式及引數
  • ONBUILD 當構建一個被繼承的Dockerfle時執行命令,父映象在被子繼承後父映象的onbuild被觸發

  • 總結

    dockerFile保留字

4.案例

4.1Base映象scratch

  • Dokcer hub中99%的映象都是在base映象中安裝和配置需要的軟體構建出來的

4.2自定義映象mycentos

  • 編寫

    • Hub預設Centos映象什麼情況

    • 初始化centos執行該映象進入是預設路徑是/

    • 預設不支援vim
    • 預設不支援ifconfig

    • 準備編寫DokcerFile檔案

    • 自定義mycentos目的,使我們的自己的映象具備如下:

      • 登陸後的預設路徑
      • vim編輯器
      • ifconfig查詢網路配置
    • 建立檔案並編輯: vim DockerFile2

    • myCentOS內容DokcerFile

    FROM centos
    MAINTAINER hanguixian<[email protected]163.com>
    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
    
  • 構建

    • 命令: docker build -f /mydocker/DockerFile2 -t mycentos:1.3 .

    • 檢視: docker images

    [root@iZuf64yofkbhp8tm0ackshZ mydocker]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
    mycentos            1.3                 d70dd7d1c9d0        About a minute ago   371MB
    centos              latest              5182e96772bf        3 weeks ago          200MB
    
    • 可以看到有了mycentos映象,同時和原來的centos映象大小有了明顯的區別
  • 執行

    • 命令: dcoker run -it mycnetos:1.3
    [[email protected] mydocker]# docker run -it mycentos:1.3
    [[email protected]9f936361751f local]# pwd
    /usr/local
    
    • 可以看到預設的路徑是:/usr/local

    • 驗證vim,ifconfig,可以看到我們修改的映象

  • 列出映象的變更歷史

    • 命令 : docker history 映象名或映象IMAGE ID

    • 例子:docker history d70dd7d1c9d0 或 docker history mycentos:1.3

[[email protected] mydocker]# docker history mycentos:1.3
IMAGE               CREATED             CREATED BY                                      SIZE
d70dd7d1c9d0        25 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B         
fa82ffb7c68b        25 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B         
353215faa466        25 minutes ago      /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B         
34a9a9b7c41d        25 minutes ago      /bin/sh -c #(nop)  EXPOSE 80                    0B         
8803a34e02ea        25 minutes ago      /bin/sh -c yum -y install net-tools             22.4MB     
0effdb62c656        25 minutes ago      /bin/sh -c yum -y install vim                   149MB       
5a83aca44197        25 minutes ago      /bin/sh -c #(nop) WORKDIR /usr/local            0B         
e8b15471d355        26 minutes ago      /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B         
d99ee0589704        26 minutes ago      /bin/sh -c #(nop)  MAINTAINER hanguixian<hn_…   0B         
5182e96772bf        3 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B         
<missing>           3 weeks ago         /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B         
<missing>           3 weeks ago         /bin/sh -c #(nop) ADD file:6340c690b08865d7e…   200MB

4.3CMD/ENTRYPOINT 映象案例

  • 都是指定一個容器啟動時要執行的命令

  • CMD

    • Dockerfile中可以有多個CMD指令,但只有最後一個生效,CMD會被docker run之後的引數替換

    • 如tomcat:dockerfile最後有: CMD ["catalina.sh", "run"]

    • 我們用: docker run -it -p 7777:80 tomcat 能啟動tomcat,可以看到列印的日誌

    • 如果使用: docker run -it -p 7777:80 tomcat ls -l tomcat沒有啟動起來

      [[email protected] mydocker]# docker run -it -p 7777:80 tomcat ls -l
      total 152
      -rw-r----- 1 root root  19533 Aug 12 08:23 BUILDING.txt
      -rw-r----- 1 root root   6090 Aug 12 08:23 CONTRIBUTING.md
      -rw-r----- 1 root root  57092 Aug 12 08:23 LICENSE
      -rw-r----- 1 root root   1726 Aug 12 08:23 NOTICE
      -rw-r----- 1 root root   3255 Aug 12 08:23 README.md
      -rw-r----- 1 root root   7140 Aug 12 08:23 RELEASE-NOTES
      -rw-r----- 1 root root  16262 Aug 12 08:23 RUNNING.txt
      drwxr-x--- 2 root root   4096 Aug 23 00:47 bin
      drwx--S--- 2 root root   4096 Aug 12 08:23 conf
      drwxr-sr-x 3 root staff  4096 Aug 23 00:47 include
      drwxr-x--- 2 root root   4096 Aug 23 00:47 lib
      drwxr-x--- 2 root root   4096 Aug 12 08:20 logs
      drwxr-sr-x 3 root staff  4096 Aug 23 00:47 native-jni-lib
      drwxr-x--- 2 root root   4096 Aug 23 00:47 temp
      drwxr-x--- 7 root root   4096 Aug 12 08:21 webapps
      drwxr-x--- 2 root root   4096 Aug 12 08:20 work
      [[email protected] mydocker]# docker ps
      CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES
      
      • 相當於: CMD ["catalina.sh", "run"]ls -l替換掉了
      CMD ["catalina.sh", "run"]
      CMD ls -l
  • ENTRYPOINT

    • docker run 之後的引數會被稻作引數傳遞給ENTRYPOINT,之後形成新的命令組合
    • Case
    • crul命令解釋:

      • curl命令可以用來執行下載、傳送各種HTTP請求,指定HTTP頭部等操作。
      • 如果系統沒有curl可以使用yum install curl安裝,也可以下載安裝。
      • curl是將下載檔案輸出到stdout
      • 使用命令: curl http://www.baidu.com 執行後,www.baidu.com的html就會顯示在螢幕上了.這是最簡單的使用方法。用這個命令獲得了http://curl.haxx.se指向的頁面.
      • 如果這裡的URL指向的是一個檔案或者一幅圖都可以直接下載到本地。如果下載的是HTML文件,那麼預設的將只顯示檔案頭部,即HTML文件的header。要全部顯示,請加引數-i
    • 製作CMD版可以查詢ip資訊的容器

      • vim DockerFile3
      FROM centos
      RUN yum install -y curl
      CMD ["curl","-s","http://ip.cn"]
      • 構建 docker build -f /mydocker/DockerFile3 -t myip .
      [email protected] mydocker]# docker build -f /mydocker/DockerFile3 -t myip .
      Sending build context to Docker daemon  4.096kB
      Step 1/3 : FROM centos
      ---> 5182e96772bf
      Step 2/3 : RUN yum install -y curl
      ---> Running in c50d2b39b009
      Loaded plugins: fastestmirror, ovl
      Determining fastest mirrors
      * base: ftp.sjtu.edu.cn
      * extras: ftp.sjtu.edu.cn
      * updates: ftp.sjtu.edu.cn
      Package curl-7.29.0-46.el7.x86_64 already installed and latest version
      Nothing to do
      Removing intermediate container c50d2b39b009
      ---> bcb77c235890
      Step 3/3 : CMD ["curl","-s","http://ip.cn"]
      ---> Running in 9a8447179feb
      Removing intermediate container 9a8447179feb
      ---> 4780e697e548
      Successfully built 4780e697e548
      Successfully tagged myip:latest
      • 執行: docker run myip
      • 輸出: 當前 IP:xxxx 來自:xxxxx
    • 問題

      • 如果要顯示Http頭資訊,就需要加上引數 -i
    • WHY

      • 執行docker run myip -i ,相當於在 CMD ["curl","-s","http://ip.cn"]後面,加上 CMD -i
      • 我們可以看到可執行檔案找不到的報錯,executable file not found。跟在映象名後面的是command,執行時會替換CMD的預設值。
      • 因此這裡的-i替換了原來的CMD,而不是新增在原來的curl -s http://ip.cn後面。而-i根本不是命令,所以自然找不到。
      • 那麼如果我們希望加入-i這引數,我們就必須重新完整的輸入這個命令:
        • docker run myip curl -s http://ip.cn -i
    • 製作ENTRYPOINT版可以查詢ip資訊的容器

      • vim DockerFile4
      FROM centos
      RUN yum install -y curl
      ENTRYPOINT ["curl","-s","http://ip.cn"]
      • 構建 docker build -f /mydocker/DockerFile4 -t myip2
      • 執行 dokcer run myip2 -i
      [r[email protected] mydocker]# docker run myip2 -i
      HTTP/1.1 200 OK
      Date: Tue, 28 Aug 2018 04:28:37 GMT
      Content-Type: text/html; charset=UTF-8
      Transfer-Encoding: chunked
      Connection: keep-alive
      Set-Cookie: __cfduid=d762232cds1acd1cd4328e662d6dbb13990ede35430517; expires=Wed, 28-Aug-19 04:28:37 GMT; path=/; domain=.ip.cn; HttpOnly
      Server: cloudflare
      CF-RAY: 4we9e87vv8b63c5426-LAX
      
      當前 IP:xxxxx 來自:xxxx
      

4.4 ONBUILD

  • 當構建一個被繼承的Dockerfle時執行命令,父映象在被子繼承後父映象的onbuild被觸發了

  • 例子:

    • vim Dockerfile_father
    FROM centos
    RUN yum install -y curl
    ENTRYPOINT ["curl","-s","http://ip.cn"]
    ONBUILD RUN echo "father  onbuild ....."
    • docker build -f /mydocker/Dockerfile_father -t myip_father .

    • vim Dockerfile_son

      FROM myip_father
      RUN yum install -y curl
      ENTRYPOINT ["curl","-s","http://ip.cn"]
    • docker build -f /mydocker/Dockerfile_son -t myip_son .

      • 會有下面這句話,可以看到ONBUILD被觸發
      
      # Executing 1 build trigger
      
      ---> Running in f3e46b30c6fa
      father  onbuild .....
      

4.5自定義映象Tomcat8

  • 準備
    • 在 /mydocker: touch hgxDockerFile
    • vim c.txt
    • 下載java8和tomcat8.5到/mydocker下:
[[email protected] mydocker]# ll
total 190728
-rw-r--r-- 1 root root   9621331 Aug 28 17:28 apache-tomcat-8.5.33.tar.gz
-rw-r--r-- 1 root root        17 Aug 28 17:49 c.txt
-rw-r--r-- 1 root root      1048 Aug 28 18:01 hgxDockerFile
-rw-r--r-- 1 root root 185646832 Aug 28 17:30 jdk-8u181-linux-x64.tar.gz
  • dockerfile編寫:
FROM centos
MAINTAINER  hanguixian<hn_hanguixian@163.com>
#把宿主機當前上下文的c.txt拷貝到容器/usr/local/路徑下
COPY c.txt /usr/local/cincontainer.txt
#把java與tomcat新增到容器中
ADD jdk-8u181-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.33.tar.gz /usr/local/
#安裝vim編輯器
RUN yum -y install vim
#設定工作訪問時候的WORKDIR路徑,登入落腳點
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java與tomcat環境境變數
ENV JAVA_HOME /usr/local/jdk1.8.0_181
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.33
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.33
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器執行時監聽的埠
EXPOSE 8080
#啟動時執行tomcat
#ENTRYPOINT「"/usr/local/apache-tomcat-8.5.33/bin/startup.sh"]
#CMD["/usr/local/apache-tomcat-8.5.33/bin/catalina.sh","run"l
CMD /usr/local/apache-tomcat-8.5.33/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.33/logs
catalina.out
  • 構建 : docker build -f hgxDockerFile -t hgxtomcat8 .
  • 執行:
docker run -d -p 8888:8080 --name myt8 -v /hanguixian/mydockerfile/tomcat8/test:/usr/local/apache-tomcat-8.5.33/webapps/test -v /hanguixian/mydockerfile/tomcat8/tomcat8logs/:/usr/local/apache-tomcat-8.5.33/logs --privileged=true hgxtomcat8 
  • 可以看到有tomcat啟動:

    tomcatUI

  • 結合前面的容器卷將測試web服務test釋出

    • 在 /hanguixian/mydockerfile/tomcat8/test下:

    • vim index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>docker test</title>
      </head>
      <body>
       <%= "I am docker tomcat self" %>
       <h2>釋出一個docker jsp</h2>
       <% System.out.println("docker tomcat self"); %>
      </body>
    </html>
    
    • mkdir WEB-INF

      • cd WEB-INF
      • vim web.xml
      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
      </web-app>
      
    • 訪問 : xxxx:8888/test/index.jsp

5.總結

dockerFile解析