前言
hello,大家好 ,我是郎同學,一個想要每天博學一點點的小青年。
最近幾天,項目超忙,忙什么呢,一方面是忙著項目的第三輪發測,另一方面是忙著給項目組的后端服務上云,作為一名后端開發工程師,寫了一周的Shell腳本,哎呀,那個酸爽哦,我還想在回味一次。
最令我惡心的是,公司自研的容器云平臺一點都不穩定(聽說容器云小組要把底層語言java轉成Go,導致近一段時間都不怎么維護容器云平臺了)。在容器云平臺構建鏡像時常常因為拉取jar包超時而導致構建失敗,當我好不容易構建完成,最終來到各類應用服務,中間件編排時,還需要對各類依賴關系、端口、IP一一進行環境變量的配置,真的是欲仙欲死,欲罷不能。
但是,經過這次項目,我的shell編程能力達到了前所未有的高度(雖然在外人眼中依舊很菜)。
寫的最多無非是Dockerfile,以前總覺得Dockerfile構建鏡像很牛逼,寫多了就發現來來回回那幾個命令,難的是shell編程中的反人類語法,今天下班早,我就總結下Dockerfile的知識點,希望可以幫助到大家。
1、Dockerfile原理
在學習Dokcerfile前,我們需要了解下Dockerfile、Docker鏡像及Dcoker容器間的關系。
容器化
Docker的核心思想就是將應用容器化。
應用容器化通常分為以下幾個步驟:
(1)編寫應用代碼
(2)編寫Dokcerfile腳本,該腳本包含當前應用的描述、依賴以及該如何運行這個應用
(3)對Dockerfile腳本執行docker image build命令,構建鏡像
(4)構建完成的鏡像被使用,完成容器化的過程
因此,編寫優秀的Dockerfile文件對構建鏡像必不可少。
DockerFile是由一系列命令和參數,用以構建docker鏡像的文件,docker能夠讀取Dockerfile指定的指令自動構建,從上到下的每一個指令都會創建一個鏡像層,即鏡像都是多層疊加而成,因此,層越多,效率越低,創建鏡像,層越少越好。因此能在一個指令完成的動作盡量通過一個指令定義。
在Dokcerfile編寫指令的過程中,需要先確定制作鏡像的目錄,即包含Dockerfile文件所在的目錄通常稱為構建上下文。
NOTE:Dockerfile文件必須以字母D開頭。
下面,就讓我們在學習Dockerfile命令過程中理解鏡像的構建。
2、Dockerfile常用命令
我們先看一個Dockerfile的指令表
指令 | 作用 |
---|---|
FROM | 構建鏡像使用的基礎鏡像 |
MAINTAINER | 設置鏡像的作者 |
RUN | 編譯鏡像時需要運行的指令 |
CMD | 鏡像的啟動命令 |
LABEL | 設置鏡像的啟動標簽 |
EXPOSE | 設置鏡像暴露的端口 |
ENV | 設置容器的環境變量 |
ADD | 編譯鏡像時復制文件到鏡像中 |
COPY | 編譯鏡像時復制文件到鏡像中(與ADD命令有區別) |
ENTRYPOINT | 容器的入口程序 |
VOLUME | 設置容器的掛載卷 |
USER | 執行命令的用戶名 |
WORKDIR | 進入容器的目錄 |
ARG | 編譯鏡像時加入的參數 |
指令看起來很多,其實理解起來并不難,下面,我們對這些指令一一作出解釋
2.1 FROM
每個Dockerfile文件的第一行都是FROM指令,FROM指令指定的鏡像都會作為當前鏡像的基礎鏡像層。
使用格式:
-
FROM
#默認最新版的鏡像
-
FROM
[:
]#指定tag版本鏡像 -
FROM
[@
]#使用加密后的摘要獲取鏡像
2.2 MAINTAINER
該指令用于確定維護該鏡像的作者信息
使用格式為:
- MAINTAINER<name>
目前這個指令已經廢棄了,可以使用指令LABEL
- LABELuser="simon"key2="value2"
多個信息可以使用多個鍵值對表示
2.3 RUN
RUN命令為構建鏡像時指令的命令
使用格式:
-
RUN
- RUN["executable","param1","param1"]
第一種格式在在shell終端中運行,即/bin/sh -c(默認);
NOTE: bash與bash -c
bash -c后面接執行的命令
bash后面接可執行的腳本
第二種格式類似于函數調用,可以將executable理解為可執程序,后面就是兩個參數
舉個例子:
- RUNyuminstall-yvim
- RUN["/bin/bash","-c","yuminstall-yvim"]
每條RUN指定將在當前鏡像基礎上執行指定命令,并提交為新的鏡像,當命令較長時,可以使用\來換行
2.4 CMD
CMD命令為容器啟動時要運行的命令
使用格式:
- CMD["executable","param1","param2"]
- CMD["param1","param2"]
- CMDcommandparam1param2
第一種格式和第二種格式都是在可執行程序加上參數形式
舉例
- CMD["bash","-c,"jav-jardemo_application.jar"]
- CMD["java-jar","demo_application.jar"]
第三種比較簡單
- CMDJava-jardemo_application.jar
2.5 LABEL
LABEL為鏡像指定標簽
-
LABEL<key>=
< key>=< key>=...
我們經常使用LABEL指令代替MAINTAINER指令
2.6 EXPOSE
EXPOSE是暴露容器運行時的端口,但是EXPOSE并不會使容器訪問主機的端口,如果想使得容器與主機的端口有映射關系,必須在容器啟動的時候加上 -P參數。
使用格式:
- EXPOSE8848#NACOS
- EXPOSE8070#APOLLO
2.7 ENV
ENV是設置環境變量,以便在腳本中使用
使用格式:
-
ENV<key>
-
ENV<key>=
..
2.8 ADD
ADD是復制命令,將Dockerfile上下文目錄中文件/路徑復制容器的指定目錄中
使用格式:
-
ADD
... -
ADD["
" ,..."" ]
src指的是的上下文目錄下的文件,dest指的是容器中的路徑
NOTE:
當復制一個壓縮文件時,使用ADD指令可以自定解壓
ADD可以復制url到容器中
2.9 COPY
COPY類似于ADD,拷貝文件和目錄到容器中,它可以從構建上下文目錄中<原路徑>的文件/目錄復制到新的一層的鏡像內的<目標路徑>位置
使用格式:
- COPYsrcdest
-
COPY["
" ,..."" ]
2.10 ENTRYPOINT
ENTRYPOINT和CMD指令類似,都是在容器啟動時執行
使用格式:
- ENTRYPOINT["executable","param1","param2"]
- ENTRYPOINTcommandparam1param2
2.11 VOLUME
VOLUME指令實現掛載功能,用于定義容器運行時可以掛載到宿主機的目錄
使用格式:
- VOLUME["/data"]
2.12 USER
USER設置啟動容器的用戶
使用格式:
- USERsimongsimon
simon為用戶,gsimon為用戶組
2.1.3 WORKDIR
WORKDIR設置容器內的工作目錄,當創建容器后,終端默認登錄進來的工作目錄。
使用格式:
- WORKDIR/path/to/workdir
3、一個簡單的Dockerfile文件實例
3.1 編寫Dockerfile文件
- #基于哪個鏡像
- Fromjava:8
- #暴露端口
- EXPOSE8080
- #創建工作目錄
- RUNmkdir-p/com/simon/study
- #復制文件到容器
- ADDtarget/demo_application.jar/com/simon/study
- #進入工作目錄
- WORKDIR/com/simon/study
- #配置容器啟動后執行的命令
- ENTRYPOINT["java","-jar","demo_application.jar"]
3.2 使用docker build命令構建鏡像
- dockerbuild-tdemo_application:v1.0
docker build -t 鏡像名稱:標簽 ,使用-t選項指定了鏡像的標簽。
3.3 啟動鏡像
- dockerrun-p8080:8080demo-application:v1.0
4、總結
這篇文章只是簡單的介紹了Dockerfile的使用,并沒有針對上云做具體的介紹。事實上,編寫上云腳本不僅僅只是編寫Dockerfile,它還會牽扯到其它的腳本配合使用,與其它腳本相比,Dockerfile算是很簡單的了,因為其它腳本還要編寫大量的中間件的環境變量,用戶/目錄的授權,SSL證書的檢測等等。
如果對上云感興趣的同學,可以私信我,相信我能幫助到你!
原文鏈接:https://mp.weixin.qq.com/s/Tw24EUbxzsmYr5zLKP26tg