how to generate docker image Layer DiffID?

Viewed 1660

I read the Docker Image Specification v1.2.0. It said:

Layers are referenced by cryptographic hashes of their serialized representation. This is a SHA256 digest over the tar archive used to transport the layer, represented as a hexadecimal encoding of 256 bits, e.g., sha256:a9561eb1b190625c9adb5a9513e72c4dedafc1cb2d4c5236c9a6957ec7dfd5a9. Layers must be packed and unpacked reproducibly to avoid changing the layer ID, for example by using tar-split to save the tar headers. Note that the digest used as the layer ID is taken over an uncompressed version of the tar.

I want find out the specific process. So I try the flowing:

chao@manager-02:~/image_lab$ docker image save busybox:1.27-glibc > busybox.tar
chao@manager-02:~/image_lab$ tar -xvf busybox.tar 
47f54add1c481ac7754f9d022c2c420099a16e78faf85b4f2926a96ee40277fe/
47f54add1c481ac7754f9d022c2c420099a16e78faf85b4f2926a96ee40277fe/VERSION
47f54add1c481ac7754f9d022c2c420099a16e78faf85b4f2926a96ee40277fe/json
47f54add1c481ac7754f9d022c2c420099a16e78faf85b4f2926a96ee40277fe/layer.tar
fe2d514cd10652d0384abf2b051422722f9cdd7d189e661450cba8cd387a7bb8.json
manifest.json
repositories
chao@manager-02:~/image_lab$ ls
47f54add1c481ac7754f9d022c2c420099a16e78faf85b4f2926a96ee40277fe  Dockerfile                                                             manifest.json
busybox.tar                                                       fe2d514cd10652d0384abf2b051422722f9cdd7d189e661450cba8cd387a7bb8.json  repositories
chao@manager-02:~/image_lab$ sha256sum 47f54add1c481ac7754f9d022c2c420099a16e78faf85b4f2926a96ee40277fe/layer.tar 
545903a7a569bac2d6b75f18d399251cefb53e12af9f644f4d9e6e0d893095c8  47f54add1c481ac7754f9d022c2c420099a16e78faf85b4f2926a96ee40277fe/layer.tar

Why the sha256sum I generated is not equal to sha256sum of the image layer?

1 Answers

Technically, you did answer your own question. This is what the Docker image spec says (as you quoted):

[DiffID] is a SHA256 digest over the tar archive used to transport the layer (...) Note that the digest used as the layer ID is taken over an uncompressed version of the tar.]"

But later on, when describing the content of the image, the same doc also says:

There is a directory for each layer in the image. Each directory is named with a 64 character hex name that is deterministically generated from the layer information. These names are not necessarily layer DiffIDs or ChainIDs.

If you look at the manifest.json of your image, you'll see that the rootfs.diff_ids array points to same hash you obtained by sha256suming layer.tar. The hash you computed is the DiffID.

The obvious follow up question then is: where did that directory name came from?!

I am not sure, but it seems that it is generated by whatever algorithm was used to generate layer IDs on the older Docker image format v1. Back then, images and layers were conflated into a single concept.

I'd guess they kept the v1 directory names unchanged to simplify the use old layers with newer Docker versions.

Footnote: AFAIU, the Docker image format spec is superseded by the OCI image format specification, but docker image save seems to generate archives in the older Docker format.)

Related