Docker 基礎 : 鏡像


目錄

鏡像是 Docker 的三大核心概念之一。Docker 運行容器前需要本地存在對應的鏡像,如果本地沒有對應的鏡像,Docker 會嘗試從默認的鏡像倉庫下載。當然用戶也可以通過配置,使用自定義的鏡像倉庫。
本文將介紹鏡像的具體操作,包括使用 pull 命令從 Docker Hub 的鏡像倉庫中拉取(下載)公共鏡像;查看本地已有的鏡像信息;使用 search 命令搜索鏡像;刪除鏡像標簽和鏡像文件;創建用戶自定義鏡像並上傳到 Docker Hub 鏡像倉庫。
與鏡像相關的操作都被定義在 docker image 子命令中,雖然不帶 image 的格式依然被兼容,但帶上 image 后會讓命令更容易理解,也會有更好的自動補全效果。

獲取鏡像

本地鏡像是運行容器的前提,所以在運行容器前我們需要使用 docker image pull 命令從網絡上的鏡像倉庫把鏡像拉取到本地。該命令的格式為:
docker image pull [OPTIONS] NAME[:TAG|@DIGEST]

如果只指定了鏡像的名稱,默認會選擇拉取 latest 標簽標記的鏡像。比如我們要拉取最新的 ubuntu 鏡像:

$ docker image pull ubuntu

該命令實際拉取的是 ubuntu:latest 鏡像,當前的最新版本為 16.04。從上圖中可以看到,docker 的鏡像其實被分成了很多的層,每層保存一些特定的文件。上面的命令實際相當於:

$ docker image pull registry.hub.docker.com/ubuntu:latest

即從默認的數據倉庫服務器 registry.hub.docker.com 中拉取 ubuntu 倉庫中的最新鏡像。如果我們感覺從 Docker Hub 上拉取鏡像太慢,可選擇從其它的數據倉庫服務器上拉取,比如 Docker Hub 在國內部署的服務器:

$ docker image pull registry.docker-cn.com/library/ubuntu:latest

鏡像下載到本地后就可運行容器了,比如:

$ docker run --rm ubuntu echo hello docker

查看鏡像信息

使用 docker image ls(或 docker images) 命令可以列出本地存儲的鏡像:

$ docker image ls

輸出的信息中包含的內容有:
REPOSITORY:說明鏡像來自哪個倉庫,比如 ubuntu 或 registry.docker-cn.com/library/ubuntu。
TAG:鏡像的標簽信息,比如 14.04 或 latest。
IMAGE ID:標識鏡像的 ID 號。
CREATED:創建鏡像的時間。
SIZE:鏡像大小。
其中鏡像的 ID 信息十分重要,它唯一的標識了鏡像。
TAG 信息用來標記來自同一個倉庫(比如 ubuntu)的不同鏡像。例如 ubuntu 倉庫中有多個鏡像,可以通過 TAG 信息來區分它們,TAG 13.04、14.04 和 16.04 都代表了不同的發行版本。

使用 docker image tag 命令為本地的鏡像添加新的標簽還可以方便我們的使用,比如為 ubuntu:14.04 鏡像添加下面的標簽:

$ docker image tag ubuntu:14.04 oldubuntu

然后就可以通過 oldubuntu 來引用 ubuntu:14.04 鏡像了。其實從 docker image ls 的輸出中我們可以看到,它們引用的是同一個鏡像 ID:

我們添加的新標簽就像給鏡像取了個別名一樣。

使用 docker image inspect 命令可以獲取鏡像的詳細信息,比如查看 ubuntu:latest 鏡像的信息:

$ docker image inspect ubuntu:latest

這個命令的輸出很長,上圖只是截取了一小部分的信息。它輸出的是一個 JSON 格式的信息,一般情況下我們會有的放矢的通過 -f 選項取其中的某一部分。比如只獲取鏡像的 Architecture 信息:

$ docker image inspect -f {{".Architecture"}} ubuntu:latest

搜索鏡像

除了直接在 Docker Hub 的官方網站上搜索鏡像資源,還可以通 docker search 命令以命令行的方式進行搜索,比如搜索 mysql 鏡像:

$ docker search mysql

該圖只截取了一部分結果。個人感覺這個命令的價值有限,因為我們在選擇鏡像時還是需要慎重的。往往要在 Docker Hub 的官方網站上查看鏡像相關的詳細信息,然后才會決定是否使用,而 docker search 命令提供的信息過於有限。

刪除鏡像

對於不再需要的鏡像我們可以使用 docker image rm 命令進行刪除,以釋放鏡像占用的磁盤空間。我們可以為 docker image rm 命令傳遞鏡像的標簽或 ID,這兩種方式略微有些區別,下面我們將分別介紹。

使用進行的標簽刪除鏡像
比如刪除標簽為 mysql:5.6 的鏡像:

