原文地址:http://blog.jboost.cn/docker-4.htmlphp
在Docker中,應用是經過容器來運行的,而容器的運行是基於鏡像的,相似面向對象設計中類與對象的關係——沒有類的定義就談不上實例的建立與使用,沒有鏡像的定義就談不上容器的建立與運行。
html
鏡像從哪裏來,通常兩個途徑,一是公共鏡像庫,如官方鏡像庫Docker Hub,上面有大量的高質量的鏡像直接可拿來用;二是自定義,咱們可基於一個已有鏡像,在其基礎上增長一些層(還記得鏡像的分層存儲特性吧),而後構建造成本身的鏡像。mysql
若是咱們知道某個鏡像的名稱,則可直接經過docker pull
來下載鏡像到本地,如ubuntu、redis、nginx等,docker pull
命令的格式以下(中括號表示可有可沒有)linux
docker pull [選項] [Docker Registry的地址[:端口號]/]倉庫名[:標籤]
其中選項可設置: nginx
Docker Registry的地址即鏡像倉庫地址,通常爲域名或IP加端口號,若是不指定則默認爲Docker Hub;倉庫名包含兩部分,<用戶名>/<軟件名>,對於Docker Hub,若是不給出用戶名,則默認爲library,表示官方提供;標籤通常是對應軟件的版本號,若是不指定則默認爲latest。web
好比咱們要下一個nginx鏡像,則可執行以下命令redis
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx fc7181108d40: Already exists d2e987ca2267: Pull complete 0b760b431b11: Pull complete Digest: sha256:48cbeee0cb0a3b5e885e36222f969e0a2f41819a68e07aeb6631ca7cb356fed1 Status: Downloaded newer image for nginx:latest
這裏咱們沒有指定選項,也沒有指定鏡像倉庫地址,那麼默認會從Docker Hub獲取鏡像(但Docker Hub因爲在國外,速度比較慢,因此通常要設置國內加速器,參考Docker筆記(三):Docker安裝與配置第二部分:配置國內鏡像),也沒有給出用戶名,因此默認是library(第三行),沒有指定標籤,因此默認是latest(第二行),由第四至第六行可見,這個鏡像包含三個層,而且第一個層已經存在了(以前下載的鏡像已經包含了這個層, 直接複用),鏡像分層的概念及層的複用,應該已經理解了。sql
若是咱們不知道鏡像的完整名稱怎麼辦,那就搜索一下,有兩個途徑,一是經過命令,假設咱們記不起nginx全稱了, 只記得ngi
,則可經過以下命令搜索docker
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker search ngi NAME DESCRIPTION STARS OFFICIAL AUTOMATED nginx Official build of Nginx. 11693 [OK] jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 1628 [OK] richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of… 726 [OK] bitnami/nginx Bitnami nginx Docker Image 69 [OK] linuxserver/nginx An Nginx container, brought to you by LinuxS… 69 tiangolo/nginx-rtmp Docker image with Nginx using the nginx-rtmp… 48 [OK] nginx/nginx-ingress NGINX Ingress Controller for Kubernetes 20 nginxdemos/hello NGINX webserver that serves a simple page co… 18 [OK] jlesage/nginx-proxy-manager Docker container for Nginx Proxy Manager 17 [OK] schmunk42/nginx-redirect A very simple container to redirect HTTP tra… 17 [OK] crunchgeek/nginx-pagespeed Nginx with PageSpeed + GEO IP + VTS + more_s… 13 blacklabelops/nginx Dockerized Nginx Reverse Proxy Server. 12 [OK] ...
該命令會從Docker Hub搜索鏡像名包含ngi
的鏡像,其中STARS表示收藏用戶數,OFFICIAL爲[OK]表示官方提供的鏡像,AUTOMATED [OK]表示由自動構建生成,通常選擇STARS最多,官方提供的鏡像。 ubuntu
這種方式獲取到的信息有限,好比具體包含哪些版本不知道。還有一個途徑是直接在Docker Hub網站上搜索,打開 https://hub.docker.com , 在搜索框輸入ngi
,以下圖
則會列出全部知足條件的鏡像,點開nginx
結果連接,能夠看到提供的版本(經過版本連接能夠查看定義對應鏡像的Dockerfile),及相應的文檔說明。這種方式獲取的信息更加全面,因此推薦這種方式!
另外,當咱們沒有執行docker pull
,直接經過docker run xx
來運行一個容器時,若是沒有對應的鏡像,則會先自動下載鏡像,再基於鏡像啓動一個容器,好比咱們在Docker筆記(三):Docker安裝與配置中檢驗docker是否安裝成功時運行的hello-world
將鏡像下載到本地後,咱們能夠基於鏡像來建立、運行容器,及對鏡像進行管理。
查看本地鏡像
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest f68d6e55e065 2 weeks ago 109MB mysql latest c7109f74d339 5 weeks ago 443MB hello-world latest fce289e99eb9 6 months ago 1.84kB
上面各列依次列出了鏡像名稱、標籤(版本)、鏡像ID、建立時間、鏡像大小。鏡像能夠擁有多個標籤(版本)。鏡像的大小總和通常要大於實際的磁盤佔有量,爲何?回憶一下鏡像的分層存儲概念,層是能夠複用的,某個層其中一個鏡像有了,另外一個鏡像就不會再下載了。口說無憑,咱們來驗證下,docker system df
可列出鏡像、容器、數據卷所佔用的空間
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 3 1 497.1MB 497.1MB (99%) Containers 1 0 0B 0B Local Volumes 0 0 0B 0B Build Cache 0 0 0B 0B
經過docker image ls
列出的各鏡像大小總共約552MB,但這裏列出的鏡像大小隻有約497MB,這下有憑有據了吧。
根據條件列出鏡像
docker image ls nginx # 根據名稱列出鏡像 docker image ls nginx:latest # 根據名稱與標籤列出鏡像 docker image ls -f since=hello-world:latest # -f 是--filter的縮寫,過濾器參數,列出在hello-world:latest以後創建的鏡像,before=hello-world:latest則查看以前創建的鏡像
指定顯示格式
docker image ls -q # 只顯示鏡像ID docker image ls --digests # 列出鏡像摘要 docker image ls --format "{{.ID}}: {{.Repository}}" # 使用Go的模板語法格式化顯示,這裏顯示格式爲 鏡像ID:鏡像名稱 docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}" # 本身定義表格格式
虛懸鏡像
有時候會看到某些鏡像既沒有倉庫名,也沒有標籤,均爲 <none>
。這些鏡像本來是有鏡像名和標籤的,隨着官方鏡像維護,發佈了新版本後(新版本會複用以前的鏡像名稱與標籤,通常是bug修復版),從新docker pull xx
時, 這個鏡像名被轉移到了新下載的鏡像身上,而舊的鏡像上的這個名稱則被取消,從而成爲了<none>
。除了docker pull
可能致使這種狀況, docker build
也一樣能夠致使這種現象。因爲新舊鏡像同名,舊鏡像名稱被取消,從而出現倉庫名、標籤均爲 <none>
的鏡像。這類無標籤鏡像被稱爲虛懸鏡像(dangling image) ,能夠用下面的命令專門顯示這類鏡像:
docker image ls -f dangling=true
通常虛懸鏡像沒什麼意義了,能夠經過以下命令刪除
docker image prune
中間層鏡像
爲了加速鏡像構建、重複利用資源,Docker會利用中間層鏡像。因此在使用一段時間後,可能會看到一些依賴的中間層鏡像。默認的docker image ls
列表中只會顯示頂層鏡像,若是但願顯示包括中間層鏡像在內的全部鏡像的話,能夠加 -a
$ docker image ls -a
這樣會看到不少無標籤的鏡像,與虛懸鏡像不一樣,這些無標籤的鏡像不少都是中間層鏡像,是其它鏡像所依賴的鏡像。這些無標籤鏡像不該該刪除,不然會致使上層鏡像由於依賴丟失而出錯。實際上,這些鏡像也不必刪除,由於相同的層只會存一遍,而這些鏡像是別的鏡像的依賴,所以並不會由於它們被列出來而多存了一份,不管如何你也會須要它們。只要刪除那些依賴它們的鏡像後,這些依賴的中間層鏡像也會被連帶刪除。
刪除鏡像
刪除鏡像命令格式
docker image rm [選項] <鏡像1> [<鏡像2> ...]
選項能夠設置:
<鏡像1>、<鏡像2> 等能夠是鏡像的名稱,鏡像的全ID,也能夠是鏡像ID的前面幾個數字(只要與其它鏡像區分開來就行),或者是鏡像摘要。 如刪除鏡像名稱爲mysql的鏡像
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker image rm mysql Untagged: mysql:latest Untagged: mysql@sha256:415ac63da0ae6725d5aefc9669a1c02f39a00c574fdbc478dfd08db1e97c8f1b Deleted: sha256:c7109f74d339896c8e1a7526224f10a3197e7baf674ff03acbab387aa027882a Deleted: sha256:35d60530f024aa75c91a123a69099f7f6eaf5ad7001bb983f427f674980d8482 Deleted: sha256:49d8bb533eee600076e3a513a203ee24044673fcef0c1b79e088b2ba43db2c17 ...
由上面命令的執行結果可見,刪除鏡像包括另個行爲:Untagged、Deleted。
當咱們使用上面命令來刪除鏡像的時候,其實是在要求刪除某個/某些標籤的鏡像。因此首先須要作的是將知足要求的全部鏡像標籤都取消,這就是Untagged的行爲。一個鏡像能夠對應多個標籤,所以當咱們刪除了所指定的標籤後,可能還有別的標籤指向了這個鏡像,若是是這種狀況,那麼Delete行爲就不會發生,僅僅是取消了這個鏡像的符合要求的全部標籤。因此並不是全部的docker image rm
都會產生刪除鏡像的行爲,有可能僅僅是取消了某個標籤而已。
當該鏡像全部的標籤都被取消了,該鏡像極可能就失去了存在的意義,所以會觸發刪除行爲。鏡像是多層存儲結構,所以在刪除的時候也是從上層向基礎層方向依次進行判斷刪除。若是某個其它鏡像正依賴於當前鏡像的某一層,這種狀況,依舊不會觸發刪除該層的行爲。直到沒有任何鏡像依賴當前層時,纔會真實的刪除當前層。
另外還須要注意是容器對鏡像的依賴。若是基於鏡像啓動的容器存在(即便容器沒有運行處於中止狀態) ,一樣不能夠刪除這個鏡像。咱們以前說了容器是以鏡像爲基礎,再加一層容器存儲層組成的多層存儲結構去運行的。因此若是這些容器是不須要的,應該先將它們刪除,而後再來刪除鏡像。
經過組合命令來刪除
docker image rm $(docker image ls -q nginx) # 刪除鏡像名稱爲nginx的全部鏡像 docker image rm $(docker image ls -q -f since=hello-world:latest) # 刪除全部在hello-world:latest以後創建的鏡像
本文對鏡像的獲取及本地鏡像的基本管理作了介紹,本文鏡像的獲取途徑都是從鏡像倉庫直接獲取,鏡像的另外一個獲取途徑即是自定義,接下來會經過實例來進行介紹,歡迎關注。
個人我的博客地址:http://blog.jboost.cn
個人微信公衆號:jboost-ksxy (一個不僅有技術乾貨的公衆號,歡迎關注,及時獲取更新內容)
———————————————————————————————————————————————————————————