Docker 鏡像簡(jiǎn)介

原文發(fā)布在:http://cizixs.com/2016/04/06/docker-images,轉(zhuǎn)載請(qǐng)注明出處。

這篇文章主要講講 docker 中鏡像有關(guān)的知識(shí),將涉及到下面幾個(gè)方面:

  • docker images 命令的使用
  • docker 和 registry 交互的過(guò)程腋逆,pull 命令到底做了什么
  • docker storage driver
  • aufs 的格式和實(shí)際的組織結(jié)構(gòu)
  • Dockerfile 原語(yǔ)和 docker 鏡像之間的關(guān)系

簡(jiǎn)介

一圖看盡 docker 鏡像
  • docker 鏡像代表了容器的文件系統(tǒng)里的內(nèi)容,是容器的基礎(chǔ)侈贷,鏡像一般是通過(guò) Dockerfile 生成的
  • docker 的鏡像是分層的惩歉,所有的鏡像(除了基礎(chǔ)鏡像)都是在之前鏡像的基礎(chǔ)上加上自己這層的內(nèi)容生成的
  • 每一層鏡像的元數(shù)據(jù)都是存在 json 文件中的,除了靜態(tài)的文件系統(tǒng)之外俏蛮,還會(huì)包含動(dòng)態(tài)的數(shù)據(jù)

使用鏡像:docker image 命令

docker client 提供了各種命令和 daemon 交互撑蚌,來(lái)完成各種任務(wù),其中和鏡像有關(guān)的命令有:

  • docker images :列出 docker host 機(jī)器上的鏡像搏屑,可以使用 -f 進(jìn)行過(guò)濾
  • docker build:從 Dockerfile 中構(gòu)建出一個(gè)鏡像
  • docker history:列出某個(gè)鏡像的歷史
  • docker import:從 tarball 中創(chuàng)建一個(gè)新的文件系統(tǒng)鏡像
  • docker pull:從 docker registry 拉去鏡像
  • docker push:把本地鏡像推送到 registry
  • docker rmi: 刪除鏡像
  • docker save:把鏡像保存為 tar 文件
  • docker search:在 docker hub 上搜索鏡像
  • docker tag:為鏡像打上 tag 標(biāo)記

從上面這么多命令中争涌,我們就可以看出來(lái),docker 鏡像在整個(gè)體系中的重要性辣恋。

下載鏡像:pull 和 push 鏡像到底在做什么第煮?

如果了解 docker 結(jié)構(gòu)的話,你會(huì)知道 docker 是典型的 C/S 架構(gòu)抑党。平時(shí)經(jīng)常使用的 docker pulldocker run 都是客戶端的命令撵摆,最終這些命令會(huì)發(fā)送到 server 端(docker daemon 啟動(dòng)的時(shí)候會(huì)啟動(dòng)docker server)進(jìn)行處理底靠。下載鏡像還會(huì)和 Registry 打交道,下面我們就說(shuō)說(shuō)使用 docker pull 的時(shí)候特铝,docker 到底在做些什么暑中!

docker client 組織配置和參數(shù)壹瘟,把 pull 指令發(fā)送給 docker server,server 端接收到指令之后會(huì)交給對(duì)應(yīng)的 handler鳄逾。handler 會(huì)新開(kāi)一個(gè) CmdPull job 運(yùn)行稻轨,這個(gè) job 在 docker daemon 啟動(dòng)的時(shí)候被注冊(cè)進(jìn)來(lái),所以控制權(quán)就到了 docker daemon 這邊雕凹。docker daemon 是怎么根據(jù)傳過(guò)來(lái)的 registry 地址殴俱、repo 名、image 名和tag 找到要下載的鏡像呢枚抵?具體流程如下:

  1. 獲取 repo 下面所有的鏡像 id:GET /repositories/{repo}/images
  2. 獲取 repo 下面所有 tag 的信息: GET /repositories/{repo}/tags
  3. 根據(jù) tag 找到對(duì)應(yīng)的鏡像 uuid线欲,并下載該鏡像
    • 獲取該鏡像的 history 信息,并依次下載這些鏡像層: GET /images/{image_id}/ancestry
    • 如果這些鏡像層已經(jīng)存在汽摹,就 skip李丰,不存在的話就繼續(xù)
    • 獲取鏡像層的 json 信息:GET /images/{image_id}/json
    • 下載鏡像內(nèi)容: GET /images/{image_id}/layer
    • 下載完成后,把下載的內(nèi)容存放到本地的 UnionFS 系統(tǒng)
    • 在 TagStore 添加剛下載的鏡像信息

