docker教程——鏡像使用(四)

一、獲取鏡像

        Docker Hub 上有大量的高質量的鏡像可以用,這裏我們就說一下怎麼獲取這些鏡像。從 Docker 鏡像倉庫獲取鏡像的命令是 docker pull。其命令格式爲:

docker pull [選項] [Docker Registry 地址[:端口號]/]倉庫名[:標籤]

具體的選項可以通過 docker pull --help 命令看到,這裏我們說一下鏡像名稱的格式。

  • Docker 鏡像倉庫地址:地址的格式一般是 <域名/IP>[:端口號]。默認地址是 Docker Hub。
  • 倉庫名:如之前所說,這裏的倉庫名是兩段式名稱,即 <用戶名>/<軟件名>。對於 Docker Hub,如果不給出用戶名,則默認爲 library,也就是官方鏡像。

比如:

$ docker pull ubuntu:18.04

上面的命令中沒有給出 Docker 鏡像倉庫地址,因此將會從 Docker Hub 獲取鏡像。而鏡像名稱是 ubuntu:18.04,因此將會獲取官方鏡像 library/ubuntu 倉庫中標籤爲 18.04 的鏡像。

從下載過程中可以看到我們之前提及的分層存儲的概念,鏡像是由多層存儲所構成。下載也是一層層的去下載,並非單一文件。下載過程中給出了每一層的 ID 的前 12 位。並且下載結束後,給出該鏡像完整的 sha256 的摘要,以確保下載一致性。
        有了鏡像後,我們就能夠以這個鏡像爲基礎啓動並運行一個容器。以上面的 ubuntu:18.04 爲例,如果我們打算啓動裏面的 bash 並且進行交互式操作的話,可以執行下面的命令。

$ docker run -it --rm \
    ubuntu:18.04 \
    bash
root@e7009c6ce357:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

docker run 就是運行容器的命令,具體格式我們會在 容器 一節進行詳細講解,我們這裏簡要的說明一下上面用到的參數。

  • -it:這是兩個參數,一個是 -i:交互式操作,一個是 -t 終端。我們這裏打算進入 bash 執行一些命令並查看返回結果,因此我們需要交互式終端。
  • --rm:這個參數是說容器退出後隨之將其刪除。默認情況下,爲了排障需求,退出的容器並不會立即刪除,除非手動 docker rm。我們這裏只是隨便執行個命令,看看結果,不需要排障和保留結果,因此使用 --rm 可以避免浪費空間。
  • ubuntu:18.04:這是指用 ubuntu:18.04 鏡像爲基礎來啓動容器。
  • bash:放在鏡像名後的是命令,這裏我們希望有個交互式 Shell,因此用的是 bash。

進入容器後,我們可以在 Shell 下操作,執行任何所需的命令。這裏,我們執行了 cat /etc/os-release,這是 Linux 常用的查看當前系統版本的命令,從返回的結果可以看到容器內是 Ubuntu 18.04.1 LTS 系統。最後我們通過 exit 退出了這個容器。
        當我們在本地主機上使用一個不存在的鏡像時 Docker 就會自動下載這個鏡像。如果我們想預先下載這個鏡像,我們可以使用 docker pull 命令來下載它。

runoob@runoob:~# docker pull training/webapp

下載完成後,我們可以直接使用這個鏡像來運行容器。我們可以從 Docker Hub 網站來搜索鏡像,Docker Hub 網址爲: https://hub.docker.com/ 。同時我們也可以使用 docker search 命令來搜索鏡像。比如我們需要一個httpd的鏡像來作爲我們的web服務。我們可以通過 docker search 命令搜索 httpd 來尋找適合我們的鏡像。


附加:當我們從docker鏡像倉庫中下載的鏡像不能滿足我們的需求時,我們可以通過以下兩種方式對鏡像進行更改。

  • 從已經創建的容器中更新鏡像,並且提交這個鏡像
  • 使用 Dockerfile 指令來創建一個新的鏡像

二、本地鏡像

        當運行容器時,使用的鏡像如果在本地中不存在,docker 就會自動從 docker 鏡像倉庫中下載,默認是從 Docker Hub 公共鏡像源下載。我們可以使用 docker images 來列出本地主機上的鏡像。

