參考鏈接:https://blog.csdn.net/u010566813/article/details/117783220
第一步:
首先我們先拉取鏡像:
docker pull ubuntu:latest
Using default tag: latest
latest: Pulling from library/ubuntu
345e3491a907: Pull complete
57671312ef6f: Pull complete
5e9250ddb7d0: Pull complete
Digest:sha256:adf73ca014822ad8237623d388cedf4d5346aa72c270c5acc01431cc93e18e2d
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
這里的345e3491a907,57671312ef6f,5e9250ddb7d0為壓縮的layer層的哈希值這些值為layerID
,即distribution hashes
,他們從遠(yuǎn)程的repository拉取下來。
第二步:
查看鏡像的詳細(xì)信息:
docker inspect ubuntu:latest
其中有一個(gè)rootfs的鍵值對,如下:
"RootFS": {
"Type": "layers",
"Layers": ["sha256:ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439", "sha256:63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107", "sha256:2f140462f3bcf8cf3752461e27dfd4b3531f266fa10cda716166bd3a78a19103"
]
},
這是鏡像的底層的rootfs,但是我們發(fā)現(xiàn)這些sha256值和第一步拉取下來的層layerID不一致。這是為什么呢?
因?yàn)閜ull下來的是壓縮的數(shù)據(jù),layerID
是壓縮數(shù)據(jù)的sha256的值(Layer ID
指Distribution
根據(jù)layer compressed data
計(jì)算的),而inspect rootfs中的值是解壓后,對解壓的內(nèi)容進(jìn)行sha256的值他們是diffID,是在本地由Docker根據(jù)layer uncompressed data
計(jì)算的。
記住這里的rootfs layers
的值是diffID
。
第三步:
那么從遠(yuǎn)程拉取下來的layerID和解壓后的diffID是如何一一對應(yīng)的呢?
ls /var/lib/docker/image/overlay2/distribution/
diffid-by-digest
v2metadata-by-diffid
其中diffid-by-digest
保存了digest(layerID)->diffID
的映射關(guān)系,即distribution hashes
和Content hashes
的映射關(guān)系。也即是正向查詢。
v2metadata-by-diffid
保存了diffid -> (digest,repository)
的映射關(guān)系,這可以方便查找layer的digest及其所屬的repository。也即是反向查詢,可以從diffID->layerID
(其實(shí)就是digest)。
cd /var/lib/docker/image/overlay2/distribution/diffid-by-digest/sha256
cat <layerID>
<diffID> //得到 相對應(yīng)的diffID
cd /var/lib/docker/image/overlay2/distribution/v2metadata-by-diffid/sha256
cat <diffID>
[{"Digest":"sha256:345e3491a907bb7c6f1bdddcf4a94284b8b6ddd77eb7d93f09432b17b20f2bbe","SourceRepository":"docker.io/library/ubuntu","HMAC":""}] // 得到相應(yīng)的layerID和庫相關(guān)信息。
第四步:
從diffID組成chainID:
layer.ChainID只用本地,根據(jù)layer.DiffID計(jì)算,并用于layerdb的目錄名稱。
chainID唯一標(biāo)識了一組(像糖葫蘆一樣的串的底層)diffID的hash值,包含了這一層和它的父層(底層),當(dāng)然這個(gè)糖葫蘆可以有一顆山楂,也就是chainID(layer0)==diffID(layer0)
;對于多顆山楂的糖葫蘆,ChainID(layerN) = SHA256hex(ChainID(layerN-1) + " " + DiffID(layerN))
cd /var/lib/docker/image/overlay2/layerdb/sha256
這個(gè)sha256目錄中保存了所有的chainID,在第二步對鏡像的inspect中,
["sha256:ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439", "sha256:63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107", "sha256:2f140462f3bcf8cf3752461e27dfd4b3531f266fa10cda716166bd3a78a19103"]
三個(gè)diffID,第一個(gè)是最底層的ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439,所以diffID(layer0)==chainID(layer0)
然后這個(gè)文件夾中包含了diff、cache-id等,最主要的是Diff文件保存了這個(gè)層的diffID.cache-id為具體/var/lib/docker/overlay2/<cache-id>
存儲路徑。
另外兩個(gè)chainID如何計(jì)算呢?
除了底層的layer層,還有一些高層的layer,他們的chainID文件夾中包含了parent文件,這個(gè)是值為ChainID(layerN-1)
,diff文件存儲了DiffID(layerN)
,而文件夾也就是ChainID(layerN) = SHA256hex(ChainID(layerN-1) + " " + DiffID(layerN))
echo -n "sha256:ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439 sha256:63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107" | sha256sum | awk '{print $1}'
一定注意要加上 “sha256:”和中間的空格“ ”這兩個(gè)字符,否則計(jì)算就錯(cuò)誤了。
得出中間層chainID它也包括自己diff、parent、cache-id等:8d8dceacec7085abcab1f93ac1128765bc6cf0caac334c821e01546bd96eb741
再計(jì)算最后的chainID:
echo -n "sha256:8d8dceacec7085abcab1f93ac1128765bc6cf0caac334c821e01546bd96eb741 sha256:2f140462f3bcf8cf3752461e27dfd4b3531f266fa10cda716166bd3a78a19103" | sha256sum | awk '{print $1}'
得出最后的值為:
3dd8c8d4fd5b59d543c8f75a67cdfaab30aef5a6d99aea3fe74d8cc69d4e7bf2
第五步:
最后從chainID->cacheID
通過上一步計(jì)算找到當(dāng)前最頂層的chainID:
/var/lib/docker/image/overlay2/layerdb/sha256/保存了chianID信息,目錄名稱為chainID
這個(gè)目錄下的cache-id、diff、parent
通過這個(gè)chain生成一個(gè)cache-id
diff保存當(dāng)前l(fā)ayer的diff ID
parent保存上一層layer的chainID
cd 3dd8c8d4fd5b59d543c8f75a67cdfaab30aef5a6d99aea3fe74d8cc69d4e7bf2
cat cache-id
ddd5760e7cbfde67e325e77b540dfc13e7dccf1c7d1b156554d0a79378642bd1
第六步:
從cache-id得到最終的磁盤文件:
在/var/lib/docker/overlay2/
cd /var/lib/docker/overlay2/<cache-id>
得到當(dāng)前的內(nèi)容。
完結(jié)。
總結(jié):
Overlay2比overlay更加高效,因?yàn)閛verlay2優(yōu)化了inode的利用。
layerID -> diffID -> chainID -> cacheID
layerID和diffID的對應(yīng)關(guān)系在diffid-by-digest和v2metadata-by-diffid
chainID主要存在于/var/lib/docker/image/overlay2/layerdb/sha256/<chain-id>,
cacheID主要存在于/var/lib/docker/overlay2/<cache-id>