存儲(chǔ)鏡像:docker storage 介紹

在上一個(gè)章節(jié)提到下載的鏡像會(huì)保存起來(lái)逼泣,這一節(jié)就講講到底是怎么存的趴泌。

UnionFS 和 aufs

如果對(duì) docker 有所了解的話,會(huì)聽(tīng)說(shuō)過(guò) UnionFS 的概念拉庶,這是 docker 實(shí)現(xiàn)層級(jí)鏡像的基礎(chǔ)嗜憔。在 wikipedia 是這么解釋的:

Unionfs is a filesystem service for Linux, FreeBSD and NetBSD which
implements a union mount for other file systems. It allows files and
directories of separate file systems, known as branches, to be
transparently overlaid, forming a single coherent file system.
Contents of directories which have the same path within the merged
branches will be seen together in a single merged directory, within
the new, virtual filesystem.

簡(jiǎn)單來(lái)說(shuō),就是用多個(gè)文件夾和文件(這些是系統(tǒng)文件系統(tǒng)的概念)存放內(nèi)容砍的,對(duì)上(應(yīng)用層)提供虛擬的文件訪問(wèn)痹筛。
比如 docker 中有鏡像的概念,應(yīng)用層看來(lái)只是一個(gè)文件廓鞠,可以讀取帚稠、刪除,在底層卻是通過(guò) UnionFS 系統(tǒng)管理各個(gè)鏡像層的內(nèi)容和關(guān)系床佳。

docker 負(fù)責(zé)鏡像的模塊是 Graph滋早,對(duì)上提供一致和方便的接口,在底層通過(guò)調(diào)用不同的 driver 來(lái)實(shí)現(xiàn)砌们。常用的 driver 包括 aufs杆麸、devicemapper,這樣的好處是:用戶可以選擇甚至實(shí)現(xiàn)自己的 driver浪感。

aufs 鏡像在機(jī)器上的存儲(chǔ)結(jié)構(gòu)

NOTE:

  • 只下載了 ubuntu:14.04 鏡像
  • docker version:1.6.3
  • image driver:aufs

使用 docker history 查看鏡像歷史:

root@cizixs-ThinkPad-T450:~# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
172.16.1.41:5000/ubuntu   14.04               2d24f826cb16        13 months ago       188.3 MB
root@cizixs-ThinkPad-T450:~# docker history 2d24
IMAGE               CREATED              CREATED BY                                      SIZE
2d24f826cb16        13 months ago        /bin/sh -c #(nop) CMD [/bin/bash]               0 B
117ee323aaa9        13 months ago        /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.895 kB
1c8294cc5160        13 months ago        /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
fa4fd76b09ce        13 months ago        /bin/sh -c #(nop) ADD file:0018ff77d038472f52   188.1 MB
511136ea3c5a        2.811686 years ago                                                   0 B

可以看到昔头,ubuntu:14.04 一共有五層鏡像。aufs 數(shù)據(jù)存放在 /var/lib/docker/aufs 目錄下:

root@cizixs-ThinkPad-T450:/var/lib/docker/aufs# tree -L 1
.
├── diff
├── layers
└── mnt

一共有三個(gè)文件夾影兽,每個(gè)文件夾下面都是以鏡像 id 命令的文件夾揭斧,保存了每個(gè)鏡像的信息。先來(lái)介紹一下這三個(gè)文件夾

  • layers:顯示了每個(gè)鏡像有哪些層構(gòu)成
  • diff:每個(gè)鏡像的和之前鏡像的區(qū)別峻堰,就是這一層的內(nèi)容
  • mnt:UnionFS 對(duì)外提供的 mount point讹开,因?yàn)?UnionFS 底層是多個(gè)文件夾和文件盅视,對(duì)上層要提供統(tǒng)一的文件服務(wù),是通過(guò) mount 的形式實(shí)現(xiàn)的旦万。每個(gè)運(yùn)行的容器都會(huì)在這個(gè)目錄下有一個(gè)文件夾

