Dockerfile中的yum install、yum clean和rm -rf /var/cache/yum
通常情況下,Dockerfile中的前三行指令一般是:
FROM 172.29.XX.151/base/jdk1.8.0_202 USER root RUN yum install -y python-devel gcc-* gcc openssh-clients && \ yum clean all && \ rm -rf /var/cache/yum
其中yum install、yum clean all、rm -rf /var/cache/yum一般是依賴文件的安裝清除三件套。
1、yum install -y ……
安裝鏡像所需的依賴文件。
如果不知道哪些依賴是自己鏡像所需的,可以通過不斷build,根據報錯提示安裝對應的依賴:
1)command not found: xxx
說明缺少xxx命令,直接安裝包含該命令的包:
yum install -y xxx
2)error while loading shared libraries:libxxx.so.x:cannot open shared object file
說明缺少系統庫文件,需要安裝包含該庫的包。可通過yum provides "*/libxxx.so.x"查找包名,再安裝:
yum provides "*/libssl.so.1.1" #假設結果顯示包名為openssl-libs,安裝該包即可 yum install -y openssl-libs
3)permission denied
可能是依賴包未安裝導致的間接錯誤,先解決其他報錯再來看。
清理
這種方式可能會由于多次build產生很多無用的新鏡像、層文件,這屬于開發階段的正常現象,這些文件會占用磁盤空間,但可以通過主動清理命令定期刪除,避免存儲空間被過度占用。
1)最常用:docker system prune
#清理所有未被使用的鏡像、層、容器、網絡(不含存儲卷) docker system prune #參數-a:刪除所有未被容器引用的鏡像(包含沒有標簽的中間層) docker system prune -a #參數-f:強制清理,無需確認 docker system prune -af
該方案可用于清理之前那種試錯+安裝的過程中產生的大部分冗余數據。
2)只刪除特定鏡像:docker rmi
如果要保留部分有用的鏡像,可手動刪除試錯產生的臨時鏡像:
#查看所有鏡像(包含中間層,帶<none>標簽的通常是build殘留) docker images -a #刪除指令鏡像 docker rmi 鏡像ID/鏡像名:標簽 #刪除所有帶<none>標簽的鏡像(build過程中產生的中間層) docker rmi $(docker images -f "dangling=true" -q)
鏡像標簽為<none>的通常是build過程中,由于多次修改Dockerfile而產生的中間層。
如果刪除時提示“鏡像被容器引用”,可先刪除引用該鏡像的容器(docker rm 容器ID),再刪除鏡像。
2、yum clean all、rm -rf /var/cache/yum
dockerfile中通過yum install安裝的依賴,默認會將安裝包(.rpm)保存到容器內的絕對路徑/var/cache/yum目錄下。這是yum包管理器的默認行為,目的是為了后續重復安裝同一軟件時無需重新下載,提高效率。
1)緩存的具體路徑
/var/cache/yum/ ├── <架構>(如 x86_64) │ └── 7(系統版本) │ ├── base(基礎倉庫) │ ├── extras(額外倉庫) │ └── updates(更新倉庫) │ └── packages(實際緩存的 .rpm 安裝包)
當執行yum install <包名>時,下載的.rpm文件會被保存在對應倉庫的packages目錄下。
2)緩存的作用與問題
作用:重復安裝同一軟件時,yum會直接使用緩存的.rpm文件而無需重新下載,加快安裝速度。
問題:這些緩存文件對運行中的容器沒有作用,但會占用鏡像空間(每層的RUN yum install都會保留這些緩存)。
3)清理緩存
為了減少鏡像體積,必須在安裝依賴之后清理這些緩存,且清理命令需與安裝命令放在同一RUN指令中,否則緩存會被固化到上一層的鏡像層中:
RUN yum install -y openssl-libs \ && yum clean all \ # 清理 yum 緩存(包括元數據和安裝包) && rm -rf /var/cache/yum/* # 徹底刪除緩存目錄(確保無殘留)
后兩行的yum clean all和rm -rf /var/cache/yum/*就是清理緩存的指令。
- yum clean all:yum自帶的清理命令,刪除.rpm安裝包、倉庫元數據;
- rm -rf /var/cache/yum/*:額外刪除緩存目錄本身,避免殘留空目錄或未清理干凈的文件;
其實從作用上來看,rm -rf /var/cache/yum/基本覆蓋了yum clean all的大部分功能,但在實際使用中,二者還是結合使用,這是因為yum包管理器有自己的緩存管理機制,yum clean all不僅會刪除緩存rpm我呢間,還會更新yum內部的緩存索引,避免后續執行yum命令時因緩存文件被手動刪除而出現異常。
組合使用yum clean all && rm -rf /var/cache/yum/已成為Docker社區的約定俗成的實踐寫法。
3、rpm文件的安裝、使用時機
安裝與刪除
yum install安裝的依賴會被正常使用,而rm -rf僅刪除的是安裝包緩存(.rpm),不影響已安裝的依賴本身。
yum install的工作結果有兩個:1)先從yum倉庫下載對應軟件的.rpm安裝包(存到/var/cache/yum);2)執行安裝過程:將軟件的可執行文件、庫、配置等解壓并復制到對應目錄(/usr/bin、/usr/lib、/etc)。類似于下載某個壓縮文件并解壓的過程。
rm -rf會將.rpm文件刪除,相當于把壓縮文件刪除,但是已經解壓完成的文件(即之前安裝的依賴,如/usr/bin/curl、/usr/lib/libssl.so庫文件等依然存在)。
使用
安裝的依賴會在兩個階段被使用:
build(構建)階段:如果后續的RUN指令需要調用這些依賴,如RUN curl http://example.com需要用curl命令,如果此時依賴已經安裝,命令可以正常執行。
run(運行)階段:容器啟動后(執行CMD或ENTRYPOINT時),應用程序會調用這些依賴(如Node.js用用需要libssl庫來寄哪里HTTPS連接),此時依賴早已存在于鏡像的文件系統中,可直接使用。

浙公網安備 33010602011771號