イメージがレジストリ V2 にプッシュされた場合、イメージ ID もレジストリにプッシュされますか? V2 レジストリから特定のリポジトリのイメージ ID を取得することは可能ですか?
3 に答える
イメージが Docker Client 1.10 以降でプッシュされた場合、レジストリからイメージ ID を取得できます。
GET /v2/<image>/manifests/<tag>
リクエストにはヘッダーを含める必要があります
Accept: application/vnd.docker.distribution.manifest.v2+json
応答では、イメージ ID はContent-Docker-Digest
応答ヘッダーにあります。
[2020 年 11 月に回答を更新]
docker イメージを使用する場合、対処すべきことがたくさんあります。各ファイル システム レイヤーには一意の sha があり、レイヤーが圧縮されてレジストリに格納されると更新されます。イメージ構成を表す json オブジェクトで計算された sha があり、ローカルでイメージ ID を検索すると、次のように表示されます。
$ docker inspect busybox:latest --format '{{ .ID }}'
sha256:f0b02e9d092d905d0d87a8455a1ae3e9bb47b4aa3dc125125ca5cd10d6441c9f
レジストリには、単一のプラットフォームのマニフェストの sha があります。このマニフェストには、イメージ構成とさまざまなレイヤーへのポインターが含まれています。また、これらの個々のプラットフォームのそれぞれを指すマルチプラットフォーム マニフェストの sha もあります。それらを掘り下げてみましょう。まず、匿名のリクエストで Docker Hub レジストリをクエリするために使用するスクリプトを次に示します。
$ cat manifest-v2.sh
#!/bin/sh
ref="${1:-library/ubuntu:latest}"
sha="${ref#*@}"
if [ "$sha" = "$ref" ]; then
sha=""
fi
wosha="${ref%%@*}"
repo="${wosha%:*}"
tag="${wosha##*:}"
if [ "$tag" = "$wosha" ]; then
tag="latest"
fi
api="application/vnd.docker.distribution.manifest.v2+json"
apil="application/vnd.docker.distribution.manifest.list.v2+json"
token=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull" \
| jq -r '.token')
curl -H "Accept: ${api}" -H "Accept: ${apil}" \
-H "Authorization: Bearer $token" \
-s "https://registry-1.docker.io/v2/${repo}/manifests/${sha:-$tag}" | jq .
次に、latest タグのマニフェストを取得します。
$ ./manifest-v2.sh library/busybox:latest
{
"manifests": [
{
"digest": "sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc",
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"platform": {
"architecture": "amd64",
"os": "linux"
},
"size": 527
},
{
"digest": "sha256:a7c572c26ca470b3148d6c1e48ad3db90708a2769fdf836aa44d74b83190496d",
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v5"
},
"size": 527
},
...
結果はマニフェスト リストです。amd64 プラットフォームだけの sha を取得します。
$ ./manifest-v2.sh library/busybox@sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1493,
"digest": "sha256:f0b02e9d092d905d0d87a8455a1ae3e9bb47b4aa3dc125125ca5cd10d6441c9f"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 764619,
"digest": "sha256:9758c28807f21c13d05c704821fdd56c0b9574912f9b916c65e1df3e6b8bc572"
}
]
}
そこには単一のレイヤーと構成オブジェクトがあり、その構成のapplication/vnd.docker.container.image.v1+json
メディア タイプの sha はイメージ id と一致しますsha256:f0b02e9d092d9...
。Accept
これは、マニフェスト スクリプトがヘッダーを挿入する理由である、レジストリからの v2 出力で簡単に選択できます。
YMMV、IANAL などの一致が保証されているとは思わないことに注意してください。ドッカー エンジンのさまざまなバージョンによって無視されるフィールドの追加/削除をドッカーが予見できます。したがって、この動作の強い依存関係は避けたいと思います。
この sha は、イメージをプルするためにレジストリでイメージを一意に識別するために使用する sha とは異なることに注意してください。そのためには、マニフェスト sha が必要です。マニフェスト リストがある場合は、それを使用する必要があります。タグを解決するときに HEAD リクエストだけでこの sha を確認できます ( -I
curl のパラメーターを使用):
$ cat manifest-v2-head.sh
#!/bin/sh
ref="${1:-library/ubuntu:latest}"
sha="${ref#*@}"
if [ "$sha" = "$ref" ]; then
sha=""
fi
wosha="${ref%%@*}"
repo="${wosha%:*}"
tag="${wosha##*:}"
if [ "$tag" = "$wosha" ]; then
tag="latest"
fi
# echo "Looking up repo $repo, ${sha:-$tag}"
# api="application/vnd.oci.image.index.v1+json"
# api="application/vnd.oci.image.manifest.v1+json"
api="application/vnd.docker.distribution.manifest.v2+json"
apil="application/vnd.docker.distribution.manifest.list.v2+json"
token=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull" \
| jq -r '.token')
curl -H "Accept: ${api}" -H "Accept: ${apil}" \
-H "Authorization: Bearer $token" \
-I -s "https://registry-1.docker.io/v2/${repo}/manifests/${sha:-$tag}"
$ ./manifest-v2-head.sh library/busybox:latest
HTTP/1.1 200 OK
Content-Length: 2080
Content-Type: application/vnd.docker.distribution.manifest.list.v2+json
Docker-Content-Digest: sha256:a9286defaba7b3a519d585ba0e37d0b2cbee74ebfe590960b0b1d6a5e97d1e1d
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:a9286defaba7b3a519d585ba0e37d0b2cbee74ebfe590960b0b1d6a5e97d1e1d"
Date: Wed, 18 Nov 2020 14:38:59 GMT
Strict-Transport-Security: max-age=31536000
RateLimit-Limit: 250;w=21600
RateLimit-Remaining: 250;w=21600
上記から、できdocker pull busybox@sha:a9286d...
ます。
ここにあるコマンドはすべて Docker Hub 固有のものです。他のレジストリを操作するために、他のレジストリへの認証および API 呼び出しを処理するregctl
コマンドをregclientプロジェクトで使用できます。
$ regctl image manifest busybox
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1493,
"digest": "sha256:f0b02e9d092d905d0d87a8455a1ae3e9bb47b4aa3dc125125ca5cd10d6441c9f"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 764619,
"digest": "sha256:9758c28807f21c13d05c704821fdd56c0b9574912f9b916c65e1df3e6b8bc572"
}
]
}
$ regctl image digest busybox --list
sha256:a9286defaba7b3a519d585ba0e37d0b2cbee74ebfe590960b0b1d6a5e97d1e1d
$ regctl image digest busybox
sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc
元の答え:
イメージ ID 自体は、レジストリ API でアクセス可能な場所には保存されません。ローカル レジストリを使用した例を次に示します。
bash$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
Unable to find image 'registry:2' locally
2: Pulling from library/registry
...
bash$ docker tag busybox localhost:5000/busybox
bash$ docker push localhost:5000/busybox
The push refers to a repository [localhost:5000/busybox]
5f70bf18a086: Pushed
...
bash$ curl http://localhost:5000/v2/busybox/tags/list
{"name":"busybox","tags":["latest"]}
bash$ curl http://localhost:5000/v2/busybox/manifests/latest
{
"schemaVersion": 1,
"name": "busybox",
"tag": "latest",
"architecture": "amd64",
"fsLayers": [
{
"blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
},
{
"blobSum": "sha256:385e281300cc6d88bdd155e0931fbdfbb1801c2b0265340a40481ee2b733ae66"
}
],
"history": [
{
"v1Compatibility": "{\"architecture\":\"amd64\",\"config\":{\"Hostname\":\"156e10b83429\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"sh\"],\"Image\":\"56ed16bd6310cca65920c653a9bb22de6b235990dcaa1742ff839867aed730e5\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"container\":\"5f8098ec29947b5bea80483cd3275008911ce87438fed628e34ec0c522665510\",\"container_config\":{\"Hostname\":\"156e10b83429\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [\\\"sh\\\"]\"],\"Image\":\"56ed16bd6310cca65920c653a9bb22de6b235990dcaa1742ff839867aed730e5\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"created\":\"2016-03-18T18:22:48.810791943Z\",\"docker_version\":\"1.9.1\",\"id\":\"437595becdebaaaf3a4fc3db02c59a980f955dee825c153308c670610bb694e1\",\"os\":\"linux\",\"parent\":\"920777304d1d5e337bc59877253e946f224df5aae64c72538672eb74637b3c9e\"}"
},
{
"v1Compatibility": "{\"id\":\"920777304d1d5e337bc59877253e946f224df5aae64c72538672eb74637b3c9e\",\"created\":\"2016-03-18T18:22:48.262403239Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) ADD file:47ca6e777c36a4cfffe3f918b64a445c8f32300deeb9dfa5cc47261bd7b75d21 in /\"]}}"
}
],
"signatures": [
{
"header": {
"jwk": {
"crv": "P-256",
"kid": "FIFX:SJRD:AQHW:MCFX:M6WC:LXI2:3VO2:4LFW:UHDZ:QUN7:OLX4:6WGD",
"kty": "EC",
"x": "Xm8wJTzw3nb--rGoD3dxjKffikj7Snb9dHW-qGbqSAM",
"y": "GnATS--7lVcA_-jQGuDKTtjhmnGgvBrx8rLdlPOJV3U"
},
"alg": "ES256"
},
"signature": "f8NVzOF6ujm_0COedniGCGL_q3KsTfKFM9T8ZZDf2MSIMJ3TYoR_s795NqdEy8yWaoLuT2LoI0BCEsuOTZUhCw",
"protected": "eyJmb3JtYXRMZW5ndGgiOjE5MTQsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNi0wNi0xMVQwMToxMzoyMVoifQ"
}
]
bash$ curl -I http://localhost:5000/v2/busybox/manifests/latest
HTTP/1.1 200 OK
Content-Length: 2561
Content-Type: application/vnd.docker.distribution.manifest.v1+prettyjws
Docker-Content-Digest: sha256:e45f25b1760f616e65f106b424f4ef29185fbd80822255d79dabc73b8eb715ad
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:e45f25b1760f616e65f106b424f4ef29185fbd80822255d79dabc73b8eb715ad"
X-Content-Type-Options: nosniff
Date: Sat, 11 Jun 2016 01:21:26 GMT
これらの API 呼び出しのどこにも、ローカルで表示される目的の 47bcc53... イメージ ID を見つけることができませんでした。
bash$ docker inspect busybox:latest
[
{
"Id": "sha256:47bcc53f74dc94b1920f0b34f6036096526296767650f223433fe65c35f149eb",
"RepoTags": [
"busybox:latest",
"localhost:5000/busybox:latest"
],
...
このイメージ仕様から、イメージ ID は再現可能なハッシュであり、異なるシステムでイメージ ID に同じ値が表示されます。
ImageID 各イメージの ID は、構成 JSON の SHA256 ハッシュによって与えられます。これは、256 ビットの 16 進エンコーディングとして表されます。ハッシュ化された構成 JSON は画像内の各レイヤーのハッシュを参照するため、この ImageID の定式化により、画像はコンテンツを追加可能になります。
したがって、API 呼び出しから構成 JSON を再現できる場合は、イメージ ID を自分で生成できる可能性があります。