比如 diff 文件夾是這樣的:

root@cizixs-ThinkPad-T450:/var/lib/docker/aufs# ls diff/2d24f826cb16146e2016ff349a8a33ed5830f3b938d45c0f82943f4ab8c097e7/
root@cizixs-ThinkPad-T450:/var/lib/docker/aufs# ls diff/117ee323aaa9d1b136ea55e4421f4ce413dfc6c0cc6b2186dea6c88d93e1ad7c/
etc
root@cizixs-ThinkPad-T450:/var/lib/docker/aufs# ls diff/1c8294cc516082dfbb731f062806b76b82679ce38864dd87635f08869c993e45/
etc  sbin  usr  var
root@cizixs-ThinkPad-T450:/var/lib/docker/aufs# ls diff/fa4fd76b09ce9b87bfdc96515f9a5dd5121c01cc996cf5379050d8e13d4a864b/
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@cizixs-ThinkPad-T450:/var/lib/docker/aufs# ls diff/511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158/

除了這些實(shí)際的數(shù)據(jù)之外闹击,docker 還為每個(gè)鏡像層保存了 json 格式的元數(shù)據(jù),存儲(chǔ)在 /var/lib/docker/graph/<image_id>/json成艘,比如:

root@cizixs-ThinkPad-T450:/var/lib/docker# cat graph/2d24f826cb16146e2016ff349a8a33ed5830f3b938d45c0f82943f4ab8c097e7/json | jq '.'
{
  "id": "2d24f826cb16146e2016ff349a8a33ed5830f3b938d45c0f82943f4ab8c097e7",
  "parent": "117ee323aaa9d1b136ea55e4421f4ce413dfc6c0cc6b2186dea6c88d93e1ad7c",
  "created": "2015-02-21T02:11:06.735146646Z",
  "container": "c9a3eda5951d28aa8dbe5933be94c523790721e4f80886d0a8e7a710132a38ec",
  "container_config": {
    "Hostname": "43bd710ec89a",
    "Domainname": "",
    "User": "",
    "Memory": 0,
    "MemorySwap": 0,
    "CpuShares": 0,
    "Cpuset": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "PortSpecs": null,
    "ExposedPorts": null,
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ],
    "Cmd": [
      "/bin/sh",
      "-c",
      "#(nop) CMD [/bin/bash]"
    ],
    "Image": "117ee323aaa9d1b136ea55e4421f4ce413dfc6c0cc6b2186dea6c88d93e1ad7c",
    "Volumes": null,
    "WorkingDir": "",
    "Entrypoint": null,
    "NetworkDisabled": false,
    "MacAddress": "",
    "OnBuild": [],
    "Labels": null
  },
  "docker_version": "1.4.1",
  "config": {
    "Hostname": "43bd710ec89a",
    "Domainname": "",
    "User": "",
    "Memory": 0,
    "MemorySwap": 0,
    "CpuShares": 0,
    "Cpuset": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "PortSpecs": null,
    "ExposedPorts": null,
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ],
    "Cmd": [
      "/bin/bash"
    ],
    "Image": "117ee323aaa9d1b136ea55e4421f4ce413dfc6c0cc6b2186dea6c88d93e1ad7c",
    "Volumes": null,
    "WorkingDir": "",
    "Entrypoint": null,
    "NetworkDisabled": false,
    "MacAddress": "",
    "OnBuild": [],
    "Labels": null
  },
  "architecture": "amd64",
  "os": "linux",
  "Size": 0
}

除了 json 之外赏半,還有一個(gè)文件 /var/lib/docker/graph/<image_id>/layersize 保存了鏡像層的大小。

創(chuàng)建鏡像:鏡像的 cache 機(jī)制

在使用 docker build 創(chuàng)建新的鏡像的時(shí)候狰腌,docker 會(huì)使用到 cache 機(jī)制除破,來(lái)提高執(zhí)行的效率。為了理解這個(gè)問(wèn)題琼腔,我們先看一下 build 命令都做了哪些東西吧瑰枫。

