Image Registry では、Image Manifest V 2, Schema 2
から Multi-Architecture Image
の使用が可能になりました。これによって、単一の Image Repository で複数 Architecture Image を扱う事ができます。
この実装は以前から広く利用されていますが、Image Registry の利用者にとっては、あまり馴染みの無いものです。
ここでは、利用者から見た Multi-Architecture Image
の確認方法と取得方法をご紹介します。
Image Manifest V 2, Schema 2
Image Manifest V 2, Schema 2
の説明は以下に記載されています。
https://github.com/distribution/distribution/blob/main/docs/spec/manifest-v2-2.md#manifest-list
https://docs.docker.com/registry/spec/manifest-v2-2/
This second schema version has two primary goals. The first is to allow multi-architecture images, through a "fat manifest" which references image manifests for platform-specific versions of an image.
fat manifest(別称 Manifest List)
とは、以下の Media Type を指します。
application/vnd.docker.distribution.manifest.list.v2+json: Manifest list, aka "fat manifest"
Multi-Architecture の情報は、.manifests[].platform
に記載されます。
Image Manifest の確認
ここでは、Docker Hub の Alpine Image を例にとって、Image Manifest を確認してみます。
また、暗黙の latest
Tag の影響を避けるために、明示的に 3.15
Tag を使用します。
alpine Docker Official Image
A minimal Docker image based on Alpine Linux with a complete package index and only 5 MB in size!
https://hub.docker.com/_/alpine
podman manifest inspect
コマンドで、Image Manifest の Media Type を確認します。
$ podman manifest inspect docker.io/library/alpine:3.15 | jq -r '.mediaType'
application/vnd.docker.distribution.manifest.list.v2+json
この Manifest が Manifest List
であることが分かります。
実装されている Architecture も確認してみます。
$ podman manifest inspect docker.io/library/alpine:3.15 | jq -rc '.manifests[].platform'
{"architecture":"amd64","os":"linux"}
{"architecture":"arm","os":"linux","variant":"v6"}
{"architecture":"arm","os":"linux","variant":"v7"}
{"architecture":"arm64","os":"linux","variant":"v8"}
{"architecture":"386","os":"linux"}
{"architecture":"ppc64le","os":"linux"}
{"architecture":"s390x","os":"linux"}
skopeo inspect --raw
コマンドでも、同様に確認することができます。
$ skopeo inspect --raw docker://docker.io/library/alpine:3.15 | jq -r '.mediaType'
application/vnd.docker.distribution.manifest.list.v2+json
$ skopeo inspect --raw docker://docker.io/library/alpine:3.15 | jq -rc '.manifests[].platform'
{"architecture":"amd64","os":"linux"}
{"architecture":"arm","os":"linux","variant":"v6"}
{"architecture":"arm","os":"linux","variant":"v7"}
{"architecture":"arm64","os":"linux","variant":"v8"}
{"architecture":"386","os":"linux"}
{"architecture":"ppc64le","os":"linux"}
{"architecture":"s390x","os":"linux"}
oc image info
コマンドでも、実装されている Architecture を確認することができます。
$ oc image info docker.io/library/alpine:3.15
error: the image is a manifest list and contains multiple images - use --filter-by-os to select from:
OS DIGEST
linux/amd64 sha256:4ff3ca91275773af45cb4b0834e12b7eb47d1c18f770a0b151381cd227f4c253
linux/arm/v6 sha256:3c66139adbd2513f9fc56eff206513ffc8356b282bed31a4e74c7eb926b850aa
linux/arm/v7 sha256:0615cdd745d0b78e7e6ac3a7b1f02e4daefa664eae0324120955f4e4c91bea3f
linux/arm64/v8 sha256:c3c58223e2af75154c4a7852d6924b4cc51a00c821553bbd9b3319481131b2e0
linux/386 sha256:72af6266bafde8c78d5f20a2a85d0576533ce1ecd6ed8bcf7baf62a743f3b24d
linux/ppc64le sha256:0f3aeb63bb71ccd3ba0020772f5617e50946a4f2713953c3f494203f1544ea03
linux/s390x sha256:83167bc8418071fc178d191ed604f44792c94ad3c3ac26350c29d2445f6a9644
特定 Architecture Image の確認(inspect)
skopeo inspect
コマンドで、特定 Platform の Manifest を確認することができます。
先程、skopeo inspect --raw
コマンドで確認した情報を使用してみます。
$ skopeo inspect --override-arch=arm --override-os=linux --override-variant=v7 docker://docker.io/library/alpine:3.15
{
"Name": "docker.io/library/alpine",
"Digest": "sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454",
"RepoTags": [
"2.6",
"2.7",
"20190228",
"20190408",
"20190508",
"20190707",
"20190809",
"20190925",
"20191114",
"20191219",
"20200122",
"20200319",
"20200428",
"20200626",
"20200917",
"20201218",
"20210212",
"20210730",
"20210804",
"20220316",
"20220328",
"3",
"3.1",
"3.10",
"3.10.0",
"3.10.1",
"3.10.2",
"3.10.3",
"3.10.4",
"3.10.5",
"3.10.6",
"3.10.7",
"3.10.8",
"3.10.9",
"3.11",
"3.11.0",
"3.11.10",
"3.11.11",
"3.11.12",
"3.11.13",
"3.11.2",
"3.11.3",
"3.11.5",
"3.11.6",
"3.11.7",
"3.11.8",
"3.11.9",
"3.12",
"3.12.0",
"3.12.1",
"3.12.10",
"3.12.11",
"3.12.12",
"3.12.2",
"3.12.3",
"3.12.4",
"3.12.5",
"3.12.6",
"3.12.7",
"3.12.8",
"3.12.9",
"3.13",
"3.13.0",
"3.13.1",
"3.13.10",
"3.13.2",
"3.13.3",
"3.13.4",
"3.13.5",
"3.13.6",
"3.13.7",
"3.13.8",
"3.13.9",
"3.14",
"3.14.0",
"3.14.1",
"3.14.2",
"3.14.3",
"3.14.4",
"3.14.5",
"3.14.6",
"3.15",
"3.15.0",
"3.15.0-rc.4",
"3.15.1",
"3.15.2",
"3.15.3",
"3.15.4",
"3.16",
"3.16.0",
"3.2",
"3.3",
"3.4",
"3.5",
"3.6",
"3.6.5",
"3.7",
"3.7.3",
"3.8",
"3.8.4",
"3.8.5",
"3.9",
"3.9.2",
"3.9.3",
"3.9.4",
"3.9.5",
"3.9.6",
"edge",
"latest"
],
"Created": "2022-04-04T23:57:35.203088109Z",
"DockerVersion": "20.10.12",
"Labels": null,
"Architecture": "arm",
"Os": "linux",
"Layers": [
"sha256:57fb4b5f1a47c953ca5703f0f81ce14e5d01cf23aa79558b5adb961cc526e320"
],
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
]
}
"Architecture": "arm"
"Os": "linux"
と表示されていることが確認できます。
また、skopeo inspect --config
コマンドで、Image Configuration
を確認することができます。
OCI Image Configuration
https://github.com/opencontainers/image-spec/blob/main/config.md
$ skopeo inspect --config --override-arch=arm --override-os=linux --override-variant=v7 docker://docker.io/library/alpine:3.15
{
"created": "2022-04-04T23:57:35.203088109Z",
"architecture": "arm",
"variant": "v7",
"os": "linux",
"config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh"
]
},
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:f3cad9f8ac1ee2f04e09db4d66d14c7806b881917a632bed9ae1117c6b10e1f9"
]
},
"history": [
{
"created": "2022-04-04T23:57:34.600819269Z",
"created_by": "/bin/sh -c #(nop) ADD file:20f8cdddc53a4a8bd78945fc32fe08e9f80ab3b16dc20a9aa4ba73b79f2bc71c in / "
},
{
"created": "2022-04-04T23:57:35.203088109Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
"empty_layer": true
}
]
}
"architecture": "arm"
"variant": "v7"
"os": "linux"
と表示されていることが確認できます。
特定 Architecture Image の取得(Pull)
Multi-Architecture Image
の Image Repository から、特定 Architecture Image を取得することもできます。
何も指定せずに Image を Pull すると、現在の環境に対応した Image が取得されます。
$ podman pull docker.io/library/alpine:3.15
Trying to pull docker.io/library/alpine:3.15...
Getting image source signatures
Copying blob df9b9388f04a done
Copying config 0ac33e5f5a done
Writing manifest to image destination
Storing signatures
0ac33e5f5afa79e084075e8698a22d574816eea8d7b7d480586835657c3e1c8b
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/alpine 3.15 0ac33e5f5afa 2 months ago 5.86 MB
$ podman inspect 0ac33e5f5afa | jq -rc '.[].Architecture'
amd64
$ podman image inspect 0ac33e5f5afa
[
{
"Id": "0ac33e5f5afa79e084075e8698a22d574816eea8d7b7d480586835657c3e1c8b",
"Digest": "sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454",
"RepoTags": [
"docker.io/library/alpine:3.15"
],
"RepoDigests": [
"docker.io/library/alpine@sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454",
"docker.io/library/alpine@sha256:a777c9c66ba177ccfea23f2a216ff6721e78a662cd17019488c417135299cd89"
],
"Parent": "",
"Comment": "",
"Created": "2022-04-05T00:19:59.912662499Z",
"Config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh"
]
},
"Version": "20.10.12",
"Author": "",
"Architecture": "amd64",
"Os": "linux",
"Size": 5859398,
"VirtualSize": 5859398,
"GraphDriver": {
"Name": "overlay",
"Data": {
"UpperDir": "/var/lib/containers/storage/overlay/4fc242d58285699eca05db3cc7c7122a2b8e014d9481f323bd9277baacfa0628/diff",
"WorkDir": "/var/lib/containers/storage/overlay/4fc242d58285699eca05db3cc7c7122a2b8e014d9481f323bd9277baacfa0628/work"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:4fc242d58285699eca05db3cc7c7122a2b8e014d9481f323bd9277baacfa0628"
]
},
"Labels": null,
"Annotations": {},
"ManifestType": "application/vnd.docker.distribution.manifest.v2+json",
"User": "",
"History": [
{
"created": "2022-04-05T00:19:59.790636867Z",
"created_by": "/bin/sh -c #(nop) ADD file:5d673d25da3a14ce1f6cf66e4c7fd4f4b85a3759a9d93efb3fd9ff852b5b56e4 in / "
},
{
"created": "2022-04-05T00:19:59.912662499Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
"empty_layer": true
}
],
"NamesHistory": [
"docker.io/library/alpine:3.15"
]
}
]
ここで、先程と同様に --arch=arm
--os=linux
--variant=v7
を指定してみます。
$ podman pull --arch=arm --os=linux --variant=v7 docker.io/library/alpine:3.15
Trying to pull docker.io/library/alpine:3.15...
Getting image source signatures
Copying blob 57fb4b5f1a47 done
Copying config d378343b49 done
Writing manifest to image destination
Storing signatures
d378343b49e42a7f34e8c5a63abea857964e5ebc62628e6f9d21dda419f0efc3
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 0ac33e5f5afa 2 months ago 5.86 MB
docker.io/library/alpine 3.15 d378343b49e4 2 months ago 4.09 MB
$ podman inspect d378343b49e4 | jq -rc '.[].Architecture'
arm
$ podman inspect d378343b49e4
[
{
"Id": "d378343b49e42a7f34e8c5a63abea857964e5ebc62628e6f9d21dda419f0efc3",
"Digest": "sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454",
"RepoTags": [
"docker.io/library/alpine:3.15"
],
"RepoDigests": [
"docker.io/library/alpine@sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454",
"docker.io/library/alpine@sha256:dc18010aabc13ce121123c7bb0f4dcb6879ce22b4f7c65669a2c634b5ceecafb"
],
"Parent": "",
"Comment": "",
"Created": "2022-04-04T23:57:35.203088109Z",
"Config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh"
]
},
"Version": "20.10.12",
"Author": "",
"Architecture": "arm",
"Os": "linux",
"Size": 4087379,
"VirtualSize": 4087379,
"GraphDriver": {
"Name": "overlay",
"Data": {
"UpperDir": "/var/lib/containers/storage/overlay/f3cad9f8ac1ee2f04e09db4d66d14c7806b881917a632bed9ae1117c6b10e1f9/diff",
"WorkDir": "/var/lib/containers/storage/overlay/f3cad9f8ac1ee2f04e09db4d66d14c7806b881917a632bed9ae1117c6b10e1f9/work"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:f3cad9f8ac1ee2f04e09db4d66d14c7806b881917a632bed9ae1117c6b10e1f9"
]
},
"Labels": null,
"Annotations": {},
"ManifestType": "application/vnd.docker.distribution.manifest.v2+json",
"User": "",
"History": [
{
"created": "2022-04-04T23:57:34.600819269Z",
"created_by": "/bin/sh -c #(nop) ADD file:20f8cdddc53a4a8bd78945fc32fe08e9f80ab3b16dc20a9aa4ba73b79f2bc71c in / "
},
{
"created": "2022-04-04T23:57:35.203088109Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
"empty_layer": true
}
],
"NamesHistory": [
"docker.io/library/alpine:3.15"
]
}
]
先に取得した amd64 Image(IMAGE ID: 0ac33e5f5afa)と REPOSITORY、TAG が重複するため、amd64 Image が Dangling Image
として扱われている事が分かります。
Prune unused Docker objects
https://docs.docker.com/config/pruning/
なお、当然ながら arm Image を amd64 環境で実行することはできません。
$ podman inspect docker.io/library/alpine:3.15 | jq -rc '.[].Architecture'
arm
$ podman run -ti docker.io/library/alpine:3.15 sh
standard_init_linux.go:228: exec user process caused: exec format error
このように、podman
コマンドや skopeo
コマンドを利用して、Multi-Architecture Image
の Manifest の確認や、特定 Architecture Image の取得をすることができます。