新版本的docker鏡像存儲其實是很繞的,各種ID和目錄定義較多,不是很直觀,本文較詳細的分析一下鏡像本地存儲和在registry存儲的格式。
root@ubuntu:/home# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
a39c84e173f0: Pull complete
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
root@ubuntu:/home# docker history ubuntu
IMAGE CREATED CREATED BY SIZE COMMENT
d5ca7a445605 34 hours ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 34 hours ago /bin/sh -c #(nop) ADD file:ff4909f2124325dac… 65.6MB
root@ubuntu:/home# docker image inspect ubuntu
"GraphDriver": {
"Data": {
"MergedDir": "/var/lib/docker/overlay2/492c0894bbb23c44e42da84b6eeefb75a92895ff84b5360257e02cd8e1fa2bae/merged",
"UpperDir": "/var/lib/docker/overlay2/492c0894bbb23c44e42da84b6eeefb75a92895ff84b5360257e02cd8e1fa2bae/diff",
"WorkDir": "/var/lib/docker/overlay2/492c0894bbb23c44e42da84b6eeefb75a92895ff84b5360257e02cd8e1fa2bae/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec"
]
},
爲了測試方便,我們基於ubuntu加兩個文件,使用 docker build -t myubuntu .
創建一個新鏡像。
## myubuntu.Dockerfile ##
FROM ubuntu:latest
ADD one.txt /tmp/
ADD two.txt /home/
概覽
鏡像元數據存儲在 /var/lib/docker/image/overlay2
:
root@ubuntu:/var/lib/docker/image/overlay2# ls -ls
total 16
4 drwx------ 4 root root 4096 Oct 17 10:55 distribution
4 drwx------ 4 root root 4096 Oct 17 10:21 imagedb
4 drwx------ 5 root root 4096 Oct 19 15:33 layerdb
4 -rw------- 1 root root 379 Oct 19 15:43 repositories.json
root@ubuntu:/var/lib/docker/image/overlay2# cat repositories.json |jq .
{
"Repositories": {
"myubuntu": {
"myubuntu:latest": "sha256:0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f"
},
"ubuntu": {
"ubuntu:latest": "sha256:d5ca7a4456053674d490803005766890dd19e3f7e789a48737c0d462da531f5d",
"ubuntu@sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322": "sha256:d5ca7a4456053674d490803005766890dd19e3f7e789a48737c0d462da531f5d"
}
}
}
- distribution 是registry用的,docker pull和push會用到裏面元數據。
- imagedb存儲鏡像元數據。
- layerdb存儲layer元數據。
- repositories.json 則是鏡像的倉庫以及版本信息。ubuntu對應了兩條信息,其中ubuntu@sha256對應的是鏡像倉庫中的ID,鏡像倉庫中的id是根據壓縮後的layer計算出來的。myubuntu是基於ubuntu另外加了兩層的新鏡像,因爲沒有push到倉庫,所以只有一條記錄。
imagedb目錄
imagedb目錄存儲的是鏡像元數據。
- content主要是鏡像元數據的Json文件。
- metadata目錄存儲的是父鏡像的ImageID,因爲d5ca7a...沒有父鏡像,所以該目錄下沒有信息。
├── content
│ └── sha256
│ ├── 0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f
│ ├── 7b8fd4f52df342ac54019ffe8db2275f44e7c61f88130def5b5baa8ba85572b7
│ └── d5ca7a4456053674d490803005766890dd19e3f7e789a48737c0d462da531f5d
└── metadata
└── sha256
├── 0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f
│ ├── lastUpdated
│ └── parent
└── 7b8fd4f52df342ac54019ffe8db2275f44e7c61f88130def5b5baa8ba85572b7
└── parent
Image Json
- 每個鏡像都會有一個對應的Json文件,用於描述鏡像的基礎信息,比如鏡像創建時間、作者以及入口文件,默認參數、網絡和數據卷配置等。這個Json文件也存儲了鏡像的分層記錄diff_ids,以及提供對應層的歷史信息。
- 這個Json文件是不可更改的,如果改了會影響ImageID,因爲ImageID就是sha256(ImageJson)得到的。
- 如 debian:10 的image id是
d5ca...
,它對應的Json文件在$DOCKER_DIR/image/overlay2/imagedb/content/sha256/d5ca7a4456053674d490803005766
,內容如下:
...
"created": "2021-10-16T01:47:45.87597179Z",
"docker_version": "20.10.7",
"history": [
{
"created": "2021-10-16T01:47:45.455040439Z",
"created_by": "/bin/sh -c #(nop) ADD file:ff4909f2124325dac58d43c617132325934ed48a5ab4c534d05f931fcf700a2f in / "
},
{
"created": "2021-10-16T01:47:45.87597179Z",
"created_by": "/bin/sh -c #(nop) CMD [\"bash\"]",
"empty_layer": true
}
],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec"
]
},
"variant": "v8"
}
Image ID
鏡像ID是從Image Json文件得到的,即 sha256sum(ImageJson)。
root@ubuntu:/home# sha256sum /var/lib/docker/image/overlay2/imagedb/content/sha256/d5ca7a4456053674d490803005766890dd19e3f7e789a48737c0d462da531f5d
d5ca7a4456053674d490803005766890dd19e3f7e789a48737c0d462da531f5d /var/lib/docker/image/overlay2/imagedb/content/sha256/d5ca7a4456053674d490803005766890dd19e3f7e789a48737c0d462da531f5d
layerdb目錄
Layer DiffID
Layer DiffID是沒有壓縮的對應層的tar文件的sha256sum值。當然,打包和截包文件的適合得保證是可以可重複操作的,不然會導致Layer的DiffID出錯(可以使用tar-split保存tar headers)。比如上面例子中ubuntu鏡像只有一層,diff_ids列表只有 (history裏面的CMD不佔磁盤空間) "sha256:350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec"。每一層的tar文件我們可以通過 docker save ubuntu -o ubuntu.tar
得到,解壓ubuntu.tar後可以得到對應的層級的打包後的layer.tar文件,如下可以驗證DiffID的值計算原理。
root@ubuntu:/home/ubuntutar/3354e7edac2389f01e81eb3372e6c8239af07d389d703b0b08ea347b218ff6d6# sha256sum layer.tar
350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec layer.tar
Layer ChainID
ChainID用於標識鏡像層級棧,它的值由DiffID計算得來。ChainID對應的layer目錄是 /var/lib/docker/image/overlay2/layerdb/sha256
,這下面的目錄就是ChainID,其中內容存儲了鏡像的層級棧關係。比如這一層的parent是什麼,以及對應的鏡像數據存儲目錄的cache_id。本身layerdb只是存儲layer的元數據信息,並不存儲實際鏡像數據。
ChainID(L₀) = DiffID(L₀)
ChainID(L₀|...|Lₙ₋₁|Lₙ) = Digest(ChainID(L₀|...|Lₙ₋₁) + " " + DiffID(Lₙ))
即最底層的ChainID跟DiffID一樣,而其他層的ChainID則是通過計算從最底層到這層的Digest得到。
root@ubuntu:/home/ssj/dockerfiles# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu latest 0a95d0866cb5 2 seconds ago 65.6MB
ubuntu latest d5ca7a445605 3 days ago 65.6MB
root@ubuntu:/var/lib/docker/image/overlay2/imagedb# docker history myubuntu
IMAGE CREATED CREATED BY SIZE COMMENT
0a95d0866cb5 4 days ago /bin/sh -c #(nop) ADD file:8d08d699a25a24091… 4B
7b8fd4f52df3 4 days ago /bin/sh -c #(nop) ADD file:5ff37a8c444d9cf17… 4B
d5ca7a445605 8 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 8 days ago /bin/sh -c #(nop) ADD file:ff4909f2124325dac… 65.6MB
查看Image Json文件可以看到diff_ids加了兩層,imagedb目錄下面也多了兩個鏡像元數據信息文件,對應新增加的兩層鏡像。
root@ubuntu:/var/lib/docker/image/overlay2/imagedb/content/sha256# cat 0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec",
"sha256:7c7eb5781271639891432f506fce3b30b74c63f0b145ad7746a7e01284e4f7a2",
"sha256:a58f164385b2d99773a41596a257920d90c6900c9f74d6a22a633d78f9c8424e"
]
},
root@ubuntu:/var/lib/docker/image/overlay2/imagedb/content/sha256# ls -ls
total 12
4 -rw------- 1 root root 1927 Oct 19 15:43 0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f
4 -rw------- 1 root root 1689 Oct 19 15:43 7b8fd4f52df342ac54019ffe8db2275f44e7c61f88130def5b5baa8ba85572b7
4 -rw------- 1 root root 1475 Oct 17 11:40 d5ca7a4456053674d490803005766890dd19e3f7e789a48737c0d462da531f5d
除了之前的350f...對應ubuntu,其中7c7e是one.txt那層,而a58f則是two.txt那層。
root@ubuntu:/var/lib/docker/image/overlay2/layerdb/sha256# ls -ls
total 12
4 drwx------ 2 root root 4096 Oct 19 15:43 06e00d189a99510f2ee2bfc4b6eed7b4d119adc4514acbfc13efc16e6b482a3d
4 drwx------ 2 root root 4096 Oct 17 11:40 350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec
4 drwx------ 2 root root 4096 Oct 19 15:43 850bf45b4ce3aa79e125f8bf8142bc760506a854e8ac2c42b5fc343be8099097
ChainID(350f) = DiffID(350f) = 350f...
ChainID(7c7e) = Digest(DiffID(350f) + DiffID(7c7e)) = 06e0...
ChainID(a58f) = Digest(ChainID(7c7e) + DiffID(a58f)) = 850b...
# echo -n 'sha256:350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec sha256:7c7eb5781271639891432f506fce3b30b74c63f0b145ad7746a7e01284e4f7a2' > /tmp/chain1
# sha256sum /tmp/chain1
06e00d189a99510f2ee2bfc4b6eed7b4d119adc4514acbfc13efc16e6b482a3d /tmp/chain1
# echo -n 'sha256:06e00d189a99510f2ee2bfc4b6eed7b4d119adc4514acbfc13efc16e6b482a3d sha256:a58f164385b2d99773a41596a257920d90c6900c9f74d6a22a633d78f9c8424e' > /tmp/chain2
# sha256sum /tmp/chain2
850bf45b4ce3aa79e125f8bf8142bc760506a854e8ac2c42b5fc343be8099097 /tmp/chain2
我們可以看下ChainID目錄下的內容,可以看到除了ubuntu的基礎層,其他層都有一個文件parent,值就是父層的diff_id,diff是diff_id值,cache-id則是鏡像實際存儲目錄,位於 /var/lib/docker/overlay2/{cache-id}
,size是這一層實際增加文件的大小,tar-split.json.gz是打包這層鏡像的配置,參考 https://github.com/vbatts/tar-split。
root@ubuntu:/var/lib/docker/image/overlay2/layerdb/sha256# tree
.
├── 06e00d189a99510f2ee2bfc4b6eed7b4d119adc4514acbfc13efc16e6b482a3d
│ ├── cache-id
│ ├── diff
│ ├── parent
│ ├── size
│ └── tar-split.json.gz
├── 350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec
│ ├── cache-id
│ ├── diff
│ ├── size
│ └── tar-split.json.gz
└── 850bf45b4ce3aa79e125f8bf8142bc760506a854e8ac2c42b5fc343be8099097
├── cache-id
├── diff
├── parent
├── size
└── tar-split.json.gz
overlay2目錄
CacheID
CacheID是一個uuid值,每次都不一樣。它對應的目錄 /var/lib/docker/overlay2/${CacheID}
,該目錄存儲了鏡像每層文件和下一層的鏈接等。驗證一下:
root@ubuntu:/var/lib/docker/image/overlay2/layerdb/sha256# cat 06e00d189a99510f2ee2bfc4b6eed7b4d119adc4514acbfc13efc16e6b482a3d/cache-id
743685bc1d83ec4165681442dcb5f19107406be3b28b479860a5ff13414ed49
root@ubuntu:/var/lib/docker/overlay2/743685bc1d83ec4165681442dcb5f19107406be3b28b479860a5ff13414ed497# tree
.
├── committed
├── diff
│ └── tmp
│ └── one.txt
├── link
├── lower
└── work
root@ubuntu:/var/lib/docker/overlay2/743685bc1d83ec4165681442dcb5f19107406be3b28b479860a5ff13414ed497# cat link
EV2GF3SYGZFG7HYF7THVYGLOBQ
root@ubuntu:/var/lib/docker/overlay2/743685bc1d83ec4165681442dcb5f19107406be3b28b479860a5ff13414ed497# cat lower
l/F3YS2JA2OLBGKAAGJCQRSGCQZ3
root@ubuntu:/var/lib/docker/overlay2# ls -ls l/
total 12
4 lrwxrwxrwx 1 root root 72 Oct 19 15:43 EV2GF3SYGZFG7HYF7THVYGLOBQ -> ../743685bc1d83ec4165681442dcb5f19107406be3b28b479860a5ff13414ed497/diff
4 lrwxrwxrwx 1 root root 72 Oct 17 11:40 F3YS2JA2OLBGKAAGJCQRSGCQZ3 -> ../492c0894bbb23c44e42da84b6eeefb75a92895ff84b5360257e02cd8e1fa2bae/diff
4 lrwxrwxrwx 1 root root 72 Oct 19 15:43 P63ZKOO3TBJQCZE65OB7QEMKYZ -> ../c4ba312d8d454a3b0e7f74d985b086d688cacc5e00a995db482cf030f10729d5/diff
其中diff目錄下面便是這一層的文件。link是對應的diff目錄的短鏈接,lower則是下一層diff目錄的短鏈接。
鏡像大小
在layerdb目錄的size文件可以看到每一層的鏡像大小,但是加起來跟docker images
顯示的大小會有點差距,比如myubuntu鏡像每一層計算加起來是 4 + 65593591 + 4 = 65593599 / 1024 / 1024 = 62.55MiB
,實際顯示是 65.6MB,這是因爲docker images
裏面計算是按 65593599/1000/1000=65.59
計算的。
另外,因爲鏡像每層記錄的是相對前一層的文件變化,即便刪除了文件和軟件包,新鏡像大小也不會變小。除非使用 docker export
重新導出一個新鏡像。
distribution目錄
這個目錄存儲的是layer diffid和digest的關係,其中digest是鏡像倉庫裏面的目錄ID。
root@ubuntu:/var/lib/docker/image/overlay2/distribution# tree
.
├── diffid-by-digest
│ └── sha256
│ └── a39c84e173f038958d338f55a9e8ee64bb6643e8ac6ae98e08ca65146e668d86
└── v2metadata-by-diffid
└── sha256
├── 350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec
其中 v2metadata-by-diff存儲了layer diffid對應在鏡像倉庫的信息,包括digest,sourcerepository等。
root@ubuntu:/var/lib/docker/image/overlay2/distribution# cat v2metadata-by-diffid/sha256/350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec |jq .
[
{
"Digest": "sha256:a39c84e173f038958d338f55a9e8ee64bb6643e8ac6ae98e08ca65146e668d86",
"SourceRepository": "docker.io/library/ubuntu",
"HMAC": ""
}
]
diffid-by-digest則是反過來的,文件名是倉庫裏面的layer digest,內容是layer diffid。因爲我們新加的鏡像myubuntu並沒有push到倉庫,所以這個目錄下面沒有信息。
我們創建一個本地的registry,然後對myubuntu另外打個tag,docker tag myubuntu 127.0.0.1:5000/myubuntu
,則respositories.json會多一條新的記錄。此時,distribution目錄還沒有變化。
root@ubuntu:/var/lib/docker/image/overlay2/distribution# cat ../repositories.json |jq .
{
"Repositories": {
"127.0.0.1:5000/myubuntu": {
"127.0.0.1:5000/myubuntu:latest": "sha256:0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f"
},
"myubuntu": {
"myubuntu:latest": "sha256:0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f"
},
"registry": {
"registry:2": "sha256:979f2f24c32b2553fa72c6589287d88c57241a139992bf73e3feadd7cf607cf8",
"registry@sha256:265d4a5ed8bf0df27d1107edb00b70e658ee9aa5acb3f37336c5a17db634481e": "sha256:979f2f24c32b2553fa72c6589287d88c57241a139992bf73e3feadd7cf607cf8"
},
"ubuntu": {
"ubuntu:latest": "sha256:d5ca7a4456053674d490803005766890dd19e3f7e789a48737c0d462da531f5d",
"ubuntu@sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322": "sha256:d5ca7a4456053674d490803005766890dd19e3f7e789a48737c0d462da531f5d"
}
}
}
當我們執行 docker push 127.0.0.1:5000/myubuntu
,則會發現distribution的兩個目錄分別多了兩條記錄,對應的是myubuntu的7c7e...
和a58f...
兩個diffid。此時repository.json裏面127.0.0.1:5000/myubuntu
會多一條帶digest的記錄,這就是鏡像倉庫裏面對應的digest。其中push時顯示的digest:sha256:bb3c...
對應的是registry的manifest文件的digest,下一節分析。
root@ubuntu:/home/ssj# docker push 127.0.0.1:5000/myubuntu
Using default tag: latest
The push refers to repository [127.0.0.1:5000/myubuntu]
a58f164385b2: Pushed
7c7eb5781271: Pushed
350f36b271de: Pushed
latest: digest: sha256:bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d size: 943
root@ubuntu:/var/lib/docker/image/overlay2/distribution# tree
.
├── diffid-by-digest
│ └── sha256
│ ├── a362e9896a95c6c3b46f3f958cf378bb818552890669d83e44cc86f2a2c4a726
│ ├── fba52c366bc01edecaf465ef739f5230b3034d01f8fcfe16f005929b2fd0e432
......
└── v2metadata-by-diffid
└── sha256
├── 7c7eb5781271639891432f506fce3b30b74c63f0b145ad7746a7e01284e4f7a2
├── a58f164385b2d99773a41596a257920d90c6900c9f74d6a22a633d78f9c8424e
......
root@ubuntu:/var/lib/docker/image/overlay2/distribution# cat ../repositories.json |jq .
{
"Repositories": {
"127.0.0.1:5000/myubuntu": {
"127.0.0.1:5000/myubuntu:latest": "sha256:0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f",
"127.0.0.1:5000/myubuntu@sha256:bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d": "sha256:0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f"
},
......
registry存儲
registry中存儲的鏡像文件是經過gzip壓縮,比如myubuntu本地大小是65.6MB,推到registry壓縮後大小約27MB,壓縮比還是不錯的。registry存儲目錄如下,主要分爲blobs和repositories兩個目錄。
- repositories:存儲的鏡像元數據。
- blobs:存儲的鏡像文件打包後的gzip壓縮文件,即layer.tar.gz。
root@ubuntu:/home/registry/docker/registry/v2# tree
.
├── blobs
│ └── sha256
│ ├── 0a
│ │ └── 0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f
│ │ └── data
│ ├── a3
│ │ ├── a362e9896a95c6c3b46f3f958cf378bb818552890669d83e44cc86f2a2c4a726
│ │ │ └── data
│ │ └── a39c84e173f038958d338f55a9e8ee64bb6643e8ac6ae98e08ca65146e668d86
│ │ └── data
│ ├── bb
│ │ └── bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d
│ │ └── data
│ └── fb
│ └── fba52c366bc01edecaf465ef739f5230b3034d01f8fcfe16f005929b2fd0e432
│ └── data
└── repositories
└── myubuntu
├── _layers
│ └── sha256
│ ├── 0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f
│ │ └── link
│ ├── a362e9896a95c6c3b46f3f958cf378bb818552890669d83e44cc86f2a2c4a726
│ │ └── link
│ ├── a39c84e173f038958d338f55a9e8ee64bb6643e8ac6ae98e08ca65146e668d86
│ │ └── link
│ └── fba52c366bc01edecaf465ef739f5230b3034d01f8fcfe16f005929b2fd0e432
│ └── link
├── _manifests
│ ├── revisions
│ │ └── sha256
│ │ └── bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d
│ │ └── link
│ └── tags
│ └── latest
│ ├── current
│ │ └── link
│ └── index
│ └── sha256
│ └── bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d
│ └── link
└── _uploads
repositories目錄分析
repositories的一級子目錄是鏡像名,這裏是myubuntu。下面對應三個子目錄 _manifests,_layers, _uploads。
- _manifests: 對應鏡像的一些元數據,比如該版本對應的manifest文件的sha256值。其中
bb3c.../link
的值就是bb3c...
,這個值是根據manifest文件的內容sha256sum得到的。manifest文件的各項內容在文檔中有說明 https://github.com/opencontainers/image-spec/blob/main/manifest.md#image-manifest-property-descriptions。該文件中的layers存儲的digest是各layer的gzip壓縮文件的sha256sum值。 - _layers: 其中sha256目錄下的子目錄名是imageid和diffid值,link文件存儲的就是這些值本身。
- _uploads: 目錄爲空,暫且不討論。
root@ubuntu:/home/registry/docker/registry/v2/repositories/myubuntu# sha256sum ../../blobs/sha256/bb/bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d/datta
bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d ../../blobs/sha256/bb/bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d/data
root@ubuntu:/home/registry/docker/registry/v2/repositories/myubuntu# cat ../../blobs/sha256/bb/bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d/data
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1927,
"digest": "sha256:0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f"
}, # ImageID
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 27170900, # 壓縮後的blobs/sha256/xx/xxyy/data文件大小
"digest": "sha256:a39c84e173f038958d338f55a9e8ee64bb6643e8ac6ae98e08ca65146e668d86"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 142,
"digest": "sha256:fba52c366bc01edecaf465ef739f5230b3034d01f8fcfe16f005929b2fd0e432" # diffid_by_digest目錄的文件名
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 140,
"digest": "sha256:a362e9896a95c6c3b46f3f958cf378bb818552890669d83e44cc86f2a2c4a726"
}
]
}
blobs目錄分析
blobs存儲的內容除了各鏡像layer的壓縮後的文件,還包括Manifest Json和Image Json文件(未壓縮)。
root@ubuntu:/home/registry/docker/registry/v2/blobs# file sha256/*/*/data
sha256/0a/0a95d0866cb574d513d22e62014898de8c0108df9c1ec25a75a0dc2cbbaed16f/data: JSON data # Image Json
sha256/a3/a362e9896a95c6c3b46f3f958cf378bb818552890669d83e44cc86f2a2c4a726/data: gzip compressed data, original size modulo 2^32 2560
sha256/a3/a39c84e173f038958d338f55a9e8ee64bb6643e8ac6ae98e08ca65146e668d86/data: gzip compressed data, original size modulo 2^32 68047360
sha256/bb/bb3c3d9d84b6b39e08f9c18ddba9572d2168bf7e7eb656b7bbc1458cbe07220d/data: JSON data # Manifest Json
sha256/fb/fba52c366bc01edecaf465ef739f5230b3034d01f8fcfe16f005929b2fd0e432/data: gzip compressed data, original size modulo 2^32 2560
選一個layer的壓縮文件data解壓看一下內容:
root@ubuntu:/home/registry/docker/registry/v2/blobs# ls -ls sha256/a3/a362e9896a95c6c3b46f3f958cf378bb818552890669d83e44cc86f2a2c4a726/data
4 -rw-r--r-- 1 root root 140 Oct 24 10:12 sha256/a3/a362e9896a95c6c3b46f3f958cf378bb818552890669d83e44cc86f2a2c4a726/data
root@ubuntu:/home/registry/docker/registry/v2/blobs# tar -tvf sha256/a3/a362e9896a95c6c3b46f3f958cf378bb818552890669d83e44cc86f2a2c4a726/data
drwxr-xr-x 0/0 0 2021-10-19 15:43 home/
-rw-r--r-- 0/0 4 2021-10-19 15:33 home/two.txt