$ docker image rm mysql:5.6

鏡像的所有內容一下就被刪除了(很多鏡像層被刪除掉),再來刪除 ubuntu:14.04 試試:

$ docker image rm ubuntu:14.04

為什么這次只刪除了一點點東西?再去看看進行列表,oldubuntu 還在,並且引用着 ID 為 3b853789146f 的鏡像:

原來,對於被多個標簽引用的鏡像 ID,刪除標簽時只是把那個標簽刪掉了,並會真正刪除鏡像文件。現在再刪除一次 oldubuntu 試試:

由於 oldubuntu 是最后一個引用該鏡像的標簽,所以刪除該標簽會同時刪除該鏡像的所有文件。

使用鏡像 ID 刪除鏡像
對於鏡像 ID 為 c9d990395902 的鏡像來說,也有兩個標簽引用着它,分別是 ubuntu:latest 和 newubuntu:

現在讓我們嘗試通過鏡像 ID 刪除它:

$ docker image rm c9d990395902

此時 docker 檢測到該鏡像 ID 被引用了多次就機智的報錯了,並且終止了刪除操作。同樣如果由其它的鏡像引用了該 ID 的鏡像, docker 同樣會報錯並終止刪除操作。所以,只有當一個鏡像不被多個標簽引用,也沒其它鏡像引用它時,才可以被通過鏡像 ID 刪除。

創建鏡像

我們可以通過不同的方式創建鏡像,比如基於已有容器進行創建和基於 Dockerfile 文件進行創建。筆者在《Docker 基礎 : Dockerfile》一文中介紹過通過 docker build 命令利用 Dockerfile 文件創建鏡像,所以這里只介紹如何通過 docker container commit 命令基於已有容器創建鏡像。我們先啟動一個以 ubuntu:latest 為鏡像的容器,然后在當前目錄下創建一個名為 nickfile 的文件:

$ docker run -it ubuntu:latest bash

在文件創建后退出容器,但要記住該容器的 ID 為:7e26732e14e6。然后執行下面的命令創建鏡像:

$ docker container commit -m "add file nickfile." 7e26732e14e6 nickimage

鏡像創建成功后,你可以在鏡像列表中看到名稱為 nickimage 的鏡像:

下面運行一個基於 nickimage 的容器,看看 nickfile 是否存在:

$ docker run --rm nickimage ls

驗明正身!我們在容器中創建的文件 nickfile 已經被成功的添加到 nickimage 鏡像中了。

導出和導入鏡像

當碰到沒有網絡的環境時,如何獲取鏡像呢?答案是在能夠獲得鏡像的環境中把鏡像導出為文件,然后通過 U 盤等設備拷貝到目標環境中,再進行導入。

導出鏡像
通過 docker image save 命令可以把鏡像導出為本地文件,比如導出 ubuntu:latest 鏡像為 ubuntu1604.tar:

$ docker image save -o ubuntu1604.tar ubuntu:latest

一般我們還會再壓縮一下,這樣最終的文件會小不少:

$ tar -czf ubuntu1604.tar.gz ubuntu1604.tar

文件大小從 112M 壓縮到了 41M,效果還是很明顯的。

導入鏡像
把 ubuntu1604.tar.gz 文件拷貝到目標系統上后先要解壓出 ubuntu1604.tar 文件:

$ tar -xf ubuntu1604.tar.gz

然后通過 docker image load 命令執行鏡像的導入操作:

$ docker image load -i ubuntu1604.tar

這樣就 OK 了,用 docker image ls 命令看看,是不是已經可以看到 ubuntu:latest 鏡像了!

上傳鏡像

可以使用 docker image push 命令把鏡像上傳到鏡像倉庫服務器,默認是上傳到 Docker Hub 的鏡像倉庫,此時事先需要注冊用戶並進行登錄。上傳鏡像的命令格式為:
docker image push NAME[:TAG]
比如筆者在 Docker Hub 注冊了賬號 ljfpower,並通過 docker login 命令完成了登錄操作(需要輸入用戶名和密碼進行驗證)。接下來就可把本地的鏡像上傳到鏡像倉庫服務器了。在上傳前需要給鏡像打上合法的標簽(用戶賬號/倉庫名稱:TAG),比如:

$ docker image tag azcli:1.0 ljfpower/azcli:latest

最后上傳這個標簽就行了:

$ docker image push ljfpower/azcli:latest 

上傳后你就可以在 Docker Hub 上看到這個鏡像了:

總結

鏡像是使用 docker 的前提,所以本文比較詳細的介紹了 docker 鏡像相關的操作,包括獲取、查看、搜索、創建、刪除、導出、導入等。希望對大家了解、學習 docker 有所幫助。

參考:
《Docker 技術入門與實戰》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM