Dockerfile是由一系列命令和參數(shù)構(gòu)成的腳本唇撬,這些命令應(yīng)用于基礎(chǔ)鏡像并最終創(chuàng)建一個(gè)新的鏡像屿脐。它們簡(jiǎn)化了從頭到尾的流程并極
大的簡(jiǎn)化了 部署工作妓肢。Dockerfile從FROM命令開(kāi)始严肪,緊接著是各種方法键思、命令和參數(shù)。其產(chǎn)出為一個(gè)新的可以用于創(chuàng)建容器的鏡像
使用Dockerfiles的優(yōu)點(diǎn)
-干凈阐枣,生成的鏡像不會(huì)有日志文件马靠、臨時(shí)文件等東西
-靈活,可以挑選更合適的父鏡像來(lái)編譯
-可追溯蔼两,使用明確的步驟執(zhí)行操作甩鳄,通過(guò)history命令可以明確查看鏡像的生成過(guò)程
1 查找 Docker Hub 上的 Dockerfile
Docker Hub 網(wǎng)站是容器鏡像的常用搜索網(wǎng)站,在搜索鏡像后额划,文檔頁(yè)中可能會(huì)提供其 Dockerfile 的鏈接
例如:打開(kāi) 搜索mysql妙啃,在結(jié)果界面中,點(diǎn)開(kāi)搜索結(jié)果中的mysql锁孟,就能看到這個(gè)鏡像的具體信息彬祖,點(diǎn)開(kāi)版本茁瘦,里面
就有Dockerfiles
2 使用 OpenShift Source-to-Image 工具
Source-to-Image (S2I)提供了使用 Dockerfile 創(chuàng)建新容器鏡像的替代選擇品抽,可以作為 OpenShift 的一項(xiàng)功能或單獨(dú)的 s2i 實(shí)用程序來(lái)使用S2I 允許開(kāi)發(fā)人員利用其常用的工具來(lái)操作,不需要學(xué)習(xí) Dockerfile 語(yǔ)法和利用 yum 等操作系統(tǒng)命令甜熔,并且通常能創(chuàng)建層數(shù)較少的精簡(jiǎn)型鏡像
S2I 利用下列流程為應(yīng)用構(gòu)建自定義容器鏡像
從基礎(chǔ)容器鏡像(稱為 構(gòu)建器鏡像)啟動(dòng)容器圆恤;基礎(chǔ)容器鏡像中包含編程語(yǔ)言運(yùn)行時(shí)和基本的開(kāi)發(fā)工具,如編譯器和軟件包管
理器
通常從 Git 服務(wù)器獲取應(yīng)用源代碼腔稀,并將它發(fā)送到容器
在容器內(nèi)構(gòu)建應(yīng)用二進(jìn)制文件
在進(jìn)行一些清理后盆昙,將容器保存為新的容器鏡像,后者同時(shí)包含應(yīng)編程語(yǔ)言運(yùn)行時(shí)和應(yīng)用二進(jìn)制文件
怎么在 OpenShift 外的僅 Docker 環(huán)境中運(yùn)行 S2I 流程焊虏?
安裝 source-to-image RPM 軟件包安裝到 RHEL 系統(tǒng)上淡喜,也可通過(guò)在 GitHub 上的 S2I 項(xiàng)目中提供的安裝程序安裝到其他平臺(tái)上,如 Windows 和 MacOS诵闭,可以獲得s2i命令來(lái)執(zhí)行s2i流程
3 使用Dockerfile構(gòu)建自定義容器鏡像
從 Dockerfile 構(gòu)建鏡像涉及三個(gè)步驟
1. 創(chuàng)建工作目錄
docker 命令可 使用工作目錄中的文件構(gòu)建鏡像
應(yīng)創(chuàng)建空的工作目錄以防將不必要的文件納入鏡像
出于安全原因炼团,根目錄 / 不應(yīng)用作鏡像構(gòu)建的工作目錄
2. 編寫 Dockerfile 規(guī)格
Dockerfile 是應(yīng)在工作目錄中存在的文本文件
Dockerfile文件的基本語(yǔ)法
Docker文件中采用“鍵 值”方式定義
Docker文件中使用#作為注釋澎嚣,且#必須放在行首,放在行中不是注釋
Dockerfile 中的指令按照其出現(xiàn)的順序執(zhí)行
第一條非注釋指令必須是 FROM 指令瘟芝,用于指定構(gòu)建時(shí)要基于的基礎(chǔ)鏡像
每條 Dockerfile 指令均獨(dú)立運(yùn)行
Dockerfiles常用指令
FROM 指定base鏡像
LABEL 添加元數(shù)據(jù)
MAINTAINER 設(shè)置鏡像的作者
COPY 將文件從build context 復(fù)制到鏡像易桃,COPY src dest
ADD 與COPY類似,將文件從build context 復(fù)制到鏡像锌俱,不同而是晤郑,ADD的src如果是歸檔文件(tar,zip贸宏,tgz造寝,xz等),文
件會(huì)自動(dòng)解壓到dest
ENV 設(shè)置環(huán)境變量
EXPOSE 指定容器中的進(jìn)程會(huì)監(jiān)聽(tīng)某個(gè)端口锚赤,Docker可以將該端口開(kāi)放出來(lái)
VOLUME 將文件或目錄申明為volume
WORKDIR 為ADD匹舞、COPY、RUN线脚、CMD赐稽、ENTRYPOINT指令設(shè)置鏡像中的工作目錄
RUN 在容器中運(yùn)行指令,一般用來(lái)裝包
CMD 容器啟動(dòng)后運(yùn)行執(zhí)行的命令
如果docker命令中指定了容器啟動(dòng)后運(yùn)行的命令浑侥,這個(gè)指定會(huì)失效
Dockerfiles中可以設(shè)定多個(gè)CMD指令姊舵,但只有最后一個(gè)生效
ENTRYPOINT 設(shè)置容器啟動(dòng)時(shí)運(yùn)行的命令
可以設(shè)定多個(gè),但只有最后一個(gè)生效
CMD寓落、docker run之后的參數(shù)都會(huì)被當(dāng)做參數(shù)傳遞給ENTRYPOINT
示例1:構(gòu)建一個(gè)Dockerfile 文件以用于生成Apache Web 服務(wù)器容器
#This is a comment line
FROM rhel7.5
LABEL description="This is a custom httpd image"
MAINTAINER Jingyan
RUN yum install -y httpd
EXPOSE 80
ENV Log "info"
ADD http://jingyan.com/img.pdf /var/www/html
COPY ./src/ var/www/html
USER apache
ENTRYPOINT ["/usr/sbin/httpd"]
CMD ["-D","FOREGROUND"]
總結(jié)一下通過(guò)Dockerfile構(gòu)建鏡像的過(guò)程:
(1)從base鏡像運(yùn)行一個(gè)容器括丁。
(2)執(zhí)行一條指令,對(duì)容器做修改伶选。
(3)執(zhí)行類似docker commit的操作史飞,生成一個(gè)新的鏡像層。
(4)Docker再基于剛剛提交的鏡像運(yùn)行一個(gè)新容器仰税。
(5)重復(fù)2~4步构资,直到Dockerfile中的所有指令執(zhí)行完畢。
從這個(gè)過(guò)程可以看出陨簇,如果Dockerfile由于某種原因執(zhí)行到某個(gè)指令失敗了吐绵,我們也將能夠得到前一個(gè)指令成功執(zhí)行構(gòu)建出的鏡像,這對(duì)調(diào)試Dockerfile非常有幫助河绽。我們可以運(yùn)行最新的這個(gè)鏡像定位指令失敗的原因己单。
1 井號(hào) (#) 開(kāi)頭的行是注釋
2 新容器鏡像將在 rhel7.3 容器鏡像基礎(chǔ)上構(gòu)建
可以將任何其他容器鏡像用作基礎(chǔ)鏡像,而不僅限于來(lái)自操作系統(tǒng)分發(fā)的鏡像
3 LABEL 負(fù)責(zé)添加通用元數(shù)據(jù)到鏡像中
4 MAINTAINER 負(fù)責(zé)設(shè)置所生成的容器鏡像的 Author 字段耙饰。您可以使用 docker inspect 命令查看鏡像元數(shù)據(jù)
5 RUN 在當(dāng)前鏡像頂部的新層中執(zhí)行命令纹笼,然后提交結(jié)果
所提交的結(jié)果將用于 Dockerfile 中的下一步
用于執(zhí)行命令的 shell 是 /bin/sh
6 EXPOSE 指示容器在運(yùn)行時(shí)偵聽(tīng)指定的網(wǎng)絡(luò)端口
Docker 容器化環(huán)境使用此信息,通過(guò)鏈接的容器功能進(jìn)行容器互連
EXPOSE 指令僅僅是元數(shù)據(jù)苟跪;不會(huì)使端口可從主機(jī)進(jìn)行訪問(wèn)廷痘。docker run 命令的 -p 選項(xiàng)可以開(kāi)放主機(jī)上的端口
7 ENV 負(fù)責(zé)定義可供容器使用的環(huán)境變量
可以在 Dockerfile 內(nèi)聲明多個(gè) ENV 指令
可以在容器內(nèi)使用 env 命令來(lái)查看各個(gè)環(huán)境變量
8 ADD 復(fù)制新文件矮嫉、目錄或遠(yuǎn)程 URL,并將它們添加到容器文件系統(tǒng)中
9 COPY 也復(fù)制新文件和目錄牍疏,并將它們添加到容器文件系統(tǒng)中
COPY無(wú)法使用 URL
10 USER 指定運(yùn)行容器鏡像時(shí)要使用的用戶名或 UID蠢笋,用于 Dockerfile 中的 RUN、CMD 和ENTRYPOINT 指令
出于安全原因鳞陨,最好定義 root 之外的其他用戶名
11 ENTRYPOINT 指定在創(chuàng)建容器時(shí)要執(zhí)行的默認(rèn)命令
默認(rèn)情況下昨寞,執(zhí)行的命令是 /bin/sh -c,除非指定了 ENTRYPOINT
12 CMD 提供 ENTRYPOINT 指令的默認(rèn)參數(shù)