選項說明:

選項 說明
REPOSITORY 表示鏡像的倉庫源
TAG 鏡像的標籤
IMAGE ID 鏡像ID
CREATED 鏡像創建時間
SIZE 鏡像大小

        同一倉庫源可以有多個 TAG,代表這個倉庫源的不同個版本,如ubuntu倉庫源裏,有15.10、14.04等多個不同的版本,我們使用 REPOSITORY:TAG 來定義不同的鏡像。所以,我們如果要使用版本爲15.10的ubuntu系統鏡像來運行容器時,命令如下:

runoob@runoob:~$ docker run -t -i ubuntu:15.10 /bin/bash

如果你不指定一個鏡像的版本標籤,例如你只使用 ubuntu,docker 將默認使用 ubuntu:latest 鏡像。

1、虛懸鏡像

        上面的鏡像列表中,還可以看到一個特殊的鏡像,這個鏡像既沒有倉庫名,也沒有標籤,均爲 <none>。這個鏡像原本是有鏡像名和標籤的,原來爲 mongo:3.2,隨着官方鏡像維護,發佈了新版本後,重新 docker pull mongo:3.2 時,mongo:3.2 這個鏡像名被轉移到了新下載的鏡像身上,而舊的鏡像上的這個名稱則被取消,從而成爲了 <none>。除了 docker pull 可能導致這種情況,docker build 也同樣可以導致這種現象。由於新舊鏡像同名,舊鏡像名稱被取消,從而出現倉庫名、標籤均爲 <none> 的鏡像。這類無標籤鏡像也被稱爲 虛懸鏡像(dangling image) ,可以用下面的命令專門顯示這類鏡像:

$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 00285df0df87 5 days ago 342 MB

一般來說,虛懸鏡像已經失去了存在的價值,是可以隨意刪除的,可以用下面的命令刪除。

$ docker image prune

2、中間層鏡像

        爲了加速鏡像構建、重複利用資源,Docker 會利用 中間層鏡像。所以在使用一段時間後,可能會看到一些依賴的中間層鏡像。默認的 docker image ls 列表中只會顯示頂層鏡像,如果希望顯示包括中間層鏡像在內的所有鏡像的話,需要加 -a 參數。

$ docker image ls -a

        這樣會看到很多無標籤的鏡像,與之前的虛懸鏡像不同,這些無標籤的鏡像很多都是中間層鏡像,是其它鏡像所依賴的鏡像。這些無標籤鏡像不應該刪除,否則會導致上層鏡像因爲依賴丟失而出錯。實際上,這些鏡像也沒必要刪除,因爲之前說過,相同的層只會存一遍,而這些鏡像是別的鏡像的依賴,因此並不會因爲它們被列出來而多存了一份,無論如何你也會需要它們。只要刪除那些依賴它們的鏡像後,這些依賴的中間層鏡像也會被連帶刪除。

3、列出部分鏡像

        不加任何參數的情況下,docker image ls 會列出所有頂級鏡像,但是有時候我們只希望列出部分鏡像。docker image ls 有好幾個參數可以幫助做到這個事情。

  • 根據倉庫名列出鏡像
$ docker image ls ubuntu
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 f753707788c5 4 weeks ago 127 MB
ubuntu latest f753707788c5 4 weeks ago 127 MB
  • 列出特定的某個鏡像,也就是說指定倉庫名和標籤
$ docker image ls ubuntu:18.04
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 f753707788c5 4 weeks ago 127 MB

除此以外,docker image ls 還支持強大的過濾器參數 --filter,或者簡寫 -f。之前我們已經看到了使用過濾器來列出虛懸鏡像的用法,它還有更多的用法。比如,我們希望看到在 mongo:3.2 之後建立的鏡像,可以用下面的命令:

$ docker image ls -f since=mongo:3.2
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 5f515359c7f8 5 days ago 183 MB
nginx latest 05a60462f8ba 5 days ago 181 MB

想查看某個位置之前的鏡像也可以,只需要把 since 換成 before 即可。此外,如果鏡像構建時,定義了 LABEL,還可以通過 LABEL 來過濾。

