1. 程式人生 > 其它 >第6章 DockerFile解析

第6章 DockerFile解析

1.1 是什麼

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

2.構建三步驟

● 編寫Dockerfile檔案

● docker build

● docker run

3.檔案什麼樣???

以我們熟悉的CentOS為例 

https://hub.docker.com/_/centos/

 

1.2 DockerFile構建過程解析

1.2.1 Dockerfile內容基礎知識

1:每條保留字指令都必須為大寫字母且後面要跟隨至少一個引數

2:指令按照從上到下,順序執行

3:#表示註釋

4:每條指令都會建立一個新的映象層,並對映象進行提交

1.2.2 Docker執行Dockerfile的大致流程

(1)docker從基礎映象執行一個容器

(2)執行一條指令並對容器作出修改

(3)執行類似docker commit的操作提交一個新的映象層

(4)docker再基於剛提交的映象執行一個新容器

(5)執行dockerfile中的下一條指令直到所有指令都執行完成

1.2.3 小總結

從應用軟體的角度來看,Dockerfile、Docker映象與Docker容器分別代表軟體的三個不同階段,
*  Dockerfile是軟體的原材料
*  Docker映象是軟體的交付品
*  Docker容器則可以認為是軟體的執行態。
Dockerfile面向開發,Docker映象成為交付標準,Docker容器則涉及部署與運維,三者缺一不可,合力充當Docker體系的基石。

1 Dockerfile,需要定義一個Dockerfile,Dockerfile定義了程序需要的一切東西。Dockerfile涉及的內容包括執行程式碼或者是檔案、環境變數、依賴包、執行時環境、動態連結庫、作業系統的發行版、服務程序和核心程序(當應用程序需要和系統服務和核心程序打交道,這時需要考慮如何設計namespace的許可權控制)等等;
 
2 Docker映象,在用Dockerfile定義一個檔案之後,docker build時會產生一個Docker映象,當執行 Docker映象時,會真正開始提供服務;
 
3 Docker容器,容器是直接提供服務的。

 

 

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

1. FROM:基礎映象,當前新映象是基於哪個映象的

2. MAINTAINER:映象維護者的姓名和郵箱地址

3. RUN:容器構建時需要執行的命令

4. EXPOSE:當前容器對外暴露出的埠

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

6.ENV:用來在構建映象過程中設定環境變數

ENV MY_PATH /usr/mytest
這個環境變數可以在後續的任何RUN指令中使用,這就如同在命令前面指定了環境變數字首一樣;
也可以在其它指令中直接使用這些環境變數,
 
比如:WORKDIR $MY_PATH

7.ADD:將宿主機目錄下的檔案拷貝進映象且ADD命令會自動處理URL和解壓tar壓縮包

8.COPY:

類似ADD,拷貝檔案和目錄到映象中。
將從構建上下文目錄中 <源路徑> 的檔案/目錄複製到新的一層的映象內的 <目標路徑> 位置

9.VOLUME:容器資料卷,用於資料儲存和持久化工作

10.CMD:指定一個容器啟動時要執行的命令

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

11.ENTRYPOINT :指定一個容器啟動時要執行的命令

ENTRYPOINT 的目的和 CMD 一樣,都是在指定容器啟動程式及引數

12.ONBUILD:當構建一個被繼承的Dockerfile時執行命令,父映象在被子繼承後父映象的onbuild被觸發

 

1.4 案例

1.4.1 Base映象(scratch)

Docker Hub 中 99% 的映象都是通過在 base 映象中安裝和配置需要的軟體構建出來的

1.4.2 自定義映象mycentos

1.編寫

● Hub預設CentOS映象什麼情況

自定義mycentos目的使我們自己的映象具備如下:
         登陸後的預設路徑
         vim編輯器
         檢視網路配置ifconfig支援

● 準備編寫DockerFile檔案

● myCentOS內容DockerFile

FROM centosMAINTAINER zzyy<[email protected]>
ENV MYPATH /usr/localWORKDIR $MYPATH
RUN yum -y install vimRUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATHCMD echo "success--------------ok"CMD /bin/bash 

2.構建

docker build -t 新映象名字:TAG .

會看到 docker build 命令最後有一個 .                                   . 表示當前目錄

3.執行

docker run -it 新映象名字:TAG 

可以看到,我們自己的新映象已經支援vim/ifconfig命令,擴充套件成功了。

4.列出映象的變更歷史

docker history 映象名

1.4.3 CMD/ENTRYPOINT 映象案例

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

● CMD

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

Case:tomcat的講解演示:docker run -it -p 8888:8080 tomcat ls -l

● ENTRYPOINT 

docker run 之後的引數會被當做引數傳遞給 ENTRYPOINT,之後形成新的命令組合

Case

  ▶製作CMD版可以查詢IP資訊的容器: FROM centosRUN yum install -y curlCMD [ "curl", "-s", "http://ip.cn" ]

  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

 

  ▶問題:如果我們希望顯示 HTTP 頭資訊,就需要加上 -i 引數

  ▶WHY:

  我們可以看到可執行檔案找不到的報錯,executable file not found。
  之前我們說過,跟在映象名後面的是 command,執行時會替換 CMD 的預設值
  因此這裡的 -i 替換了原來的 CMD,而不是新增在原來的 curl -s http://ip.cn 後面。而 -i 根本不是命令,所以自然找不到。
 
  那麼如果我們希望加入 -i 這引數,我們就必須重新完整的輸入這個命令:
 
  $ docker run myip curl -s http://ip.cn -i

  ▶製作ENTROYPOINT版查詢IP資訊的容器:

  FROM centos
  RUN yum install -y curl
  ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]

 

1.4.3 自定義映象Tomcat9

1.mkdir -p /zzyyuse/mydockerfile/tomcat9

2.在上述目錄下touch c.txt

3.將jdk和tomcat安裝的壓縮包拷貝進上一步目錄

apache-tomcat-9.0.8.tar.gz

jdk-8u171-linux-x64.tar.gz

4.在/zzyyuse/mydockerfile/tomcat9目錄下新建Dockerfile檔案

 FROM         centosMAINTAINER    zzyy<[email protected]>#把宿主機當前上下文的c.txt拷貝到容器/usr/local/路徑下COPY c.txt /usr/local/cincontainer.txt#把java與tomcat新增到容器中ADD jdk-8u171-linux-x64.tar.gz /usr/local/ADD apache-tomcat-9.0.8.tar.gz /usr/local/#安裝vim編輯器RUN yum -y install vim#設定工作訪問時候的WORKDIR路徑,登入落腳點ENV MYPATH /usr/localWORKDIR $MYPATH#配置java與tomcat環境變數ENV JAVA_HOME /usr/local/jdk1.8.0_171ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin#容器執行時監聽的埠EXPOSE  8080#啟動時執行tomcat# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ]# CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out

5.構建

6.run

 docker run -d -p 9080:8080 --name myt9 -v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test -v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs --privileged=true zzyytomcat9

備註:

Docker掛載主機目錄Docker訪問出現cannot open directory .: Permission denied
解決辦法:在掛載目錄後多加一個--privileged=true引數即可

7.驗證

8.結合前述的容器卷將測試的web服務test釋出

● 總體概述

● web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  id="WebApp_ID" version="2.5">
  
  <display-name>test</display-name>
 
</web-app>

● a.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
  </head>
  <body>
    -----------welcome------------
    <%="i am in docker tomcat self "%>
    <br>
    <br>
    <% System.out.println("=============docker tomcat self");%>
  </body>
</html>

● 測試