我們來(lái)看一個(gè)簡(jiǎn)單的 Dockerfile:

FROM ubuntu:14.04 
RUN apt-get update 
ADD run.sh /  
VOLUME /data  
CMD ["./run.sh"]  

這個(gè)文件雖然簡(jiǎn)單,卻包含了很多命令:RUN丹莲、ADD光坝、VOLUME、CMD 涉及到很多概念甥材。

一般情況下盯另,對(duì)于每條命令,docker 都會(huì)生成一層鏡像洲赵。 cache 的作用也很容易猜測(cè)鸳惯,如果在構(gòu)建某個(gè)鏡像層的時(shí)候,發(fā)現(xiàn)這個(gè)鏡像層已經(jīng)存在了叠萍,就直接使用芝发,而不是重新構(gòu)建。這里最重要的問(wèn)題在于:怎么知道要構(gòu)建的鏡像層已經(jīng)存在了苛谷? 下面就重點(diǎn)解釋這個(gè)問(wèn)題辅鲸。

docker daemon 讀到 FROM 命令的時(shí)候,會(huì)在本地查找對(duì)應(yīng)的鏡像腹殿,如果沒(méi)有找到独悴,會(huì)從 registry 去取,當(dāng)然也會(huì)取到包含 metadata 的 json 文件锣尉。然后到了 RUN 命令刻炒,如果沒(méi)有 cache 的話,這個(gè)命令會(huì)做什么呢自沧?

我們已經(jīng)知道落蝙,每層鏡像都是由文件系統(tǒng)內(nèi)容和 metadata 構(gòu)成的。

文件系統(tǒng)的內(nèi)容,就是執(zhí)行 apt-get update 命令導(dǎo)致的文件變動(dòng)筏勒,會(huì)保存到 /var/lib/docker/aufs/diff/<image_id>/,比如這里的命令主要會(huì)修改 /var/lib 和 /var/cache 下面和 apt 有關(guān)的內(nèi)容:

root@cizixs-ThinkPad-T450:/var/lib/docker# tree -L 2 aufs/diff/e7ae26691ff649c55296adf7c0e51b746e22abefa6b30310b94bbb9cfa6fce63/
aufs/diff/e7ae26691ff649c55296adf7c0e51b746e22abefa6b30310b94bbb9cfa6fce63/
├── tmp
└── var
    ├── cache
    └── lib

我們來(lái)看一下 json 文件的內(nèi)容旺嬉,最重要的改變就是 container_config.Cmd 變成了:

"Cmd": [
  "/bin/sh",
  "-c",
  "apt-get update"
],

也就是說(shuō)管行,如果下次再構(gòu)建鏡像的時(shí)候,我們發(fā)現(xiàn)新的鏡像層 parent 還是 ubuntu:14.04邪媳,并且 json 文件中 cmd 要更改的內(nèi)容也一致捐顷,那么就認(rèn)為這兩層鏡像是相同的,不需要重新構(gòu)建雨效。好了迅涮,那么構(gòu)建的時(shí)候,daemon 一定會(huì)遍歷本地所有鏡像徽龟,如果發(fā)現(xiàn)鏡像一致就使用已經(jīng)構(gòu)建好的鏡像叮姑。

ADD 和 COPY 文件

如果 Dockerfile 中有 ADD 或者 COPY 命令,那么怎么判斷鏡像是否相同呢据悔?第一個(gè)想法肯定是文件名传透,但即使文件名不變,那么文件也是可以變的极颓;那就再加上文件大小朱盐,不過(guò)兩個(gè)同名并且大小相同的文件也不一定內(nèi)容完全一樣啊菠隆!最保險(xiǎn)的辦法就是用 hash 了兵琳,嗯!docker 就是這個(gè)干的骇径,我們來(lái)看一下 ADD 這層鏡像的 json 文件變化:

"Cmd": [
  "/bin/sh",
  "-c",
  "#(nop) ADD file:9fb96e5dd9ce3e03665523c164bbe775d64cc5d8cc8623fbcf5a01a63e9223ab in /"
],