$ docker image ls -f label=com.example.version=0.1
...

4、以特定格式顯示

        默認情況下,docker image ls 會輸出一個完整的表格,但是我們並非所有時候都會需要這些內容。比如,剛纔刪除虛懸鏡像的時候,我們需要利用 docker image ls 把所有的虛懸鏡像的 ID 列出來,然後纔可以交給 docker image rm 命令作爲參數來刪除指定的這些鏡像,這個時候就用到了 -q 參數。

$ docker image ls -q
5f515359c7f8
05a60462f8ba
fe9198c04d62
00285df0df87
f753707788c5
f753707788c5
1e0c3dd64ccd
--filter 配合 -q 產生出指定範圍的 ID 列表,然後送給另一個 docker 命令作爲參數,從而針對這組實體成批的進行某種操作的做法在 Docker 命令行使用過程中非常常見,不僅僅是鏡像,將來我們會在各個命令中看到這類搭配以完成很強大的功能。因此每次在文檔看到過濾器後,可以多注意一下它們的用法。

另外一些時候,我們可能只是對錶格的結構不滿意,希望自己組織列;或者不希望有標題,這樣方便其它程序解析結果等,這就用到了 Go 的模板語法。比如,下面的命令會直接列出鏡像結果,並且只包含鏡像ID和倉庫名:

$ docker image ls --format "{{.ID}}: {{.Repository}}"
5f515359c7f8: redis
05a60462f8ba: nginx
fe9198c04d62: mongo
00285df0df87: <none>
f753707788c5: ubuntu
f753707788c5: ubuntu
1e0c3dd64ccd: ubuntu

或者打算以表格等距顯示,並且有標題行,和默認一樣,不過自己定義列:

$ docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID REPOSITORY TAG
5f515359c7f8 redis latest
05a60462f8ba nginx latest
fe9198c04d62 mongo 3.2
00285df0df87 <none> <none>
f753707788c5 ubuntu 18.04
f753707788c5 ubuntu latest

三、刪除本地鏡像

        如果要刪除本地的鏡像,可以使用 docker image rm 命令,其格式爲:

$ docker image rm [選項] <鏡像1> [<鏡像2> ...]

其中,<鏡像> 可以是 鏡像短 ID、鏡像長 ID、鏡像名 或者 鏡像摘要。比如我們有這麼一些鏡像:

$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 0584b3d2cf6d 3 weeks ago 196.5 MB
redis alpine 501ad78535f0 3 weeks ago 21.03 MB
docker latest cf693ec9b5c7 3 weeks ago 105.1 MB
nginx latest e43d811ce2f4 5 weeks ago 181.5 MB

我們可以用鏡像的完整 ID,也稱爲 長 ID,來刪除鏡像。使用腳本的時候可能會用長 ID,但是人工輸入就太累了,所以更多的時候是用 短 ID 來刪除鏡像。docker image ls 默認列出的就已經是短 ID 了,一般取前3個字符以上,只要足夠區分於別的鏡像就可以了。比如這裏,如果我們要刪除 redis:alpine 鏡像,可以執行:

$ docker image rm 501
Untagged: redis:alpine
Untagged: redis@sha256:f1ed3708f538b537eb9c2a7dd50dc90a706f7debd7e1196c9264edeea521a86d
Deleted: sha256:501ad78535f015d88872e13fa87a828425117e3d28075d0c117932b05bf189b7
Deleted: sha256:96167737e29ca8e9d74982ef2a0dda76ed7b430da55e321c071f0dbff8c2899b
Deleted: sha256:32770d1dcf835f192cafd6b9263b7b597a1778a403a109e2cc2ee866f74adf23
Deleted: sha256:127227698ad74a5846ff5153475e03439d96d4b1c7f2a449c7a826ef74a2d2fa
Deleted: sha256:1333ecc582459bac54e1437335c0816bc17634e131ea0cc48daa27d32c75eab3
Deleted: sha256:4fc455b921edf9c4aea207c51ab39b10b06540c8b4825ba57b3feed1668fa7c7

