?在上一章中,我們介紹了 docker 鏡像倉庫,本文就來介紹 docker 鏡像。
一、什么是鏡像
docker 鏡像本質上是一個 read-only 只讀文件, 這個文件包含了文件系統、源碼、庫文件、依賴、工具等一些運行 application 所必須的文件。
我們可以把 Docker 鏡像?理解成一個模板,通過這個模板,可以實例化出來很多容器。
docker 鏡像里面由一層層?Union FS(聯合文件系統)組成
鏡像生活案例
鏡像相當于我們 java 或者 C++中的類,相當于一個模板,可以很方便的構建出來不同的對象。
docker 鏡像的組合層核心:聯合文件系統(Union FS)
聯合文件系統可以將幾層文件目錄掛載到一起,形成一個虛擬文件系統。
每一層文件系統我們叫做一層 layer,聯合文件系統可以對每一層文件系統設置三種權限,只讀(readonly)、讀寫(readwrite)和寫出(whiteout-able),但是 docker 鏡像中每一層文件系統都是只讀的。(PS:聯合文件系統的讀寫速度都比較慢)
構建鏡像的時候,會從一個最基本的操作系統開始構建;每個構建的操作都相當于做一層文件目錄的修改,即增加了一層文件系統。
一層層往上疊加,上層的修改會覆蓋底層該位置的可見性。這也很容易理解,就像上層把底層遮住了一樣。當使用的時候,只會看到一個完全的整體,不知道里面有幾層,也不清楚每一層所做的修改是什么。
聯合文件系統使得容器可以擁有自己的文件視圖(即容器層),同時共享宿主機或者其他容器的基礎鏡像層(只讀層)。這種方式不僅減少了存儲空間的使用,而且提高了容器啟動速度,因為只需要復制必要的鏡像即可創建新的容器。
聯合文件系統鏡像分層生活案例
我們以日常的地板為例,開發商的房子提供給用戶的時候一般是做好了地暖,而這些地暖其實是一層一層添加的,最底層的鋼筋水泥層,然后添加保溫層,采暖管,再鋪設水泥層,到最后交付的時候家家戶戶都是水泥面,這些層一般是不可修改的。
最上層用戶一般會再鋪設商木地板或者地板磚每家每戶的選擇不一樣,相當于我們鏡像的容器層。
二、為什么需要鏡像
1、通過打包,解決環境不一致問題
在部署應用時,原先是通過手工 / 寫一些腳本的方式進行部署。這樣部署面臨的最大問題就是云端和本地環境可能不一致。用戶為每個應用打包過程比較繁瑣,需要配置和修改等操作,非常費勁。 Docker 鏡像就是為了解決這個小小的打包功能,突然一夜之間成名。
那么,讀者可能會猜測?Docker 鏡像就是個壓縮包,是的,猜對了,它就像一個壓縮包文件。那么它是如何解決 Paas 時代所面臨的云端和本地一致性問題?
很簡單,它是把一個鏡像制作成一個完整的操作系統,有所有文件和對應的目錄結構,這樣的壓縮包跟你本地和測試環境用的操作系統一摸一樣。
2、減少空間占用,加速軟件開發
docker 最大的貢獻就是定義了容器鏡像的分層的存儲格式,docker 鏡像技術的基礎是聯合文件系統(UnionFS),其文件系統是分層的。這樣既可以充分利用共享層,又可以減少存儲空間占用。
docker 鏡像提供了一種打包應用程序和預配置服務器環境的便捷方式,也可以很方便的將其用于個人用途或與其他 Docker 用戶公開共享。
三、核心:鏡像相關命令
命令清單
命令 | 別名 | 功能 | 備注 |
docker pull | docker image pull | 從鏡像倉庫中拉取鏡像 | 和鏡像倉庫命令相同,亦可以歸類為鏡像命令 |
docker push | docker image push | 推送鏡像到倉庫 | 和鏡像倉庫命令相同,亦可以歸類為鏡像命令 |
docker images | docker image ls / docker image list | 列出本地鏡像 | 必須掌握 |
docker tag | docker image tag | 給本地某個鏡像打標簽(標記版本),在推送鏡像到倉庫時比較有用 | 必須掌握 |
docker rmi | docker image rm / docker image remove | 刪除本地某個鏡像 | 必須掌握 |
docker build | docker image build | 通過 dockerfile 制作鏡像 | 必須掌握 |
docker save | docker image save | 把制定鏡像保存成 tar 格式的歸檔文件 | 必須掌握 |
docker load | docker image load | 導入使用 docker save 保存的 tar 格式的鏡像文件 | 必須掌握 |
docker image inspect | 查看鏡像的詳細信息 | 必須掌握 | |
docker history | docker image history | 查看鏡像歷史 | |
docker import | docker image import | 從歸檔文件 docker export 中創建鏡像。 (與容器 docker export 對應,在下一章容器章節講解) | |
docker prune | 刪除不使用的鏡像 |
?1、docker images
# RESPOSITORY 指的是鏡像所在倉庫名
docker images [關鍵參數] [RESPOSITORY[:TAG]]
關鍵參數
無參情況:列出本地所有鏡像
-a:列出本地所有的鏡像(含中間映像層,默認情況下,過濾掉中間映像層);
--digests:顯示鏡像的摘要信息;
-f:顯示滿足條件的鏡像;
--format:指定返回值的模板文件;
--no-trunc:顯示完整的鏡像信息;
-q :只顯示鏡像 ID
功能:?列出本地鏡像
# 列出本地全部鏡像
docker images
# 列出本地鏡像中 REPOSITORY 為 ubuntu 的鏡像列表。
docker images ubuntu
2、docker tag
# SOURCE_IMAGE:原鏡像名
# TARGET_IMAGE:目標鏡像名(可以加上倉庫地址,就可以歸入某一倉庫)
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
功能: 給本地鏡像打標簽,并歸入某一倉庫(目的通常為推送做準備)

