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