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




























