devops基礎---dockerfile介紹

什麼是Dockerfile

鏡像的定製實際上就是定製每一層所添加的配置、文件。如果我們可以把每一層修改、安裝、構建、操作的命令都寫入一個腳本,用這個腳本來構建、定製鏡像,那麼無法重複的問題、鏡像構建透明性的問題、體積的問題就都會解決。這個腳本就是 Dockerfile。

Dockerfile是由一系列命令和參數構成的腳本,這些命令應用於基礎鏡像並最終創建一個新的鏡像。它們簡化了從頭到尾的流程並極大的簡化了部署工作。Dockerfile從FROM命令開始,緊接著跟隨者各種方法,命令和參數。其產出為一個新的可以用於創建容器的鏡像。

devops基礎---dockerfile介紹

Dockerfile 是一個文本文件,其內包含了一條條的指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。

Dockerfile 指令詳解

Dockerfile有十幾條命令可用於構建鏡像,下文將簡略介紹這些命令。

FROM

FROM命令可能是最重要的Dockerfile命令。改命令定義了使用哪個基礎鏡像啟動構建流程。基礎鏡像可以為任意鏡 像。如果基礎鏡像沒有被發現,Docker將試圖從Docker image index來查找該鏡像。FROM命令必須是Dockerfile的首個命令。

在 Docker Store 上有非常多的高質量的官方鏡像,有可以直接拿來使用的服務類的鏡像,如nginx 、 redis 、 mongo 、mysql 等;也有一些方便開發、構建、運行各種語言應用的鏡像,如 node 、 openjdk 、 python 等。可以在其中尋找一個最符合我們最終目標的鏡像為基礎鏡像進行定製。

如果沒有找到對應服務的鏡像,官方鏡像中還提供了一些更為基礎的操作系統鏡像,如ubuntu 、 debian 、 centos 等,這些操作系統的軟件庫為我們提供了更廣闊的擴展空間。

# Usage: FROM [image name]

FROM centos

除了選擇現有鏡像為基礎鏡像外,Docker 還存在一個特殊的鏡像,名為 scratch 。這個鏡像是虛擬的概念,並不實際存在,它表示一個空白的鏡像。

FROM scratch

COPY 複製文件

COPY 指令將從構建上下文目錄中 的文件/目錄複製到新的一層的鏡像內的 位置。

格式:

COPY ...

COPY ["",... ""]

可以是多個,甚至可以是通配符,其通配符規則要滿足 Go 的 filepath.Match 規則。

可以是容器內的絕對路徑,也可以是相對於工作目錄的相對路徑(工作目錄可以用 WORKDIR 指令來指定)。目標路徑不需要事先創建,如果目錄不存在會在複製文件前先行創建缺失目錄。

此外,還需要注意一點,使用 COPY 指令,源文件的各種元數據都會保留。比如讀、寫、執行權限、文件變更時間等。這個特性對於鏡像定製很有用。特別是構建相關文件都在使用 Git進行管理的時候。

ADD

ADD命令有兩個參數,源和目標。它的基本作用是從源系統的文件系統上覆制文件到目標容器的文件系統。如果源是一個URL,那該URL的內容將被下載並複製到容器中。

# Usage: ADD [source directory or URL] [destination directory]

ADD /my_app_folder /my_app_folder

CMD

和RUN命令相似,CMD可以用於執行特定的命令。和RUN不同的是,這些命令不是在鏡像構建的過程中執行的,而是在用鏡像構建容器後被調用。

ADD 指令和 COPY 的格式和性質基本一致。但是在 COPY 基礎上增加了一些功能。比如 可以是一個 URL ,這種情況下,Docker 引擎會試圖去下載這個鏈接的文件放到 去。下載後的文件權限自動設置為 600 ,如果這並不是想要的權限,那麼還需要增加額外的一層 RUN 進行權限調整,另外,如果下載的是個壓縮包,需要解壓縮,也一樣還需要額外的一層 RUN 指令進行解壓縮。所以不如直接使用 RUN 指令,然後使用 wget 或者 curl 工具下載,處理權限、解壓縮、然後清理無用文件更合理。因此,這個功能其實並不實用,而且不推薦使用。

版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

# Usage 1: CMD application "argument", "argument", ..

CMD "echo" "Hello docker!"

ENTRYPOINT

