1. 程式人生 > >Docker 映象優化:減小映象尺寸

Docker 映象優化:減小映象尺寸

引 言
隨著我們對Docker 應用的持續使用,如果不加註意,那麼映象的尺寸就會變得越來越大。很多人在使用Docker 時會發現,團隊定製化的Docker 映象尺寸都至少有1GB 大。映象越大就意味著編譯和部署Docker 應用的時間會越長。因此,我們需要減小需要部署的映象的尺寸。它會抵消使用Docker 帶來的好處,失去快速迭代開發和部署應用的能力。
本文節將深入討論Docker 映象層的技術細節以及它們是如何影響最終映象的大小的。
接下來,我們將在研究Docker 映象工作原理的過程中,學習如何優化這些映象層。

鏈 式 指 令
Docker 映象尺寸變大的一個原因是很多對編譯或執行無關的指令被引入到映象中。一個常見的案例是打包元資料和快取。在安裝完編譯和執行相關的依賴包之後,這些下載的檔案就沒有存在的必要了。類似clean 的指令可以在很多倉庫(如Docker Hub)的Dockerfile 中發現,它們用於清理這類檔案,例如:
圖片描述


但是,一個Docker 映象的尺寸是每一個獨立映象層的尺寸之和,這也就是聯合檔案系統的工作機制。因此,clean 步驟並沒有真正刪掉相應的硬碟空間,可通過如下命令來檢視:
圖片描述
記錄顯示,這裡並不存在“負”的映象層尺寸。於是,Dockerfile 中每一個指令要麼保持映象尺寸不變,要麼增加它的尺寸。同時,每一步還會引入新的元資料資訊,使得整體尺寸在增大。
為了降低整個映象的尺寸,清除操作應該在同一映象層中執行。於是,解決方案是將先前的多條指令合併成一條。當Docker 使用/bin/sh 來執行每一條指令時,我們可以使用Bourne shell 提供的&&操作符來實現連結,例如:
圖片描述

現在每一個獨立層的尺寸已經足夠小了。由於獨立映象層的尺寸被減小,於是整個映象的尺寸也隨之減小。讓我們來確認一下它們的尺寸,操作如下:
圖片描述
圖片描述
分離編譯映象和部署映象
Docker 映象中另一類無用檔案是編譯過程中的依賴檔案,例如在編譯應用程式過程中所依賴的原始碼庫,如編譯檔案和標頭檔案。一旦應用程式編譯完畢,這些檔案就不再有用,因為執行該應用僅需要相關的依賴庫。
例如,編譯下面這個應用程式,它已經開發完畢並準備部署到Docker 雲主機上。這是一個簡單的Web 應用程式,採用Go 語言開發,程式碼樹如下圖所示。
圖片描述
hello.go 的內容如下:
圖片描述
圖片描述
相應的Dockerfile 中記錄瞭如何編譯原始碼和執行編譯結果,內容如下:
圖片描述

接下來,我們將展示這個Docker 映象的尺寸是如何變大的,操作如下所示。
1.首先,編譯這個Docker 映象並記錄它的尺寸,操作如下:
圖片描述
2.然後,對比執行時實際應用程式的尺寸,操作如下:
圖片描述
用Go 語言編寫應用程式以及編譯程式碼的一個優勢是,它可以生成一個單一可執行檔案,這對部署非常方便。Docker 映象中除去該可執行檔案佔據的空間,全都是Docker 基礎映象引入的無用檔案。可以發現,來自基礎映象的檔案使得整個映象尺寸增加了將近100倍。
同樣,我們可以優化這個最終的Docker 映象並僅打包最後的hello 可執行檔案和相關的依賴包,然後部署到生產環境。優化步驟如下所示。
1.首先,複製執行容器中的可執行檔案到Docker 宿主機,操作如下:
圖片描述
2.如果前面的依賴庫是一個靜態庫,那這一步就已經完成了,直接進入下一步。但是,Go 工具編譯時預設採用共享庫機制,為了讓二進位制檔案直接執行,還需要這些共享庫,操作如下:
圖片描述
3.接下來,儲存全部共享庫到Docker 宿主機,採用docker cp –L 命令,操作如下:
圖片描述
4.建立一個新的Dockerfile 用於編譯這個只有二進位制(binary-only)的映象。注意,如何使用ADD 指令將共享庫新增到Docker 映象中,操作如下:
圖片描述
5.現在,所有必要的檔案都在這個“binary-only”的映象中,資料夾中的目錄結構樹如下圖所示。
圖片描述
6.最後,採用build/Dockerfile 檔案編譯這個用於部署的二進位制Docker 映象,最終生成的映象將比原來的小,操作如下:
圖片描述
同樣的方法可以用於編譯其他應用,例如通常採用./configure && make && makeinstall 方式安裝的那些軟體。同樣,可以用於那些解釋性程式語言的應用程式,如Python、Ruby 或者PHP。但是,建立一個“執行時”的Ruby 語言的Docker 映象還需要進行一些額外處理。這種優化技術的最佳實踐案例是在一個可持續開發流程中的應用程式的場景,並且它由於映象太大導致傳輸時間太長。
相關圖書
圖片描述
《高效能Docker》
DockOne社群傾情翻譯
閱讀本書將掌握Docker效能優化實踐
更快、更高效地部署容器,改善開發工作流
【美】艾倫·埃斯皮諾薩 著
陳杰 楊峰 夏彬 譯
2016年9月出版
◎ 幫助讀者改善其Docker 工作流,並保證應用在生產環境中順利進行
◎ 除了Docker 的基礎知識外,還會學到如何優化Docker基礎架構和大規模應用