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