Docker 鏡像優化:減少鏡像尺寸

Docker 鏡像優化:減少鏡像尺寸

2016年08月23日 10:15:10 閱讀數:1366 標籤: 下載編譯應用指令鏡像docker

版權聲明:本文爲博主原創文章,未經博主容許不得轉載。 https://blog.csdn.net/broadview2006/article/details/80124932shell

引 言 
隨着咱們對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基礎架構和大規模應用緩存

相關文章
相關標籤/搜索