容器化技術——Docker專題四 | 利用Dockerfile構建私有鏡像

本文章是在網易云課堂的課程學習中編寫,部分圖片從網易云課堂ppt引用

【基礎概念】

鏡像的定制實際上就是定制每一層所添加的配置、文件。我們可以把每一層修改、安裝、構建、操作的命令都寫入一個腳本,這個腳本就是 Dockerfile,用這個腳本來構建、定制鏡像。

Dockerfile 是一個文本文件,里面包含了一條條的指令(Instruction),每一條指令構建一層。

【使用 Dockerfile構建私有鏡像】

接下來,使用 Dockerfile 定制 nginx 鏡像為例:

1、新建Dockerfile文件

在一個空白目錄中,建立一個文本文件,并命名為Dockerfile

mkdir mynginx
cd mynginx
touch Dockerfile

2、編輯Dockerfile文件

在Dockerfile文件寫入以下兩條指令

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

  • FROM 指定基礎鏡像
    我們定制鏡像,是以一個鏡像為基礎,在其上進行定制。基礎鏡像是必須指定的,一個 Dockerfile中,FROM 是必備的指令,并且必須是第一條指令。如果不使用任何現有鏡像為基礎,則可使用 **scratch **鏡像,這是一個虛擬的空白鏡像。

  • RUN 執行命令
    RUN命令有兩種格式:

  • shell 格式:RUN <命令>

比如:RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

  • exec 格式:RUN ["可執行文件", "參數1", "參數2"]

比如:RUN make -C /usr/src/redis

3、構建鏡像

在 Dockerfile 文件所在目錄執行:

docker build -t mynginx:1.0 .

現在通過docker images命令,可以查看到我們自己定制的鏡像了

4、基于該鏡像運行容器

docker run --name mynginx -p 80:80 mynginx:1.0

【Dockerfile指令詳解】

Dockerfile提供了十多個指令,除了上面已經用到的FROM、RUN指令,我們來繼續學習一下其他的指令。

1、COPY 復制文件

COPY 指令將 從構建上下文目錄中 <源路徑> 的文件/目錄 復制到 新的一層的鏡像內的 <目標路徑> 位置。

有兩種格式:

COPY <源路徑>... <目標路徑>
COPY ["<源路徑1>",... "<目標路徑>"]

比如:

COPY package.json/usr/src/app/

加上通配符也可以,要滿足 Go 的 filepath.Match 規則

COPY hom* /mydir/
COPY hom?.txt /mydir/

2、ADD 更高級的復制文件

ADD 指令和COPY 的格式和性質基本一致,但是在 COPY 基礎上增加了一些功能。

ADD ubuntu -xenial-core-cloudimg -amd64-root.tar.gz /

根據官方推薦,復制文件推薦還是使用COPY指令。適合使用 ADD 的場合,是需要自動解壓縮的場合。

在 COPY 和 ADD 指令中選擇的時候,可以遵循這樣的原則,所有的文件復制均使用 COPY 指令,僅在需要自動解壓縮的場合使用 ADD。

3、CMD 容器啟動命令

CMD 指令的格式和 RUN 相似,也是兩種格式:

shell 格式:CMD <命令>
exec 格式:CMD ["可執行文件", "參數1", "參數2"...]

  • 參數列表格式:CMD ["參數1", "參數2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具體的參數。

Docker容器是進程,在啟動容器的時候,需要指定所運行的程序及參數。CMD 指令就是用于指定默認的容器主進程的啟動命令。

4、ENTRYPOINT 入口點

ENTRYPOINT 的目的和CMD 一樣,都是在指定容器啟動程序及參數。ENTRYPOINT 在運行時也可以替代,不過比 CMD 要略顯繁瑣,需要通過 docker run 的參數 --entrypoint 來指定

5、ENV 設置環境變量

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2> ...

比如:ENV VERSION=1.0 DEBUG=on NAME="Happy Feet"

6、ARG 構建參數

ARG <參數名>[=<默認值>]

構建參數和 ENV 的效果一樣,都是設置環境變量。不同的是,ARG 所構建的環境變量,在將來容器運行時,是不會存在這些環境變量的。但是不要使用 ARG 保存密碼之類的信息,因為 docker history 還是可以看到所有值的。

7、VOLUME 定義匿名卷

VOLUME ["<路徑1>", "<路徑2>"...]
VOLUME <路徑>

容器運行時應該盡量保持容器存儲層不發生寫操作,對于數據庫類需要保存動態數據的應用,其數據庫文件應該保存于卷(volume)中。

為了防止運行時用戶忘記將動態文件所保存目錄掛載為卷,在 Dockerfile 中,我們可以事先指定某些目錄掛載為匿名卷,這樣在運行時如果用戶不指定掛載,其應用也可以正常運行,不會向容器存儲層寫入大量數據。

8、EXPOSE 暴露端口

EXPOSE <端口1> [<端口2>...]

EXPOSE 指令是聲明運行時容器提供服務端口,這只是一個聲明,在運行時并不會因為這個聲明應用就會開啟這個端口的服務。

在 Dockerfile 中寫入這樣的聲明有兩個好處,一個是幫助鏡像使用者理解這個鏡像服務的守護端口,以方便配置映射;另一個用處則是在運行時使用隨機端口映射時,也就是 docker run -P 時,會自動隨機映射 EXPOSE 的端口。

9、WORKDIR 指定工作目錄

WORKDIR <工作目錄路徑>

使用 WORKDIR 指令可以來指定工作目錄(或者稱為當前目錄),以后各層的當前目錄就被改為指定的目錄,如該目錄不存在,WORKDIR 會幫你建立目錄。如果需要改變以后各層的工作目錄的位置,那么應該使用 WORKDIR 指令。

10、USER 指定當前用戶

USER <用戶名>

USER 指令和 WORKDIR 相似,都是改變環境狀態并影響以后的層。WORKDIR 是改變工作目錄,USER 則是改變之后層的執行 RUN, CMD 以及 ENTRYPOINT 這類命令的身份。

當然,USER 只是幫助你切換到指定用戶而已,這個用戶必須是事先建立好的,否則無法切換。

11、HEALTHCHECK 健康檢查

HEALTHCHECK [選項] CMD <命令>:設置檢查容器健康狀況的命令
HEALTHCHECK NONE:如果基礎鏡像有健康檢查指令,使用這行可以屏蔽掉其健康檢查指令

HEALTHCHECK 指令是告訴 Docker 應該如何進行判斷容器的狀態是否正常,這是 Docker 1.12 引入的新指令。

假設有個鏡像是個簡單的 Web 服務,我們希望增加健康檢查來判斷其 Web 服務是否在正常工作,我們可以用 curl 來幫助判斷,其 Dockerfile 的 HEALTHCHECK 可以這么寫:

FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://localhost/ || exit 1

這里我們設置的是每 5 秒檢查一次,如果健康檢查命令超過 3 秒沒響應就視為失敗,并且使用 curl -fs http://localhost/ || exit 1 作為健康檢查命令。

12、ONBUILD 為他人作嫁衣

ONBUILD <其它指令>

ONBUILD 是一個特殊的指令,它后面跟的是其它指令,比如 RUN,COPY 等,而這些指令,在當前鏡像構建時并不會被執行。只有當以當前鏡像為基礎鏡像,去構建下一級鏡像的時候才會被執行。

【參考文檔】

Dockerfie 官方文檔

Dockerfile 最佳實踐文檔

Docker 官方鏡像 Dockerfile

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

推薦閱讀更多精彩內容