我們也可以用鏡像名,也就是 <倉庫名>:<標籤>,來刪除鏡像。

$ docker image rm centos
Untagged: centos:latest
Untagged: centos@sha256:b2f9d1c0ff5f87a4743104d099a3d561002ac500db1b9bfa02a783a46e0d366c
Deleted: sha256:0584b3d2cf6d235ee310cf14b54667d889887b838d3f3d3033acd70fc3c48b8a
Deleted: sha256:97ca462ad9eeae25941546209454496e1d66749d53dfa2ee32bf1faabd239d38

當然,更精確的是使用 鏡像摘要 刪除鏡像。

$ docker image ls --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
node slim sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228 6e0c4c8e3913 3 weeks ago 214 MB

$ docker image rm node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228
Untagged: node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228

Untagged 和 Deleted

     如果觀察上面這幾個命令的運行輸出信息的話,你會注意到刪除行爲分爲兩類,一類是 Untagged,另一類是 Deleted。我們之前介紹過,鏡像的唯一標識是其 ID 和摘要,而一個鏡像可以有多個標籤。

     因此當我們使用上面命令刪除鏡像的時候,實際上是在要求刪除某個標籤的鏡像。所以首先需要做的是將滿足我們要求的所有鏡像標籤都取消,這就是我們看到的 Untagged 的信息。因爲一個鏡像可以對應多個標籤,因此當我們刪除了所指定的標籤後,可能還有別的標籤指向了這個鏡像,如果是這種情況,那麼 Delete 行爲就不會發生。所以並非所有的 docker image rm 都會產生刪除鏡像的行爲,有可能僅僅是取消了某個標籤而已。

     除了鏡像依賴以外,還需要注意的是容器對鏡像的依賴。如果有用這個鏡像啓動的容器存在(即使容器沒有運行),那麼同樣不可以刪除這個鏡像。之前講過,容器是以鏡像爲基礎,再加一層容器存儲層,組成這樣的多層存儲結構去運行的。因此該鏡像如果被這個容器所依賴的,那麼刪除必然會導致故障。如果這些容器是不需要的,應該先將它們刪除,然後再來刪除鏡像。

        像其它可以承接多個實體的命令一樣,可以使用 docker image ls -q 來配合使用 docker image rm,這樣可以成批的刪除希望刪除的鏡像。我們在“鏡像列表”章節介紹過很多過濾鏡像列表的方式都可以拿過來使用。比如,我們需要刪除所有倉庫名爲 redis 的鏡像:

$ docker image rm $(docker image ls -q redis)

或者刪除所有在 mongo:3.2 之前的鏡像:

$ docker image rm $(docker image ls -q -f before=mongo:3.2)

四、構建鏡像

        我們使用命令 docker build , 從零開始來創建一個新的鏡像。爲此,我們需要創建一個 Dockerfile 文件,其中包含一組指令來告訴 Docker 如何構建我們的鏡像。

FROM centos:6.7
MAINTAINER Fisher "[email protected]"
​
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd docker
RUN /bin/echo 'docker:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D

        每一個指令都會在鏡像上創建一個新的層,每一個指令的前綴都必須是大寫的。第一條FROM,指定使用哪個鏡像源;RUN 指令告訴docker 在鏡像內執行命令,安裝了什麼......

        然後,我們使用 Dockerfile 文件,通過 docker build 命令來構建一個鏡像。

docker build -t docker/centos:6.7 .

參數說明:

  • -t :指定要創建的目標鏡像名
  • . :Dockerfile 文件所在目錄,可以指定Dockerfile 的絕對路徑

使用docker images 查看創建的鏡像已經在列表中存在

下面我們可以使用新的鏡像來創建容器

runoob@runoob:~$ docker run -t -i docker/centos:6.7 /bin/bash

從上面看到新鏡像已經包含我們創建的用戶docker。

五、設置鏡像標籤

        我們可以使用 docker tag 命令,爲鏡像添加一個新的標籤。

runoob@runoob:~$ docker tag a575d5581987 docker/centos:dev

使用 docker images 命令可以看到,ID爲860c279d2fec的鏡像多一個標籤。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章