真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Docker鏡像構建的優(yōu)化總結

Docker鏡像構建的優(yōu)化總結

隨著我們對docker鏡像的持續(xù)使用,在此過程中如果不加以注意并且優(yōu)化,鏡像的體積會越來越多。很多時候我們在使用docker部署應用時,會發(fā)現(xiàn)鏡像的體積至少有1G以上。鏡像體積的增大,不單單會增加磁盤資源與網(wǎng)絡資源的開銷,也會影響應用的部署效率,使得應用的部署時間會越來越長。因此我們需要減少部署鏡像的體積以加快部署效率,降低資源的開銷。而對于鏡像的優(yōu)化,可以通過對dockerfile的優(yōu)化來實現(xiàn)。

一、鏡像最小化

1、選擇最精簡的基礎鏡像

選擇體積最小的基礎鏡像可有效降低鏡像體積。如:alpine、busybox等

2、清理鏡像構建的中間產(chǎn)物。

構建鏡像的過程中,當dockerfile的指令執(zhí)行完成后,刪除鏡像不需要用的的文件。如使用yum安裝組件,最后可使用yum clean all鏡像清理不需要的文件或者使用系統(tǒng)rm命令刪除不需要的源文件等。

3、減少鏡像的層數(shù)

鏡像是一個分層存儲的文件,并且鏡像對層數(shù)也是有一定數(shù)量的限制,當前鏡像的層數(shù)最高是127層,如果不多加注意,將會導致鏡像越來越臃腫。在使用dockerfile構建鏡像時,dockerfile中的每一條指令都會生成一個層,因此可以通過合并dockerfile中可合并的指令,減少最終生成鏡像的層數(shù)。例如:在dockerfile中使用RUN執(zhí)行shell命令是,可以用"&&"將多條命令連接起來。

二、構建速度最快化

1、充分利用鏡像構建緩存

我們可以利用構建的緩存來加快鏡像構建速度,Docker構建默認會開啟緩存,緩存生效有三個關鍵點,鏡像父層沒有發(fā)生變化,構建指令不變,添加文件校驗和一致。只要一個構建指令滿足這三個條件,這一層鏡像構建就不會再執(zhí)行,它會直接利用之前構建的結果。某一層的鏡像緩存失效之后,它之后的鏡像層緩存都會失效。我們應該把變化最少的部分放在Dockerfile的前面,這樣可以充分利用鏡像緩存。dockerfile中有可能導致緩存失效的命令WORKDIR、CMD、ENV、ADD等,像這些命令最好放到dockerfile底部,以便在構建鏡像過程中最大限度使用緩存。

2、刪除構建目錄中(默認:Dockerfile所在目錄)不需要用的的文件。

編寫.dockerignore文件過濾構建過程中不必要的文件或者創(chuàng)建單獨的目錄,并且目錄中僅存在鏡像構建過程中需要使用的文件。
Docker 在運行時分為 Docker 引擎(也就是服務端守護進程)和客戶端工具。Docker 的引擎提供了一組 REST API,被稱為 Docker Remote API,而如 docker 命令這樣的客戶端工具,則是通過這組 API 與 Docker 引擎交互,從而完成各種功能。因此,雖然表面上我們好像是在本機執(zhí)行各種 docker 功能,但實際上,一切都是使用的遠程調(diào)用形式在服務端(Docker 引擎)完成。docker build 命令構建鏡像,其實并非在本地構建,而是在服務端,也就是 Docker 引擎中構建的。
構建鏡像時,Docker需要先準備context ,將所有需要的文件收集到進程中。默認的context包含Dockerfile目錄中的所有文件。如果目錄中的存在大量不相關的文件,不僅會導致構建緩慢,而且還會導致鏡像體積增大。
.dockerignore示例如下:
在一個git項目中,我們并不需要.git目錄等內(nèi)容??梢栽?dockerignore文件中加入以下內(nèi)容:
.git/

.dockerignore 的作用和語法類似于 .gitignore,可以忽略一些不需要的文件,這樣可以有效加快鏡像構建時間,同時減少Docker鏡像的大小。

3、注意優(yōu)化網(wǎng)絡請求

我們使用一些鏡像源或者在dockerfile中使用互聯(lián)網(wǎng)上的url時,去用一些網(wǎng)絡比較好的開源站點,這樣可以節(jié)約時間、減少失敗率

三、dockerfile指令優(yōu)化

1、COPY指令和ADD指令的區(qū)別

COPY 復制文件
格式:
COPY <源路徑>... <目標路徑>
COPY ["<源路徑1>",... "<目標路徑>"]
COPY 指令將從構建上下文目錄中 <源路徑> 的文件/目錄復制到新的一層的鏡像內(nèi)的 <目標路徑> 位置。比如:
COPY package.json /usr/src/app/
<源路徑> 可以是多個,甚至可以是通配符,其通配符規(guī)則要滿足 Go 的 filepath.Match 規(guī)則,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
<目標路徑> 可以是容器內(nèi)的絕對路徑,也可以是相對于工作目錄的相對路徑(工作目錄可以用 WORKDIR 指令來指定)。目標路徑不需要事先創(chuàng)建,如果目錄不存在會在復制文件前先行創(chuàng)建缺失目錄。
此外,還需要注意一點,使用 COPY 指令,源文件的各種元數(shù)據(jù)都會保留。比如讀、寫、執(zhí)行權限、文件變更時間等。這個特性對于鏡像定制很有用。特別是構建相關文件都在使用 Git 進行管理的時候。