配置容器啟動後執行的命令,並且不可被 docker run 提供的參數覆蓋。

每個 Dockerfile 中只能有一個 ENTRYPOINT,當指定多個時,只有最後一個起效。

ENTRYPOINT 幫助你配置一個容器使之可執行化,如果你結合CMD命令和ENTRYPOINT命令,你可以從CMD命令中移除“application”而僅僅保留參數,參數將傳遞給ENTRYPOINT命令。

# Usage: ENTRYPOINT application "argument", "argument", ..

# Remember: arguments are optional. They can be provided by CMD

# or during the creation of a container.

ENTRYPOINT echo

# Usage example with CMD:

# Arguments set with CMD can be overridden during *run*

CMD "Hello docker!"

ENTRYPOINT echo

ENV

ENV這個指令很簡單,就是設置環境變量而已,無論是後面的其它指令,如 RUN ,還是運行時的應用,都可以直接使用這裡定義的環境變量。這些變量以”key=value”的形式存在,並可以在容器內被腳本或者程序調用。這個機制給在容器中運行應用帶來了極大的便利。格式有兩種:

ENV

ENV = =...

# Usage: ENV key value

ENV SERVER_WORKS 4

EXPOSE

EXPOSE用來指定端口,使容器內的應用可以通過端口和外界交互。EXPOSE 指令是聲明運行時容器提供服務端口,這只是一個聲明,在運行時並不會因為這個聲明應用就會開啟這個端口的服務。在 Dockerfile 中寫入這樣的聲明有兩個好處,一個是幫助鏡像使用者理解這個鏡像服務的守護端口,以方便配置映射;另一個用處則是在運行時使用隨機端口映射時,也就是 docker run -P 時,會自動隨機映射 EXPOSE 的端口。

# Usage: EXPOSE [port]

EXPOSE 8080

MAINTAINER

我建議這個命令放在Dockerfile的起始部分,雖然理論上它可以放置於Dockerfile的任意位置。這個命令用於聲明作者,並應該放在FROM的後面。

# Usage: MAINTAINER [name]

MAINTAINER authors_name

RUN

RUN命令是Dockerfile執行命令的核心部分。它接受命令作為參數並用於創建鏡像。不像CMD命令,RUN命令用於創建鏡像(在之前commit的層之上形成新的層)。其格式有兩種:

shell 格式: RUN ,就像直接在命令行中輸入的命令一樣。剛才寫的 Dockerfile 中的 RUN 指令就是這種格式

RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html

exec 格式: RUN ["可執行文件", "參數1", "參數2"],這更像是函數調用中的格式

# Usage: RUN [command]

RUN yum install -y nginx

USER

USER命令用於設置運行容器的UID。USER 指令和 WORKDIR 相似,都是改變環境狀態並影響以後的層。 WORKDIR 是改變工作目錄, USER 則是改變之後層的執行 RUN , CMD 以及 ENTRYPOINT 這類命令的身份。當然,和 WORKDIR 一樣, USER 只是幫助你切換到指定用戶而已,這個用戶必須是事先建立好的,否則無法切換。

# Usage: USER [UID]

USER 1000

VOLUME

VOLUME命令用於讓你的容器訪問宿主機上的目錄。容器運行時應該儘量保持容器存儲層不發生寫操作,對於數據庫類需要保存動態數據的應用,其數據庫文件應該保存於卷(volume)中。為了防止運行時用戶忘記將動態文件所保存目錄掛載為卷,在 Dockerfile 中,我們可以事先指定某些目錄掛載為匿名卷,這樣在運行時如果用戶不指定掛載,其應用也可以正常運行,不會向容器存儲層寫入大量數據。

# Usage: VOLUME ["/dir_1", "/dir_2" ..]

VOLUME ["/data"]

WORKDIR

WORKDIR命令用於設置CMD指明的命令的運行目錄。使用 WORKDIR 指令可以來指定工作目錄(或者稱為當前目錄),以後各層的當前目錄就被改為指定的目錄,如該目錄不存在, WORKDIR 會幫你建立目錄。

# Usage: WORKDIR /path

WORKDIR ~/

ARG 構建參數

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

Dockerfile 中的 ARG 指令是定義參數名稱,以及定義其默認值。該默認值可以在構建命令 docker build 中用 --build-arg = 來覆蓋。

格式: ARG [=]


分享到:


相關文章: