Docker イメージには IMAGE ID と DIGEST という一見とてもよく似た値がある。
$ docker image ls --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
node 22 sha256:f6b9c31ace(...略) f95b9fc1b158 4 weeks ago 1.12GB
さらに上の IMAGE ID は実は省略形で --no-trunc
オプションをつけると
$ docker image ls --digests --no-trunc
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
node 22 sha256:f6b9c31ace(...略) sha256:f95b9fc1b1(...略) 4 weeks ago 1.12GB
となり
IMAGE ID: sha256:f95b9fc1b158a04a1d2674d648eca060c7d1be1b3cea394a6534425f23210203
DIGEST: sha256:f6b9c31ace05502dd98ef777aaa20464362435dcc5e312b0e213121dcf7d8b95
だとわかる。ますますよく似ている。これらがなんなのか調べる。
IMAGE ID と DIGEST の使われ方
DIGEST は docker pull
や Dockerfile の FROM
文などでリモートリポジトリからイメージをとってくるときに@
に続けて書くことで指定できる。
$ docker pull node@sha256:f6b9c31ace05502dd98ef777aaa20464362435dcc5e312b0e213121dcf7d8b95
これによって使うイメージを特定のバージョンに固定することができる。
IMAGE ID はあまり有効な使い道がないが、ローカルにあるイメージを参照するときに名前の代わりに使うことができる。
$ docker run -it sha256:f95b9fc1b158a04a1d2674d648eca060c7d1be1b3cea394a6534425f23210203 /bin/bash
IMAGE ID はリモートリポジトリから取ってくる時には使えない。
$ docker pull sha256:f95b9fc1b158a04a1d2674d648eca060c7d1be1b3cea394a6534425f23210203
Error response from daemon: pull access denied for sha256, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
$ docker pull node@sha256:f95b9fc1b158a04a1d2674d648eca060c7d1be1b3cea394a6534425f23210203
Error response from daemon: unknown: manifest schema unsupported
「Docker イメージ」とは何か
我々が一般に「Docker イメージ」と呼ぶとき、それは実はいくつかのもので構成されている。
「Docker イメージ」は以下のように構成されている。
イメージマニフェストが、ある一つのプラットフォーム(CPUやOS)に対応するイメージを指し、マニフェストリストはプラットフォームごとに異なるイメージを同じ名前で扱えるようにまとめたものである。:latest
などのタグはマニフェストリストを指し示している。
イメージマニフェストはコンフィグと複数のレイヤーから構成されている。図には表れていないがコンフィグにはレイヤーのハッシュ値も含まれている。なので実質的にコンフィグにはある一つのプラットフォームに対応するイメージ全体のハッシュが含まれている。
我々が普通に docker pull
等する時に指定しているのはマニフェストリストである。マニフェストリストの中から実行しているプラットフォームに対応するイメージマニフェストを取得するようになっている。
IMAGE ID と DIGEST とは何か
ここまで来れば話は簡単で、IMAGE ID とはコンフィグのハッシュ値、 DIGEST とはマニフェストリストのハッシュ値である。
なので異なるプラットフォームで同じイメージを docker pull
してきた場合、DIGEST は同じだが IMAGE ID は異なる。
$ docker pull node:22
$ docker image ls --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
node 22 sha256:f6b9c31ace(...略) f95b9fc1b158 4 weeks ago 1.12GB
$ docker pull node:22
$ docker image ls --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
node 22 sha256:f6b9c31ace(...略) c46899c5ff75 4 weeks ago 1.12GB
また同じプラットフォームで IMAGE ID は同じだが DIGEST は異なる場合もありうる。これは新しいバージョンのマニフェストリストが作られたが、一部のプラットフォームのイメージだけが更新されて自分のプラットフォームのイメージは更新されなかった場合におこる。
$ docker image ls --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
python <none> sha256:1435f1edde(...略) 23e11cf6844c 7 days ago 1GB
python <none> sha256:a8462db480(...略) 23e11cf6844c 7 days ago 1GB
Docker Hub に記載の DIGEST との関係
Docker Hub でタグを選択すると以下のような画面になる。
このうち「INDEX DIGEST」はマニフェストリストのハッシュ、つまりdocker image ls
のDIGEST
のこと。「MANIFEST DIGEST」はイメージマニフェストのハッシュで、コンフィグのハッシュとは異なりdocker image ls
では見られない値だと思われる。
歴史的経緯
イメージマニフェストやマニフェストリストの概念は後から付け足されたものらしい。よってもともとはコンフィグに対する IMAGE ID しか存在しておらずマニフェストリストに対する DIGEST も後から作られた。Docker Hub のような Docker イメージのリポジトリを生み出すときに追加された模様。なのでこのように分かりづらい状況になっているのだと思う。
参考