本文講的是<b>Dockerfile實踐優化建議</b>【編者的話】Dockerfile是一種被Docker程式解釋的腳本,Dockerfile由一條一條的指令組成,每條指令對應Linux下面的一條指令。Docker程式将這些Dockerfile指令翻譯真正的Linux指令。類似于Makefile,Dockerfile有自己書寫格式和支援的指令,Docker程式解決這些指令間的依賴關系。下面是resin.io關于Dockerfile編寫經驗和建議的總結。
文章主要分為兩個部分:1,必須在實踐中使用的; 2,提示部分,建議使用可以提高代碼品質和經驗,但是并非時強制的。
以下這些實踐經驗能在開發中為您縮減痛苦過程。
固定所有依賴的版本是實作良好實踐最佳途徑。這包括基本映象,從GitHub中提取的代碼,代碼依賴的庫等等。通過版本控制,您可以簡化應用程式已知的工作版本。
如果沒有版本控制,您的元件很容易改變,導緻以前工作的Dockerfile不能再建構。
基礎映象的架構會發現變化(這種情況極少,但是也是存在的),而使用日期标記排序,就可以辨別處穩定可用的最新映象版本。(這樣對于Docker來說,他們就一直可以下載下傳可用版本)
一個棘手的事情是固定作業系統中使用包安裝器安裝的軟體的版本問題,再Debian中,運作apt-get安裝特定的版本資訊,例如:
通常,您将從版本控制(例如從git / GitHub)安裝軟體,在這種情況下,沒有理由不使用由唯一ID(如git的hash / SHA)定義的特定送出或标簽 。 下面是一個如何使用git檢出代碼的特定标記版本的示例:
最終,安裝版本都來自于不管任何庫申請都是固定的版本,不論使用了requirements.txt(Python管理安裝子產品),package.json(Node.js管理安裝子產品),Cargo.toml(Rust管理安裝子產品),或者是其他語言的管理的安裝包管理器,這樣就總是固定版本(或者是經常鎖定當機)依賴版本号或者唯一送出。
普遍來講,加快計算機程式最好的方式之一是消除不必要計算(做的更少)。通常來講,軟體部署也是如此,加快部署和更新的最佳方式不發送不需要的代碼。是以,自身來講從容器中清除不必要的代碼,可以提高效率。
什麼是不需要的代碼? 最常見的是,它們是儲存在包管理器中的臨時檔案或者是在Dockerfile中建構和安裝的軟體源代碼。
上面的最後一行通過apt-get rm删除了裝置上不需要的的臨時檔案。
清除已安裝軟體的源代碼通常非常簡單,隻需删除在生成過程的早期步驟中建立的目錄即可。 為了保持上面的MRAA示例,通過git checkout後通過這個方式執行清理:
還要確定所有的清理語句在同一個部分運作,否則它們将看起來清除,但最終仍然存在于Docker容器成為殘留。
上面的最後一個注釋引導必須要做,這就要把邏輯上屬于一起操作步驟的語句合并進入Dockerfile中,這樣以避免類似緩存和不必要地使用磁盤空間有關常見問題。 首先,由于緩存,您可能會有意外的建構結果。 如果您的apt-get更新步驟是從apt-get install <package>步驟單獨運作的,則前者可能會被緩存,并且不會在您期望更新的時候更新。 如果你分離你的git克隆和實際建構,類似的事情也可能發生。其次,在單獨的後續RUN步驟中删除的檔案保留在最終容器中,但不可通路(殘留)。
強烈推薦以下做法,通常情況下這是從優秀到卓越的經驗,但是并不一定是一個瓶頸。
Docker嘗試緩存您的Dockerfile中尚未更改的所有步驟,但如果更改任何語句,将重做其後的所有步驟。 您可以在建構過程中節省相當多的時間,隻要有可能,就盡可能按照最不可能更改的順序編寫Dockerfile。 例如,一般設定,如設定工作目錄,啟用initsystem,設定維護應該更早發生。
這些語句執行之後,可以使用作業系統的軟體包管理器安裝軟體,然後編譯依賴關系,啟用系統服務和其他設定等。 例如,在Dockerfile末尾的這一部分執行,你應該安裝Python:
或者 Node.js 依賴.
複制應用程式源代碼的做法放應該在最後,這也是最常用的做法。我們可以适用複制指令:
這樣就可以加快建構部署的過程,而且Dockerfile檔案的可讀性強!上面的例子隻供參考,邏輯上實作可以依賴域目前應用程式的部分。
接着上一步,我們總是定義一個.dockerignore檔案,這個檔案是用來區分源碼中那些是非必須的裝置檔案,那些不用經過Copy ../拷貝步驟。忽略的檔案可是是README.md或者其他的檔案,或者是圖檔、檔案、其他不需要要求應用程式的功能而又必須放在一個庫或者其他原因的檔案。
建立和調試比較大型的項目,我們還有一個建議:不要直接使用CMD指令運作,建議時用一個開始腳本,每次調用運作:
然後在start.sh腳本檔案中你可以使用python app.py之類的指令啟動、運作你的應用程式。這樣的優勢是可以很友善擴充運作腳本檔案,增加調試功能,而不用在CMD中一步一步執行。
核心代碼釋出之前你想增加一些調試資訊?僅僅增加幾條你想要的幾條測試邏輯?
Docker的預設設定中,容器中的代碼都是通過Root賬戶運作的。作為一個良好的預防性安全實踐,建議建立一個Non-Root使用者,授予它隻需要盡可能多的特權即可。
例如:
<b>原文釋出時間為:</b>2017-01-20
<b>本文作者:</b>ylzhang
<b>本文來自雲栖社群合作夥伴Dockerone.io,了解相關資訊可以關注Dockerone.io。</b>
<b></b>
<b>原文标題:</b><b>Dockerfile實踐優化建議</b>