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最新版本:
注意:latest標籤會動態跟隨最新版本變動,這意味着鏡像內容也是動態變化的,因此出於穩定性考慮,在生產環境中,不要在生產環境中使用latest標籤。
pull命令默認從官方docker hub倉庫中下載鏡像,因此,上行命令中並無指定完整倉庫名,若是須要從其餘非官方倉庫下載鏡像,則須要指定完整倉庫名,例如,從網易很是的鏡像源中下載ubuntu:18.04鏡像:
$ docker pull hub.c.163.com/public/ubuntu18.04
2.2 查看及查找鏡像
(1)查看本機上全部鏡像基本信息:
(2)查看指定鏡像詳細信息
$ docker [image] inspect 倉庫名:標籤
例:查看上文中下載的ubuntu:18.04鏡像詳細信息
$ docker inspect ubuntu:18.04
(3)查看鏡像各層建立信息
(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文件:
開始編輯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的核心內容,鏡像管理可毫不僅僅包含這點點只是,例如鏡像存出、載入、上傳等內容就沒有涉及到。本文只做爲入門階段拋磚引玉吧。