第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>
● 測試