Docker之使用Dockerfile指令建立映象(四)--技術流ken
前言
在之前的部落格《ofollow,noindex" target="_blank">Docker埠對映及建立映象演示(二)--技術流ken 》,演示瞭如何使用一個現有容器建立一個映象,以及映象在阿里雲的上傳和下載。
但是這樣的映象有很大的侷限性,不能根據我們的生產需要進行個性化定製,所以我們急需學習一種能夠滿足我們需要的製作映象的工具。
這個時候Dockerfile就出現了。
使用dockerfile指令可以根據自己的需要,製作滿足自己生產需要的映象。
本篇部落格將詳細講解如何使用dockerfile製作自己的專屬映象。
Dockerfile簡介
映象的定製實際上就是定製每一層所新增的配置、檔案。如果我們可以把每一層修改、安裝、構建、操作的命令都寫入一個指令碼,用這個指令碼來構建、定製映象,那麼哪些無法重複的問題、映象構建透明性的問題、體積的問題就都會解決。這個指令碼就是 Dockerfile。
Dockerfile 是一個文字檔案,其內包含了一條條的指令,每一條指令構建一層,
因此每一條指令的內容,就是描述該層應當如何構建
Dockerfile編寫注意項
- # 備註
- 指令引數,指令的大小寫不敏感
- 第一個非註釋行必須是FROM指令
- 編寫Dockerfile必須在一個目錄下進行,這個目錄稱之為 工作目錄(WORKSPACE)
- Dockerfile檔案命令的首字母必須大寫
- 製作映象所要用的檔案必須放在工作目錄或者工作目錄的子目錄之下,不能放在父目錄
- 可以通過隱藏檔案 .dockeringnore 來指定不要放入到映象中的檔案,一行是一個檔案,可以用萬用字元
- 基於dockerfile做映象,本質上還是基於一個現有的映象做新映象
Dockerfile指令詳解
1. FROM
作用:FROM 就是指定基礎映象,因此一個 Dockerfile 中 FROM 是必備的指令,並且必須是第一條指令
格式:
FROM <registry>:[tag]
FROM <registry>@<digest>
FROM 示例:
第一步:建立工作目錄及dockerfile
[root@ken ~]# mkdir /ken [root@ken ~]# cd /ken [root@ken ken]# touch Dockerfile
第二步:寫入from指令
docker.io:登錄檔
nginx:倉庫
latest:版本號
[root@ken ken]# cat Dockerfile FROM docker.io/nginx:latest
2. LABEL
作用:設定一些元資料
格式:
LABEL 資訊
LABEL示例:
LABEL author "ken"
3. COPY
作用:將工作目錄下的檔案複製到所做得映象中的檔案系統中
格式:
複製單個檔案:COPY <src> <dest>
複製多個檔案:COPY [<src> <src> <src>... <dest>]
COPY示例:
COPY passwd /data/
注意:
- 原始檔路徑用相對路徑,目標一般用絕對路徑
- 也可以萬用字元
- 原始檔必須在工作目錄或者工作目錄的子目錄中
- 目標路徑可以不存在,會自動建立
- 如果原始檔是一個目錄,會自動遞迴複製目錄下的檔案到目標位置,但是目錄自身不會複製
- 如果複製多個檔案,或者原始檔中用了萬用字元,那麼目標路徑必須以 / 為結尾
4. ADD
作用:和COPY類似,可以實現將檔案和目錄載入映象中,但是區別是可以實現將tar 包解壓,也可以實現從網路下載檔案到映象
注意:下載的tar無法解壓
格式
ADD <src> <dest>
ADD ["<src>" "<src>" "<src>" "<dest>"]
ADD示例:
ADD nginx-1.14.0.tar.gz /data/
5. WORKDIR
作用:相當於執行cd命令。切換目錄,為後續的RUN、CMD、ENTRYPOINT 指令配置工作目錄。
格式:
WORKDIR 容器目錄
WORKDIR示例:
WORKDIR /pack/nginx/
6. VOLUME
作用:指定資料卷的掛載點
格式:
VOLUME 容器目錄
VOLUME示例:
VOLUME /data/mysql/mysql3306/data
7. EXPOSE
作用:設定Docker容器內部暴露的埠號,如果需要外部訪問,還需要啟動容器時增加-p或者-P引數進行分配。
格式:
EXPOSE PORT/[PROTOCOL]
EXPOSE示例:
EXPOSE 80/tcp
9. ENV
作用:設定環境變數
格式:
ENV var value
ENV var1=value1 var2=value2 ...
注意:
通過ENV所定義的變數是可以傳遞到容器之中,但是,在建立容器的時候,如果手動指定了變數的值,那麼這個值會覆蓋掉映象中原有的值
ENV示例:
ENVpkgname=nginx-1.14.0.tar.gz root=/data/mysql/mysql3306/data
10. RUN
作用:基於映象構建容器時候要執行命令
階段:第一階段,也就是構建映象的時候執行
格式:
RUN 命令
RUN示例:
RUN tar xf $root$pkgname
11. CMD
作用:定義容器啟動以後要預設執行的程式,pid為1 的程式
階段:第二階段,也就是將映象構成成容器的時候執行
注意:可以在啟動容器的時候用指定的命令替換掉映象所要執行的命令
CMD指定容器啟動是執行的命令,每個Dockerfile只能有一條CMD命令,如果指定了多條,只有最後一條會被執行。如果你在啟動容器的時候也指定的命令,那麼會覆蓋Dockerfile構建的映象裡面的CMD命令
格式:
CMD <命令> 相當於執行的是/bin/sh -c 命令,也相當於執行exec 來執行命令
CMD ["<命令>", "< 引數>", "< 引數>"]
CMD ["<引數>", "< 引數>"] <<< 需要藉助於ENTRYPOINT 指令
CMD示例:
CMD mkdir /ken
12. ENTRYPOINT
作用:定義容器啟動以後要預設執行的程式,pid為1 的程式
注意:
在執行RUN的時候所執行的命令無法覆蓋ENTRYPOINT 中的命令
RUN 後面的命令會被以引數的方式追加到原本要執行的命令的末尾,而不是替換
基於一個映象,在建立容器的時候,通過傳遞不同的引數實現建立不同的容器
每個 Dockerfile 中只能有一個 ENTRYPOINT,當指定多個時,只有最後一個起效
格式:
ENTRYPOINT ["執行命令","引數1","引數2"...]
ENTRYPOINT示例:
ENTRYPOINT [ "curl", "-s", "http://10.220.5.138" ]
13. ARG
作用:定義變數,這個變數是用在第一階段(構建映象——build )
格式:
ARG 變數名=變數值
ARG示例:
ARG name=ken
補充:Dockerfile中ENV 和 ARG的區別
在指定docker build 過程中傳引數,要用ARG
在執行docker run的過程中傳引數,要用ENV
ARG構建引數和 ENV 的效果一樣,都是設定環境變數。所不同的是, ARG 所設定的構建環境的
環境變數,在將來容器執行時是不會存在這些環境變數的
14. USER
作用:指定執行容器時的使用者名稱和UID,後續的RUN指令也會使用這裡指定的使用者
該使用者必須存在於容器的使用者空間中(容器的檔案系統的中的/etc/passwd中)
格式:
USER <UID>|<USERNAME>
USER示例:
user ken
15. HEALTHCHECK
作用:docker daemon檢查 docker 容器是否正常,如果異常會將該容器 stop
將容器 stop的條件
1)主程序停止了
2)主程序工作在了後臺
格式:
HEALTHCHECK [options] CMD
options
--interval=#s|m 指定健康檢查的時間間隔(例如:30s,30m)
--timeout=#s|m 指定等待響應的超時時間
--start-period=#s|m 指定容器啟動多久以後才可以做監控檢查
--retries=# 指定重試次數
返回值
0: success
1: unhealth
HEALTHCHECK示例:
HEALTHCHECK --interval=5m --timeout=1s --retries=3 CMD curl http://10.220.5.138/ken.html || exit 1
16. SHELL
可以用來指定系統中預設的shell型別
格式:
SHELL ["/bin/sh", "-c"] (linux系統中)
SHELL示例:
SHELL ["/bin/sh","-c"]
17. STOPSIGNAL
向容器中pid為1 的程序傳送一個訊號,通過這個訊號來關閉這個主程序
預設是15訊號
格式:
STOPSIGNAL 數值
STOPSIGNAL示例:
STOPSIGNAL 9
18. ONBULID
作用:定義一個觸發器,指定的命令在構建映象時並不執行,用來實現當基於這個這個映象做新映象的時候要執行的命令
格式:
ONBUILD 其他指令
ONBUILD示例:
ONBUILD COPY ken /app/
Dokcerfile完整演示建立nginx映象
根據上面各個指令的介紹,我就直接用上面寫的dockerfile進行演示。整個dockerifle內容如下。
[root@ken ~]# vim /ken/Dockerfile FROM docker.io/nginx:latest LABEL author "ken" COPY ./passwd /data/ WORKDIR /pack/nginx/ ENVpkgname=nginx-1.14.0.tar.gzroot=/data/mysql/mysql3306/data/ COPY nginx-1.14.0.tar.gz $root VOLUME $root EXPOSE 80/tcp RUN tar xf $root$pkgname CMD nginx -g "daemon off;"
第一步:構建映象
build:是指根據dockerfile製作映象
-t:指定一個tag標籤
.:表示上下文。你也可以理解為dockfile所在的目錄,但是並不是準確的
如果下方出現successfully就表示映象已經構建成功了
[root@ken ken]# docker build -t ken:v1-0 . Sending build context to Docker daemon 1.021 MB Step 1/10 : FROM docker.io/nginx:latest ---> 568c4670fa80 Step 2/10 : LABEL author "ken" ---> Using cache ---> 80e4e5846fd9 Step 3/10 : COPY ./passwd /data/ ---> Using cache ---> 685a7ceb74b3 Step 4/10 : WORKDIR /pack/nginx/ ---> Using cache ---> 0fc65f8c36df Step 5/10 : ENV pkgname nginx-1.14.0.tar.gz root /data/mysql/mysql3306/data/ ---> Using cache ---> 3f6038473472 Step 6/10 : COPY nginx-1.14.0.tar.gz $root ---> Using cache ---> 0cbff6223d5b Step 7/10 : VOLUME $root ---> Using cache ---> b74ac1c36c31 Step 8/10 : EXPOSE 80/tcp ---> Using cache ---> 6863a87a61a2 Step 9/10 : RUN tar xf $root$pkgname ---> Using cache ---> b32ac636a389 Step 10/10 : CMD nginx -g "daemon off;" ---> Running in 02308825301d ---> 4a91d70a57eb Removing intermediate container 02308825301d Successfully built 4a91d70a57eb
第二步:檢視映象
可以發現構建的名為ken標籤為v1-0的映象已經存在了
[root@ken ken]# docker image ls REPOSITORYTAGIMAGE IDCREATEDSIZE kenv1-04a91d70a57eb21 minutes ago116 MB
第三步:啟動容器
可以發現基於我們剛才的建立的映象的容器已經順利跑起來了。
[root@ken ken]# docker run -d --name ken3 -d ken:v1-0 11f492a28b943e619b0ed5d6b19f212f1c9cc47f9bdbe132845e7a7129e5b419 [root@ken ken]# docker container ps CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 11f492a28b94ken:v1-0"/bin/sh -c 'nginx..."16 seconds agoUp 11 seconds80/tcpken3
第四步:登入容器
可以發現我們這個啟動的容器裡面已經有我們指定的工作目錄
複製過來的passwd檔案
已經下載並傳送到/data下了
[root@ken ken]# docker exec -it ken3 bash root@11f492a28b94:/pack/nginx# ls /data/ mysql/passwd root@11f492a28b94:/pack/nginx# ls /data/ mysql/passwd oot@11f492a28b94:/pack/nginx# ls /data/mysql/mysql3306/data/nginx-1.14.0.tar.gz /data/mysql/mysql3306/data/nginx-1.14.0.tar.gz
這樣基於dockerfile自主建立映象的過程就演示完了,快去自己製作一個屬於自己的映象吧。