為什麼要進行Dockerfile的優化?
在 Docker build 過程中,會占用 Dockerfile 并且在其自身臨時的容器中一對一地運作每個可操作的指令。 結果是每個可操作的指令都有一個新映像層。Docker鏡像應該是小而快的,如果不能建構一個良好的Dockerfile來幫助你提高建構緩存命中率,那麼你的鏡像建構過程将會變得相當的緩慢,并且鏡像的體積将會很大。
如何進行優化Dockerfile
鏡像體積最小化
-1. 基礎鏡像的選擇:
常用的 Linux 系統鏡像一般有 ubuntu、centos、debian,其中debian 更輕量,而且适用的用途很廣。在運作某種應用例如PHP時,在業務需要滿足下盡量适用官方的Docker鏡像。

-2. 減少鏡像層數:
在一個Dockerfile中每個指令都會在原來的基礎上生成一層鏡像,這毫無疑問将會對鏡像增加體積,盡量将RUN指令進行組合,這将有效的減少鏡像層數達到減少體積的效果。
#優化前
RUN wget jdk-8u191-linux-x64.tar.gz
RUN tar zxvf jdk-8u191-linux-x64.tar.gz
#優化後
RUN tar zxvf jdk-8u191-linux-x64.tar.gz && \
mv jdk1.8.0_191 /usr/local/jdk
-3. 清除緩存和臨時檔案:
在鏡像建構過程中,可能會适用apt-get或yum等方式進行包的安裝,在完成後系統會殘留一些不必要的檔案,或者适用源代碼進行編譯某些應用時,源代碼檔案夾将會存放在鏡像中,在鏡像建構的最後步驟,可以将這些不必要的檔案進行删除。
RUN rm -rf /usr/local/src/* && \
yum clean all
-4. 鏡像服務化:
當有多個服務時,分開多個鏡像去運作這些服務,各司其職,例如在同一個鏡像中打包了Apache httpd、MySQL、PHP,這無疑造成該鏡像耦合性太差且體積臃腫。建議采用不同的鏡像去托管不同的應用。
建構速度最快化
-5. 建構緩存
在建構過程中,如果可以利用到緩存無疑将提升建構的速度,緩存的觸發原則是單個指令的内容沒有變化,則Docker建構時就會預設去使用緩存。我們可以通過将一些不變的操作獨立成單獨的指令,這樣在建構時隻會對有産生變化的指令建構,而不變的指令将會使用緩存。
-6. 删除建構目錄額外的檔案
在建構鏡像時将會上傳建構檔案夾中的所有檔案,但有時不是全部的檔案都是建構所需的,可以通過.dockerignore檔案進行過濾,這将提高建構的速度及鏡像的大小。
-7. 優化網絡請求
在建構鏡像過程中,可能有指令需要使用網絡去實作下載下傳、安裝等操作,由于網絡的不确定性,可能會造成建構過程較久,而且建構的時間不一等問題,建議采用本地化引用網絡資源來解決問題,例如Centos使用yum進行軟體包的管理時,可以通過Nexus進行本地代理,進而減少網絡請求的問題。
使用優化
-8. 使用CMD、VOLUME指令對Image進行服務化
在不同的業務場景中會對鏡像有不同的應用,但如果每次需要進行手動添加一些業務特定的東西時是比較繁瑣的,可以采用CMD、VOLUME指令進行鏡像的服務化彈性定制。
-9. 使用LABEL對鏡像進行中繼資料維護
在Docker鏡像倉庫中可能托管很多鏡像,每一個鏡像通途不一,但靠鏡像名和标記是無法判斷具體資訊的,使用LABEL的方式可以對鏡像的中繼資料進行管理,進而更清晰的知道鏡像的資訊。
-10. 使用變量
就像程式設計一樣,當一個字元串出現多次時,請用ARG來聲明變量取代hard code。