1 引言
將docker與汽車生產線類比,如果說docker引擎是汽車生產車間,那麼容器就是最終的產品——汽車,而本節要介紹的映象就如同汽車設計圖紙,其重要性不言而喻——只有有了設計圖(映象),才能生產汽車(汽車)。
2 映象管理
2.1 獲取映象
剛安裝好的docker裡面是沒有映象的,但我們可以從開源的映象倉庫中下載映象,docker官方提供的docker hub就是最大的一個docker倉庫,裡面有全球各地使用者提供的各式各樣的docker映象供我們下載使用。在下載映象之前,我們先來熟悉一下docker映象下載命令和相關知識。
docker [image] pull 倉庫名[:標籤]
上行命令就是我們常用的docker映象下載命令,其中,倉庫名指定我們要從哪個倉庫下載的映象,標籤是指映象便籤,通常指代的是版本資訊,例如:ubuntu:16.04和ubuntu:18.04分別指代ubuntu倉庫中16.04版本的ubuntu和18.04版本的ubuntu映象。命令中image和標籤引數可加可不加,當省略標籤引數時,即指使用預設的latest標籤,也就是說,下載指定倉庫中的的最新版本。下載ubuntu最新版本:
$ docker pull ubuntu
注意:latest標籤會動態跟隨最新版本變更,這意味著映象內容也是動態變化的,所以出於穩定性考慮,在生產環境中,不要在生產環境中使用latest標籤。
pull命令預設從官方docker hub倉庫中下載映象,所以,上行命令中並沒有指定完整倉庫名,如果需要從其他非官方倉庫下載映象,則需要指定完整倉庫名,例如,從網易非常的映象源中下載ubuntu:18.04映象:
$ docker pull hub.c.163.com/public/ubuntu18.04
2.2 檢視及查詢映象
(1)檢視本機上所有映象基本資訊:
$ docker images
(2)檢視指定映象詳細資訊
$ docker [image] inspect 倉庫名:標籤
例:檢視上文中下載的ubuntu:18.04映象詳細資訊
$ docker inspect ubuntu:18.04
(3)檢視映象各層建立資訊
$ docker history 倉庫名:標籤
(4)搜尋映象
$ docker search [選項] 關鍵詞
命令中,可以通過選項指定輸出內容格式、數量、部分過濾條件等,關鍵詞是指搜尋關鍵字。
例如:查詢ubuntu相關映象
$ docker search ubuntu
2.3 刪除映象
刪除映象可以使用一下兩種命令格式:
$ docker rmi 倉庫名:標籤或映象id
$ docker image rm 倉庫名:標籤或映象id
定位一個映象可以通過"倉庫名:標籤"和映象id兩種方式,所以,在刪除映象時,我們也可以通過這兩種方式來指定要刪除的映象,也即是上面兩行命令中的倉庫名:標籤或映象id。
刪除映象時需要注意,每次執行刪除映象命令事實上只是刪除指定映象的一個標籤,只有當該映象僅有一個標籤時,使用刪除映象命令才會真正刪除映象。啥?一個映象還有多個標籤,沒錯,人類除了真名都還有網名、小名、外號呢。在演示刪除映象前,我們先嚐試給映象新增標籤。
先檢視本地有哪些映象:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 18.04 7698f282e524 7 days ago 69.9MB hello-world latest fce289e99eb9 4 months ago 1.84kB
給hello-World映象新增一個標籤:
$ docker tag hello-world:latest bye-world:8000
如果成功,沒有任何提示,再次檢視本地所有映象:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 18.04 7698f282e524 7 days ago 69.9MB bye-world 8000 fce289e99eb9 4 months ago 1.84kB hello-world latest fce289e99eb9 4 months ago 1.84kB
看,出現了bye-world映象,但我們可沒有新建或者下載映象,這就是我們剛才為hello-World建立的新標籤,看著他們相同的映象id你就知道他們是同一個映象了。接下來嘗試刪除映象:
$ docker rmi bye-world:8000 Untagged: bye-world:8000 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 18.04 7698f282e524 7 days ago 69.9MB hello-world latest fce289e99eb9 4 months ago 1.84kB
果然如上文所說,bye-world:8000被刪除了,但事實上它所指向的映象被沒有被真正刪除,因為這個映象還有一個標籤存在。我們繼續引數刪除hello-world:latest映象:
$ docker rmi hello-world:latest Error response from daemon: conflict: unable to remove repository reference "hello-world:latest" (must force) - container 53c855a9d4a9 is using its referenced image fce289e99eb9
懵逼了,失敗了,咋回事?因為尚有依賴於該映象的容器存在,所以產生衝突。這時候要刪除映象,就必須新增-f引數,強制執行:
$ docker rmi -f hello-world:latest Untagged: hello-world:latest Untagged: hello-world@sha256:6f744a2005b12a704d2608d8070a494ad1145636eeb74a570c56b94d94ccdbfc Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 18.04 7698f282e524 7 days ago 69.9MB
只剩下一個ubuntu映象,證明刪除成功。
3 建立映象
建立映象的方法有三種:基於已有映象的容器建立映象、基於dockerfile建立、基於本地模板匯入,這裡我們只介紹前兩種。
3.1 基於已有映象容器建立映象
基於已有映象容器建立映象需通過docker commit命令,命令格式如下:
$ docker commit [選項] 容器名或容器id [<倉庫名>[:<標籤名>]]
在使用docker commit命令建立映象之前,我們先得有一個容器。
$ docker run -it ubuntu:18.04 /bin/bash root@001b647aad4e:/#
docker run命令時使用映象建立一個容器的命令,具體個引數什麼含義,我們後面繼續學習。可以看到,執行這一命令後,啟動了一個id為001b647aad4e的容器,記住這一id,後面要用到。
我們繼續在這一容器裡git環境:
root@001b647aad4e:/# git --version bash: git: command not found
可以看到,剛建立的容器裡面剛開始是沒有git的,我們安裝一個:
root@001b647aad4e:/# apt-get update root@001b647aad4e:/# apt install git root@001b647aad4e:/# git --version git version 2.17.1
可以看到,git安裝成功。
退出容器,然後使用剛才的容器建立一個映象。
root@001b647aad4e:/# exit exit $ docker commit -m "Add git in ubuntu18.04" -a "God" 001b647aad4e ubuntu_git:1.0 sha256:30e6c7c480dc44743f0f030f4904089fb8568ad2333f8de3a22c4f6a71fdb451
成功建立映象,並返回了映象id資訊。
檢視一下本地映象:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu_git 1.0 30e6c7c480dc About a minute ago 189MB ubuntu 18.04 7698f282e524 8 days ago 69.9MB
可以看到,映象建立成功。以ubuntu_git為基礎,建立一個容器,新容器也會有git環境,換句話說,docker commit相當於是對001b647aad4e進行了一次備份。
docker commit命令建立映象雖然簡單直觀,但是在時間生產中並不建議用,因為使用docker commit命令建立的映象無法追蹤映象的建立過程,造成映象建立過程難以重複、維護困難,且容易出現映象臃腫的映象。所以,在實際應用中,更推薦使用下一小節要說到的使用dockerfile檔案建立映象的方法。
3.2 使用dockerfile建立映象
dockerfile是一個文字檔案,通過每一條指令構建映象一層,或者說dockerfile每一條指令定義了映象每一層如何構建,所以,使用dockerfile建立映象的過程完全是透明的、可重複的,很好的你不了docker commit命令建立映象的不足。
還以上一小節中定製一個包含git環境的映象為例,不過這次我們使用dockerfile來建立。
首先建立一個目錄作為建立映象的上下文路徑,並進入該目錄:
$ mkdir ubuntu_dockerfile_git
$ cd ubuntu_dockerfile_git/
然後建立建立dockerfile檔案:
$ touch dockerfile
開始編輯dockerfile,在dockerfile內寫入一下內容:
FROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y git \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
先來解釋一下上面寫入dockerfile檔案的內容:
FROM ubuntu:18.04的意思是以ubuntu:18.04映象為基礎來構建新的映象,每一個新的映象,都必須有一個基礎映象,FROM命就是用於指定基礎映象,而且需要注意的是,FROM命令必須位於整個過程的第一行。
第二行的RUN命令是用來執行命令列操作。那為何上面的RUN命令執行的4條命令列操作都用一個RUN命令來執行呢?事實上,每個命令列操作都使用一個RUN命令來執行也不會出錯,但,上面提到過,dockerfile中,每一條指令都會建立一層,如果每一條命令列操作的用一個RUN命令執行,這種寫法就建立了4層,建立出來的映象就顯得臃腫,也增加了部署時間,另外從功能上來說,這4條命令列操作都是為了安裝一個git,沒必要拆分。docker映象總層數不得操作127層。
現在可以用建立好的dockerfile檔案建立映象了,使用的是docker build命令,命令格式如下:
docker build [選項] <上下文路徑/URL>
假定我們將要建立映象的映象名為ubuntu_dockerfile_git,使用docker build如下:
$ docker build -t ubuntu_dockerfile_git:1.0 .
在一大段的輸出之後可以看到:
Successfully built 6e703a3b11e2
Successfully tagged ubuntu_dockerfile_git:1.0
說明映象建立成功。再次檢視本地映象:
$ docker images $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu_dockerfile_git 1.0 6e703a3b11e2 About a minute ago 163MB ubuntu_git 1.0 30e6c7c480dc 20 hours ago 189MB ubuntu 18.04 7698f282e524 9 days ago 69.9MB
果然有剛建立的ubuntu_dockerfile_git,我們用它來建立一個容器:
$ docker run -it ubuntu_dockerfile_git:1.0 /bin/bash root@18c03ae954ab:/# git --version git version 2.17.1
可以看到,剛啟動的容器裡果然有git。
dockerfile是用的最多的一種映象建立方法,涉及到的內容也較多,在上面的應用中,我們只介紹了FROM、RUN指令,除此之外還有COPY、CMD、ADD等眾多指令沒有涉及到,大家可以參考純潔的微笑前輩的這篇部落格,寫得很詳細且通俗易懂。
4 總結
本篇博文介紹了對docker映象的管理,包括映象檢視、刪除、建立等操作。但作為docker的核心內容,映象管理可絕不僅僅包含這點點只是,例如映象存出、載入、上傳等內容就沒有涉及到。本文只作為入門階段拋磚引玉吧。