ざっくりいうとコンテナイメージは、レイヤごとのファイルをまとめた tar.gz(あるいは tar)と、 どのようにコンテナを実行するかという設定(環境変数やエントリポイントなど)から構成されていて、 OCI Image Format Specification で標準化が進んでいる。
その OCI Image Format Specification の中でコンテナイメージのアーカイブの形式(save -> load するアレ)も定義されているが、 現在の主流と思われる docker は独自のフォーマットを利用しているので、いまいちポータビリティが悪い。
検証環境
$ cat /etc/redhat-release
Rocky Linux release 8.6 (Green Obsidian)
$ podman -v
podman version 4.1.1
$ docker -v
Docker version 20.10.18, build b40c2f6
docker から podman にイメージを移す
podman が docker-archive 形式を解釈できるためイメージを移せる。 (ただし docker は oci-archive 形式では出力できない)
$ sudo docker pull ubuntu:20.04
$ sudo docker save ubuntu:20.04 -o ubuntu.tar
$ sudo chown -R rocky:rocky ubuntu.tar
$ podman load -i ubuntu.tar
Getting image source signatures
Copying blob b40ed86654e5 done
Copying config a0ce5a295b done
Writing manifest to image destination
Storing signatures
Loaded image: localhost/ubuntu:20.04
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/ubuntu 20.04 a0ce5a295b63 4 weeks ago 75.2 MB
podman から docker にイメージを移す
podman が docker-archive 形式で出力できるため、問題なく実行できる。
$ podman pull ubuntu:20.04
$ podman save ubuntu:20.04 -o ubuntu.tar
Copying blob b40ed86654e5 done
Copying config a0ce5a295b done
Writing manifest to image destination
Storing signatures
$ sudo docker load -i ubuntu.tar
Loaded image: ubuntu:20.04
ただし --format
オプションで oci-archive
を選択すると、docker で load に失敗する。 (docker は oci-archive を解釈できない)
$ podman save --format=oci-archive ubuntu:20.04 -o oci-archive.tar
Copying blob b40ed86654e5 done
Copying config 0366c72f42 done
Writing manifest to image destination
Storing signatures
$ sudo docker load -i oci-archive.tar
open /var/lib/docker/tmp/docker-import-2367465397/blobs/json: no such file or directory
oci-archive と docker-archive
oci-archive と docker-archive を展開してみると、次のようになっていた。 コンテナイメージの tar.gz と 設定 があるのは一緒だけど、いろいろと構造が違いそう。
$ tree --charset=C oci-archive
oci-archive
|-- blobs
| `-- sha256
| |-- 0366c72f42c93f821a53b2ad5c7df9b14a2499d0648f8234c71365be68221b80
| |-- 96babd50cb37eb5509a13822ff6f2162751be3b06f51effc121e4b15f25ad949
| `-- a5ae1e707212700852a8ffccb6218577421efc37a97315bf16f462b42b7b73e3
|-- index.json
`-- oci-layout
2 directories, 5 files
$ tree --charset=C docker-archive
docker-archive
|-- 5e7907c0fec1583e8d47be9244ef7ea9f7bfdc7bd5ce449a87f908c12f1a5586
| |-- json
| |-- layer.tar -> ../b40ed86654e59e1012e1716d5384910f8c3bb58274b7b00fca564a53e9897ba3.tar
| `-- VERSION
|-- a0ce5a295b637a10bc329ded296a0c895e5e56e7c5e674188d423e213b0d213e.json
|-- b40ed86654e59e1012e1716d5384910f8c3bb58274b7b00fca564a53e9897ba3.tar
|-- manifest.json
`-- repositories
1 directory, 7 files
oci-archive について
詳細は https://github.com/opencontainers/image-spec/blob/main/image-layout.md#oci-layout-file に書いてあるが、 いちおうファイルを見てみると、次のようになってた。
$ cat oci-archive/oci-layout | jq
{
"imageLayoutVersion": "1.0.0"
}
$ cat oci-archive/index.json | jq
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:96babd50cb37eb5509a13822ff6f2162751be3b06f51effc121e4b15f25ad949",
"size": 406,
"annotations": {
"org.opencontainers.image.ref.name": "docker.io/library/ubuntu:20.04"
}
}
]
}
$ cat oci-archive/blobs/sha256/96babd50cb37eb5509a13822ff6f2162751be3b06f51effc121e4b15f25ad949 | jq
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:0366c72f42c93f821a53b2ad5c7df9b14a2499d0648f8234c71365be68221b80",
"size": 579
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:a5ae1e707212700852a8ffccb6218577421efc37a97315bf16f462b42b7b73e3",
"size": 29819107
}
]
}
$ cat oci-archive/blobs/sha256/0366c72f42c93f821a53b2ad5c7df9b14a2499d0648f8234c71365be68221b80 | jq
{
"created": "2022-09-01T23:46:27.150780363Z",
"architecture": "amd64",
"os": "linux",
"config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"bash"
]
},
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:b40ed86654e59e1012e1716d5384910f8c3bb58274b7b00fca564a53e9897ba3"
]
},
"history": [
{
"created": "2022-09-01T23:46:26.800519282Z",
"created_by": "/bin/sh -c #(nop) ADD file:ff6963f777661fb16cc12fb04a97c558bd94768a6e4ab5bd90e01f3086818853 in / "
},
{
"created": "2022-09-01T23:46:27.150780363Z",
"created_by": "/bin/sh -c #(nop) CMD [\"bash\"]",
"empty_layer": true
}
]
}
$ file oci-archive/blobs/sha256/a5ae1e707212700852a8ffccb6218577421efc37a97315bf16f462b42b7b73e3
oci-archive/blobs/sha256/a5ae1e707212700852a8ffccb6218577421efc37a97315bf16f462b42b7b73e3: gzip compressed data, original size 75148800
docker で oci-archive をサポートしようとする提案(2016 年に)もあるようだが、まだマージされてなさげ Proposal: Add support for OCI Image Layout ・ Issue #25779 ・ moby/moby ・ GitHub。 docker が oci-archive をサポートしてくれないと、他のツールも docker とのポータビリティのために docker-archive 形式をサポートし続けないといけない未来が見える。