看到?jīng)]躯肌,ADD 的時(shí)候只有一串 hash 字符串,hash 算法的實(shí)現(xiàn)既峡,如果感興趣可以自己研究一下羡榴。

喂!這樣真的就萬(wàn)無(wú)一失了嗎运敢?

看完上面的內(nèi)容校仑,大多數(shù)同學(xué)會(huì)覺(jué)得 cache 機(jī)制真好, 很節(jié)省時(shí)間传惠,也能節(jié)省空間迄沫。但是這里還有一個(gè)問(wèn)題,有些命令是依賴外部的卦方,比如 apt-get update 或者 curl http://some.url.com/羊瘩,如果外部?jī)?nèi)容發(fā)生了改變,docker 就沒(méi)有辦法偵測(cè)到,去做相應(yīng)的處理了尘吗。所以它提供了 --no-cache 參數(shù)來(lái)強(qiáng)制不要使用 cache 機(jī)制逝她,所以說(shuō)這部分內(nèi)容是要用戶自己維護(hù)的。

除此之外睬捶,還需要在編寫(xiě) Dockerfile 的時(shí)候考慮到 cache黔宛,這一點(diǎn)在官方提供的 dockerfile best practice 也有提及。

運(yùn)行鏡像:docker 鏡像和 docker 容器

我們都知道 docker 容器就是運(yùn)行態(tài)的docker 鏡像擒贸,但是有一個(gè)問(wèn)題:docker 鏡像里面保存的都是靜態(tài)的東西臀晃,而容器里面的東西是動(dòng)態(tài)的,那么這些動(dòng)態(tài)的東西是如何管理的呢介劫?比如說(shuō):

  • docker 容器里該運(yùn)行那些進(jìn)程徽惋?
  • 怎么把 docker 鏡像轉(zhuǎn)換成docker 容器?
  • docker 容器里面 ip座韵、hostname 這些東西使如何動(dòng)態(tài)生成的险绘?

這就是上面提到的 json 文件的功能,哪些信息會(huì)存放在 json 文件呢回右?答案就是:除了文件系統(tǒng)的內(nèi)容外隆圆,其他都是,比如:

  • ENV FOO=BAR: 環(huán)境變量翔烁,
  • VOLUME /some/path:容器使用的 volume渺氧,乍看上去這是文件系統(tǒng)的一部分,其實(shí)這部分內(nèi)容不是確定的蹬屹,在構(gòu)建鏡像的時(shí)候數(shù)據(jù)卷可以是不存在的侣背,會(huì)在容器運(yùn)行的時(shí)候動(dòng)態(tài)地添加。所以這部分內(nèi)容不能放到鏡像層文件中
  • EXPOSE 80:expose 命令記錄了容器運(yùn)行的時(shí)候要暴露給外部的端口慨默,這也是運(yùn)行時(shí)狀態(tài)贩耐,不是文件系統(tǒng)的一部分
  • CMD ["./myscript.sh"]:CMD 命令記錄了 docker 容器的執(zhí)行入口,這不是文件系統(tǒng)的一部分

好了厦取,既然我們已經(jīng)知道這些東西是怎么存儲(chǔ)的潮太,那么實(shí)際運(yùn)行容器的時(shí)候這些內(nèi)容是怎么被加載到容器里的呢?答案就是 docker daemon虾攻,這個(gè)實(shí)際管理容器實(shí)現(xiàn)的家伙铡买。

我們知道,在容器實(shí)際運(yùn)行過(guò)程中霎箍,每個(gè)容器就是 docker daemon 的子進(jìn)程:

root      3249  0.1  6.6 985212 33288 ?        Ssl  04:53   0:19 /usr/bin/docker daemon --insecure-registry 172.16.1.41:5000 --exec-opt native.cgroupdriver=cgroupfs --bip=10.12.240.1/20 --mtu=1500 --ip-masq=false
root      3597  0.0  0.1   3816   632 ?        Ssl  04:55   0:00  \_ /pause
root      3633  0.0  0.1   3816   504 ?        Ssl  04:55   0:00  \_ /pause
root      3695  0.0  0.1   3816   516 ?        Ssl  04:55   0:00  \_ /pause
root      3710  0.0  0.1   3816   528 ?        Ssl  04:55   0:00  \_ /pause
root      3745  0.0  0.1   3816   504 ?        Ssl  04:55   0:00  \_ /pause
polkitd   3793  0.0  0.2  36524  1280 ?        Ssl  04:55   0:07  \_ redis-server *:6379
root      3847  0.0  0.0   4184   184 ?        Ss   04:55   0:00  \_ /bin/sh -c /run.sh
root      3872  0.0  0.0  17668   360 ?        S    04:55   0:00  |   \_ /bin/bash /run.sh
root      3873  0.0  0.3  42824  1752 ?        Sl   04:55   0:01  |       \_ redis-server *:6379
root      3865  0.0  1.5 166256  8024 ?        Ss   04:55   0:00  \_ apache2 -DFOREGROUND
33        3881  0.0  1.0 166280  5140 ?        S    04:55   0:00  |   \_ apache2 -DFOREGROUND
33        3882  0.0  1.0 166280  5140 ?        S    04:55   0:00  |   \_ apache2 -DFOREGROUND
33        3883  0.0  1.0 166280  5140 ?        S    04:55   0:00  |   \_ apache2 -DFOREGROUND
33        3884  0.0  1.0 166280  5140 ?        S    04:55   0:00  |   \_ apache2 -DFOREGROUND
33        3885  0.0  1.0 166280  5140 ?        S    04:55   0:00  |   \_ apache2 -DFOREGROUND
root      3939  0.0  0.7  90264  4016 ?        Ss   04:55   0:00  \_ nginx: master process nginx
33        3947  0.0  0.3  90632  1660 ?        S    04:55   0:00      \_ nginx: worker process
33        3948  0.0  0.3  90632  1660 ?        S    04:55   0:00      \_ nginx: worker process
33        3949  0.0  0.3  90632  1660 ?        S    04:55   0:00      \_ nginx: worker process
33        3950  0.0  0.3  90632  1660 ?        S    04:55   0:00      \_ nginx: worker process

也是說(shuō)奇钞,docker daemon 會(huì)讀取鏡像的信息,作為容器的 rootfs漂坏,然后讀取 json 文件中的動(dòng)態(tài)信息作為運(yùn)行時(shí)狀態(tài)景埃。

刪除鏡像:清理鏡像之道

鏡像是按照 UnionFS 的格式存放在本地的媒至,刪除也很容易理解,就是把對(duì)應(yīng)鏡像層的本地文件(夾)刪除谷徙。docker 也提供了 docker rmi 這個(gè)命令來(lái)處理拒啰。

不過(guò)需要注意一點(diǎn):鏡像也是有“引用”這個(gè)概念的,只有當(dāng)該鏡像層沒(méi)有被引用的時(shí)候蒂胞,才能刪除图呢。“引用”就是被打上 tag骗随,同一個(gè) uuid 的鏡像是可以被打上不同的 tag 的。我們來(lái)看一個(gè)官方提供的例子

$ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
test1                     latest              fd484f19954f        23 seconds ago      7 B (virtual 4.964 MB)
test                      latest              fd484f19954f        23 seconds ago      7 B (virtual 4.964 MB)
test2                     latest              fd484f19954f        23 seconds ago      7 B (virtual 4.964 MB)

$ docker rmi fd484f19954f
Error: Conflict, cannot delete image fd484f19954f because it is tagged in multiple repositories, use -f to force
2013/12/11 05:47:16 Error: failed to remove one or more images

$ docker rmi test1
Untagged: test1:latest
$ docker rmi test2
Untagged: test2:latest

$ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
test                      latest              fd484f19954f        23 seconds ago      7 B (virtual 4.964 MB)
$ docker rmi test
Untagged: test:latest
Deleted: fd484f19954f4920da7ff372b5067f5b7ddb2fd3830cecd17b96ea9e286ba5b8

刪除有 tag 的鏡像時(shí)赴叹,會(huì)先有 untag 的操作鸿染。如果刪除的鏡像還有其他 tag,必須先把所有的 tag 刪除后才能繼續(xù)乞巧,當(dāng)然你也可以使用 -f 參數(shù)來(lái)強(qiáng)制刪除涨椒。

