Docker鏡像存儲格式分析

新版本的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

參考資料

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