?3、docker rmi
# 可以同時刪除多個鏡像
docker rim [關鍵參數] 鏡像名....
關鍵參數
-f:強制刪除;
--no-prune:不移除該鏡像的過程鏡像,默認移除;
?功能:刪除指定鏡像
(PS:刪除前需要把引用了該鏡像的容器刪掉之后才能刪除鏡像;由于是比較暴力的刪除鏡像,用的較少,一般使用 docker rm 刪除容器)

4、docker save
# 可以同時把多個鏡像歸檔到一個文件
docker save [關鍵參數] 鏡像名...
?功能:把指定的鏡像保存成 tar 歸檔文件,便于在各個服務器上分發
關鍵參數
-o:把鏡像保存到哪一個文件中,(可以同時寫上路徑,就保存在那個路徑中;只寫文件名則是默認保存在當前文件夾中)?

?5、docker load
docker load [關鍵參數]
功能:把 tar 文件再加載成鏡像
關鍵參數
--input , -i : 導入的文件的文件名,代替 STDIN。
--quiet , -q : 精簡輸出信息。(默認是一層層導入的,會全部展示)
?

6、docker image inspect
# 可以同時查看多個鏡像
docker image inspect [關鍵參數] 鏡像名...
?功能:查看鏡像的詳細信息
(PS:如果是 docker inspect 的話,docker 會自動判斷是鏡像還是容器,然后顯示信息)

7、docker history
docker history [關鍵參數] 鏡像名
功能:顯示鏡像的歷史?
關鍵參數:
-H , --human:大小和日期采用人容易讀的格式展現
--no-trunc:顯示全部信息,不要隔斷(不截斷的話像 ID 等都會很長)
-q, --quiet:只顯示鏡像 id 信息

8、docker import
其與容器 docker export 對應,二者搭配使用,因此將在下一章容器進行講解
9、docker image prune
docker image prune [關鍵參數]
功能:刪除當前未使用的鏡像
(PS:無參的話,會刪除虛懸鏡像,即那些既沒有標簽又被沒有任何容器引用的鏡像)
關鍵參數:
-a , --all:刪除全部不使用的鏡像(只要沒有容器使用,就被視作未使用鏡像,比較危險,慎用)?
--filter filter:指定過濾條件;
-f, --force:不提示是否刪除;

?
10、docker build
docker build [關鍵參數] PATH | URL | -
功能:用于使用 dockfile 創建鏡像(會在 dockerfile 制作鏡像章節詳細講解)
關鍵參數:
--build-arg=[] :設置鏡像創建時的變量;
-f :指定要使用的 Dockerfile 路徑;
--label=[] :設置鏡像使用的元數據;
--no-cache :創建鏡像的過程不使用緩存;
--pull :嘗試去更新鏡像的新版本;
--quiet, -q :安靜模式,成功后只輸出鏡像 ID;
○ --tag, -t: 鏡像的名字及標簽,通常 name:tag 或者 name 格式;可以在一次構
建中為一個鏡像設置多個標簽。
○ --network: 默認 default。在構建期間設置 RUN 指令的網絡模式