另外一個(gè)要注意的是:如果一個(gè)鏡像有很多層,并且中間層沒(méi)有被引用绽媒,那么在刪除這個(gè)鏡像的時(shí)候蚕冬,所有沒(méi)有被引用的鏡像都會(huì)被刪除。

docker 1.10 的新變化

docker 鏡像的 uuid 是怎么生成的是辕?

在 1.10 之前囤热,docker 鏡像的 uuid 是隨機(jī)生產(chǎn)的;在 1.10 引入了 Content addressable storage 的概念获三,uuid 是通過(guò) SHA256 hash 算法生產(chǎn)的旁蔼,主要好處有兩點(diǎn):可以作為鏡像內(nèi)容的驗(yàn)證,不同鏡像可以共享鏡像層疙教。需要注意的是:容器的 uuid 還是隨機(jī)生成的棺聊,因?yàn)槿萜鞑淮嬖诠蚕淼那闆r。

image 的存儲(chǔ)

上面講到的鏡像存儲(chǔ)方式在 1.10 版本之前是正確的贞谓,但是 docker 1.10 引入了新的方式限佩。所以 docker image id 和 aufs 的文件目錄的名字不是對(duì)應(yīng)的!

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末裸弦,一起剝皮案震驚了整個(gè)濱河市祟同,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌烁兰,老刑警劉巖耐亏,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異沪斟,居然都是意外死亡广辰,警方通過(guò)查閱死者的電腦和手機(jī)暇矫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)择吊,“玉大人李根,你說(shuō)我怎么就攤上這事〖妇Γ” “怎么了房轿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)所森。 經(jīng)常有香客問(wèn)我囱持,道長(zhǎng),這世上最難降的妖魔是什么焕济? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任纷妆,我火速辦了婚禮,結(jié)果婚禮上晴弃,老公的妹妹穿的比我還像新娘掩幢。我一直安慰自己,他們只是感情好上鞠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布际邻。 她就那樣靜靜地躺著,像睡著了一般芍阎。 火紅的嫁衣襯著肌膚如雪世曾。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天能曾,我揣著相機(jī)與錄音度硝,去河邊找鬼。 笑死寿冕,一個(gè)胖子當(dāng)著我的面吹牛蕊程,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播驼唱,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼藻茂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了玫恳?” 一聲冷哼從身側(cè)響起辨赐,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎京办,沒(méi)想到半個(gè)月后掀序,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惭婿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年不恭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叶雹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡换吧,死狀恐怖折晦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情沾瓦,我是刑警寧澤满着,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站贯莺,受9級(jí)特大地震影響风喇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缕探,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一响驴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撕蔼,春花似錦、人聲如沸秽誊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锅论。三九已至讼溺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間最易,已是汗流浹背怒坯。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留藻懒,地道東北人剔猿。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像嬉荆,于是被迫代替她去往敵國(guó)和親归敬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Docker — 云時(shí)代的程序分發(fā)方式 要說(shuō)最近一年云計(jì)算業(yè)界有什么大事件鄙早?Google Compute Engi...
    ahohoho閱讀 15,532評(píng)論 15 147
  • docker基本概念 1. Image Definition 鏡像 Image 就是一堆只讀層 read-only...
    慢清塵閱讀 8,748評(píng)論 1 21
  • 五汪茧、Docker 端口映射 無(wú)論如何,這些 ip 是基于本地系統(tǒng)的并且容器的端口非本地主機(jī)是訪問(wèn)不到的限番。此外舱污,除了...
    R_X閱讀 1,748評(píng)論 0 7
  • 一、Docker 簡(jiǎn)介 Docker 兩個(gè)主要部件:Docker: 開(kāi)源的容器虛擬化平臺(tái)Docker Hub: 用...
    R_X閱讀 4,386評(píng)論 0 27
  • 這個(gè)月和小伙伴們一起讀了洛里?斯皮爾曼著弥虐,吳春玲扩灯,薛雨辰譯的《生命清單》媚赖。感覺(jué)收獲很大,而且在臨近年尾之際更有實(shí)際...
    慧眼識(shí)魚(yú)閱讀 1,341評(píng)論 2 10