ADD 更高級的復制文件

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

比如 <源路徑> 可以是一個 URL,這種情況下,Docker 引擎會試圖去下載這個鏈接的文件放到 <目標路徑> 去。下載后的文件權限自動設置為 600,如果這并不是想要的權限,那么還需要增加額外的一層 RUN進行權限調(diào)整,另外,如果下載的是個壓縮包,需要解壓縮,也一樣還需要額外的一層 RUN 指令進行解壓縮。所以不如直接使用 RUN 指令,然后使用 wget 或者 curl 工具下載,處理權限、解壓縮、然后清理無用文件更合理。因此,這個功能其實并不實用,而且不推薦使用。

如果 <源路徑> 為一個 tar 壓縮文件的話,壓縮格式為 gzip, bzip2 以及 xz 的情況下,ADD 指令將會自動解壓縮這個壓縮文件到 <目標路徑> 去。

在某些情況下,這個自動解壓縮的功能非常有用,比如官方鏡像 ubuntu 中:

FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
...
但在某些情況下,如果我們真的是希望復制個壓縮文件進去,而不解壓縮,這時就不可以使用 ADD 命令了。

在 Docker 官方的最佳實踐文檔中要求,盡可能的使用 COPY,因為 COPY 的語義很明確,就是復制文件而已,而 ADD 則包含了更復雜的功能,其行為也不一定很清晰。最適合使用 ADD 的場合,就是所提及的需要自動解壓縮的場合。

另外需要注意的是,ADD 指令會令鏡像構建緩存失效,從而可能會令鏡像構建變得比較緩慢。

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

2、CMD 與 ENTRYPOINT的區(qū)別

CMD
CMD 指令設置鏡像中的默認啟動命令和參數(shù). 容器啟動之后, 如果沒有加入任何啟動命令(也就是在鏡像參數(shù)之后沒有添加任何內(nèi)容) 則默認執(zhí)行鏡像中 CMD 設置的默認的啟動命令

設置啟動命令時, 應該盡量使用 JSON 格式 CMD ["command", "arg1", "arg2"]
例如 nginx 的啟動方式: CMD ["nginx", "-D"]

如果開發(fā)者和使用者都不是很熟悉 CMD 和 ENTRYPOINT 的工作原理的情況下, 盡量避免這兩個指令配合使用
例如 Django 的啟動方式: CMD ["python", "manage.py", "runserver", "0.0.0.0:8989"]

相反, 如果開發(fā)者和使用者都很熟悉 CMD 和 ENTRYPOINT 的工作原理, 推薦 CMD 作為 ENTRYPOINT 的參數(shù)來配套使用

ENTRYPOINT
當需要把容器當做一個命令行工具使用時, 推薦通過 ENTRYPOINT 指令設置鏡像的入口程序

當啟動主程序之前還需要執(zhí)行大量的前置操作時, 可以將 ENTRYPOINT 的入口指令設置為一個腳本 start.sh

當 dockerfile 中指定了 ENTRYPOINT 的時候, docker run 如果在鏡像之后添加的指令, 那么這些指令將被當做 ENTRYPOINT 的參數(shù)執(zhí)行
如果 dockerfile 中同時有 CMD 和 ENTRYPOINT 指令, 當 CMD 指令可執(zhí)行時, 它將在 ENTRYPOINT 之前運行; 如果 CMD 不是可執(zhí)行的命令, 則將作為 ENTRYPOINT 的命令參數(shù)追加

3、WORKDIR

盡量使用絕對路徑
切換目錄的時候盡量使用 WORKDIR, 而不是使用 RUN cd /data

4、USER

如果容器中的應用程序運行時不需要特殊的權限, 可以通過 USER 指令把應用程序的所有者設置為非 root 用戶. 如果該用戶不存在, 首先需要使用 RUN 命令在鏡像中創(chuàng)建用戶.

如果在每次編譯鏡像時, 對用戶的 UID/GID 有要求需要保持一致, 應該在新建用戶和組的時候指定 UID和 GID
在鏡像中避免使用sudo 命令. 應為該命令使用的 TTY 不確定, 對接收信號量也會造成影響. 如果確實需要使用 sudo 功能, 則可是使用 gosu 命令替代
可以用 root 用戶初始化一個 daemon, 然后用非 root 用戶啟動這個 daemon
為了減少鏡像體積, 應該避免不必要的用戶切換

5、EXPOSE

EXPOSE 用來聲明未來容器內(nèi)需要監(jiān)聽的端口, 在 bridge 模式下, 這些容器內(nèi)部的端口會映射到宿主機的端口上, 建議在容器內(nèi)部不要更改應用原生的端口號

EXPOSE 中只能指定未來容器內(nèi)部需要暴露的端口, 不能指定未來容器外部與內(nèi)部端口之間的映射關系, 比如設置 EXPOSE 80:80 是沒有任何意義的

當前名稱:Docker鏡像構建的優(yōu)化總結
分享網(wǎng)址:http://weahome.cn/article/ieoegi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部