[TOC]
鏡像尺寸變大的原因
- 對編譯或運行無關的指令被引入到鏡像
- 無用文件,比如編譯過程中的依賴文件
- 系統鏡像冗余文件多
- 各種日志文件,緩存文件占用磁盤
從精簡的鏡像開始構建
使用精簡版 Linux發行版 鏡像開始構建
- alpine https://hub.docker.com/_/alpine
- scratch https://hub.docker.com/_/scratch
優化鏡像內部文件
使用 dive 工具來優化鏡像文件
快速使用見 docker image 瘦身工具 dive
指令優化
一個常見的案例是打包元數據和緩存
在安裝完編譯和運行相關的依賴包之后,這些下載的文件就沒有存在的必要了
類似clean 的指令可以在很多倉庫(如Docker Hub)的Dockerfile 中發現,它們用于清理這類文件
比如
RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak
COPY ./sources.list /etc/apt/
# RUN apt-get update
# RUN apt-get install -y curl
RUN apt-get autoclean
RUN apt-get clean
# RUN apt-get autoremove
RUN rm -rf /var/lib/apt/lists/*
Docker 鏡像的尺寸是每一個獨立鏡像層的尺寸之和,這也就是聯合文件系統的工作機制。因此,
clean 步驟并沒有真正刪掉相應的硬盤空間
查詢構建過程即可知道
docker build -t demo .
docker history demo
Dockerfile 中每一個指令要么保持鏡像尺寸不變,要么增加它的尺寸
同時,每一步還會引入新的元數據信息,使得整體尺寸在增大
為了降低整個鏡像的尺寸,清除操作應該在同一鏡像層中執行。于是,解決方案是將先前的多條指令合并成一條
使用Bourne shell 提供的&&操作符來實現鏈接
RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak
COPY ./sources.list /etc/apt/
RUN apt-get autoclean \
&& apt-get clean \
&& autoremove \
&& rm -rf /var/lib/apt/lists/*
分離編譯鏡像和部署鏡像
導致鏡像過大的無用文件是編譯過程中的依賴文件
例如在編譯應用程序過程中所依賴的源代碼庫,如編譯文件和頭文件
一旦應用程序編譯完畢,這些文件就不再有用,因為運行該應用僅需要相關的依賴庫
- 使用
docker cp -L
命令 復制運行容器中的可執行文件到Docker 宿主機 - 然后使用
ADD
指令添加必要二進制文件
這種分離優化技術的最佳實踐案例是在一個可持續開發流程中的應用程序的場景,并且它由于鏡像太大導致傳輸時間太長
參考
「Allen 談 Docker 系列」之深刻理解 Docker 鏡像大小
如何讓Docker基礎鏡像變得更小
CentOS Dockerfile減少構建鏡像大小的方法