Skip to content

IPFSでのコンテナイメージの配布(実験的)

⚡ 必要条件 nerdctl >= 0.14

IPFSを使用して、レジストリなしでコンテナイメージを配布できます。

IPFSのサポートは完全にオプションです。IPFSデーモンのインストールと実行をオプトインしない限り、ホストはどのP2Pネットワークにも接続されていません。

前提 条件

ipfs デーモン

Kubo(旧go-ipfs)などのIPFSデーモンがホストで実行されていることを確認してください。 たとえば、次のコマンドを使用して Kubo を実行できます。

ipfs デーモン

ルートレスモードでは、containerd-rootless-setuptool.sh を使用して ipfs デーモンをインストールする必要があります。

containerd-rootless-setuptool.sh -- install-ipfs --init

注意:上記のコマンドの出力で説明されているように、IPFS_PATHを正しく設定してください。

ℹ If you want to expose some ports of ipfs daemon (e.g. 4001), you can install rootless containerd using containerd-rootless-setuptool.sh install with CONTAINERD_ROOTLESS_ROOTLESSKIT_FLAGS="--publish=0.0.0.0:4001:4001/tcp" environment variable.

ℹ IPFSがインターネット上のノードと通信したくない場合は、--offlineフラグを使用してIPFSデーモンをオフラインモードで実行するか、ここで説明するようにプライベートIPFSネットワークを作成できます。

ℹ IPFSデーモンをローカルで起動する代わりに、--ipfs-addressフラグを使用してIPFS APIのアドレスを指定できます。

IPFS対応イメージとOCIの互換性

IPFSでのイメージ配信は、OCI互換のIPFS対応イメージフォーマットによって実現されます。 nerdctlは、必要に応じてイメージをIPFS対応に自動的に変換します。 たとえば、nerdctlがイメージをIPFSにプッシュするときに、そのイメージがIPFS対応でない場合、そのイメージをIPFS対応のイメージに変換します。

IPFS対応のイメージ形式の詳細については、stargz-snapshotterプロジェクトのドキュメントを参照してください。

IPFSでのnerdctlの使用

nerdctlは、IPFS上のイメージを処理するためのイメージ名プレフィックス ipfs:// をサポートしています。

nerdctl push ipfs://<image-name>

nerdctl pushの場合、containerdに格納され ipfs:// 任意のイメージ名にプレフィックスを指定できます。 このプレフィックスが指定されると、nerdctlはそのイメージをIPFSにプッシュします。

> nerdctl push ipfs://ubuntu:20.04
INFO[0000] pushing image "ubuntu:20.04" to IPFS
INFO[0000] ensuring image contents
bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze

出力の最後の行に、プッシュされたイメージのIPFS CIDが出力されます。 この CID を使用して、IPFS からこのイメージをプルできます。

--estargzオプションを指定して、IPFSでeStargzベースの遅延プルを有効にすることもできます。 詳細については、後のセクションを参照してください。

> nerdctl push --estargz ipfs://fedora:36
INFO[0000] pushing image "fedora:36" to IPFS
INFO[0000] ensuring image contents
INFO[0011] converted "application/vnd.docker.image.rootfs.diff.tar.gzip" to sha256:cd4be969f12ef45dee7270f3643f796364045edf94cfa9ef6744d91d5cdf2208
bafkreibp2ncujcia663uum25ustwvmyoguxqyzjnxnlhebhsgk2zowscye

nerdctl pull ipfs://<CID> and nerdctl run ipfs://<CID>

IPFSからイメージを取り出すには、CIDはイメージのCIDである ipfs://<CID> を指定します。

> nerdctl pull ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze
bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze:                      resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:28bfa1fc6d491d3bee91bab451cab29c747e72917efacb0adc4e73faffe1f51c:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:f6eed19a2880f1000be1d46fb5d114d094a59e350f9d025580f7297c8d9527d5: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 1.2 s                                                                    total:  27.2 M (22.7 MiB/s)

nerdctl run では、同じイメージ名の構文もサポートされています。 このコマンドを指定すると、IPFSからイメージがプルされます。

> nerdctl run --rm -it ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze echo hello
hello

また、そのイメージをコンテナー レジストリにプッシュすることもできます。

nerdctl tag ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze ghcr.io/ktock/ubuntu:20.04-ipfs
nerdctl push ghcr.io/ktock/ubuntu:20.04-ipfs

プッシュされたイメージは、他の(IPFSに依存しない)ランタイムで実行できます。

> docker run --rm -it ghcr.io/ktock/ubuntu:20.04-ipfs echo hello
hello

ℹ IPFS対応イメージはOCI互換ですが、containerdpodmanなどの一部のランタイムにはバグがあり、その場合にイメージのプルに失敗することに注意してください。containerdはv1.5.8以降でこれを修正し、podmanはコミットb55fb86c28b7d743cf59701332cd78d4294c7c54以降これを修正しました。

nerdctl buildlocalhost:5050/ipfs/<CID> イメージリファレンス

IPFSのベースイメージを使用してイメージを構築できます。 BuildKit >= v0.9.3 が必要です。

Dockerfile では、プレフィックスの代わりに、次のイメージ参照を使用して、IPFS 上のイメージ ipfs:// ポイントする必要があります。

localhost:5050/ipfs/<CID>

ここで、CIDはイメージのIPFS CIDです。

ℹ nerdctl と BuildKit の将来のバージョンでは、ipfs:// プレフィックスが Dockerfile でサポートされるはずです。

このイメージ参照を使用して、IPFS上にイメージを構築できます。

FROM localhost:5050/ipfs/bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze
RUN echo hello > /hello

nerdctl ipfs registry serve が実行されていることを確認します。 これにより、nerdctl buildはIPFSからイメージをプルできます。

$ nerdctl ipfs registry serve &

その後、nerdctl build を使用してこの Dockerfile をビルドできます。

> nerdctl build -t hello .
[+] Building 5.3s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                                                                                              0.0s
 => => transferring dockerfile: 146B                                                                                                              0.0s
 => [internal] load .dockerignore                                                                                                                 0.0s
 => => transferring context: 2B                                                                                                                   0.0s
 => [internal] load metadata for localhost:5050/ipfs/bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze:latest                           0.1s
 => [1/2] FROM localhost:5050/ipfs/bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze@sha256:28bfa1fc6d491d3bee91bab451cab29c747e72917e  3.8s
 => => resolve localhost:5050/ipfs/bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze@sha256:28bfa1fc6d491d3bee91bab451cab29c747e72917e  0.0s
 => => sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54 28.57MB / 28.57MB                                                  2.1s
 => => extracting sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54                                                         1.7s
 => [2/2] RUN echo hello > /hello                                                                                                                 0.6s
 => exporting to oci image format                                                                                                                 0.6s
 => => exporting layers                                                                                                                           0.1s
 => => exporting manifest sha256:b96d490d134221ab121af91a42b13195dd8c5bf941012d7bfe07eabcf5259eda                                                 0.0s
 => => exporting config sha256:bd706574eab19009585b98826b06e63cf6eacf8d7193504dae75caa760332ca2                                                   0.0s
 => => sending tarball                                                                                                                            0.5s
unpacking docker.io/library/hello:latest (sha256:b96d490d134221ab121af91a42b13195dd8c5bf941012d7bfe07eabcf5259eda)...done
> nerdctl run --rm -it hello cat /hello
hello

注意: --ipfs フラグは v1.2.0 以降削除されました。nerdctl ipfs registry serve を使用して localhost レジストリを自分で起動する必要があります。

localhost:5050/ipfs/<CID>nerdctl ipfs レジストリの詳細

現在のところ、BuildKit はipfs://プレフィックスをサポートしていないため nerdctl は IPFS に裏打ちされた読み取り専用のローカルレジストリを持つことで IPFS でのビルドを実現しています。 このレジストリは、レジストリ API 要求を IPFS 操作に変換します。 そのため、IPFSに依存しないツールは、このレジストリを介してIPFSからイメージを引き出すことができます。

このレジストリは、サブコマンド nerdctl ipfs registry として提供されます。 このコマンドは、現在の $IPFS_PATH の IPFS リポジトリによってバックアップされるレジストリを起動します デフォルトでは、nerdctl は localhost:5050 (フラグで構成可能) でレジストリを公開します。

「nerdctlipfsレジストリ」のsystemdユニットファイルを作成しています オプションで、`nerdctl ipfs registry serve`のsystemdユニットファイルを作成できます。 `nerdctl ipfs registry serve` の systemd ユニット ファイルの例は次のとおりです。 `nerdctl ipfs registry serve` is aware of environemnt variables for configuring the behaviour (e.g. listening port) so you can use `EnvironmentFile` for configuring it.
[Unit]
Description=nerdctl ipfs registry serve

[Service]
EnvironmentFile-=/run/nerdctl-ipfs-registry-serve/env
ExecStart=nerdctl ipfs registry serve

[Install]
WantedBy=default.target

次の例では、localhost:5050 ではなく localhost:5555 でレジストリを起動します。

nerdctl ipfs registry serve --listen-registry=localhost:5555

注意: 使用する $IPFS_PATH を変更する場合は、レジストリを再起動する必要もあります。

注意: nerdctl ipfsレジストリ[up|down]はv1.2.0から削除されました。代わりに nerdctl ipfs registry serve を使用して localhost レジストリを起動する必要があります。

IPFSで作成

nerdctl compose supports same image name syntax to pull images from IPFS.

バージョン: "3.8"
サービス:
  ubuntu:
    image: ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze
    command: echo hello

IPFS上のベースイメージを使用してイメージをビルドする場合、前述のようにDockerfileでlocalhost:5050/ipfs/<CID>イメージ参照を使用できます。

nerdctl compose up --build
nerdctl compose build

注意: --ipfs フラグは v1.2.0 以降削除されました。nerdctl ipfs registry serve を使用して localhost レジストリを自分で起動する必要があります。

暗号化

OCIcryptを使用して、暗号化されたイメージをIPFSで配布できます。 イメージの暗号化および復号化方法の詳細は、/docs/ocicrypt.mdを参照してください。

通常のイメージと同様に、暗号化されたイメージは ipfs:// プレフィックスを使用してIPFSにプッシュできます。

> nerdctl image encrypt --recipient=jwe:mypubkey.pem ubuntu:20.04 ubuntu:20.04-encrypted
sha256:a5c57411f3d11bb058b584934def0710c6c5b5a4a2d7e9b78f5480ecfc450740
> nerdctl push ipfs://ubuntu:20.04-encrypted
INFO[0000] pushing image "ubuntu:20.04-encrypted" to IPFS
INFO[0000] ensuring image contents
bafkreifajsysbvhtgd7fdgrfesszexdq6v5zbj5y2jnjfwxdjyqws2s3s4

ipfs:// 接頭辞を使用してIPFSから暗号化されたイメージを取得し、/docs/ocicrypt.mdで説明されているのと同じ方法で復号化できます。

> nerdctl pull --unpack=false ipfs://bafkreifajsysbvhtgd7fdgrfesszexdq6v5zbj5y2jnjfwxdjyqws2s3s4
bafkreifajsysbvhtgd7fdgrfesszexdq6v5zbj5y2jnjfwxdjyqws2s3s4:                      resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:73334fee83139d1d8dbf488b28ad100767c38428b2a62504c758905c475c1d6c:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:8855ae825902045ea2b27940634673ba410b61885f91b9f038f6b3303f48727c: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:e74a9a7749e808e4ad1e90d5a81ce3146ce270de0fbdf22429cd465df8f10a13:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 0.3 s                                                                    total:  22.0 M (73.2 MiB/s)
> nerdctl image decrypt --key=mykey.pem ipfs://bafkreifajsysbvhtgd7fdgrfesszexdq6v5zbj5y2jnjfwxdjyqws2s3s4 ubuntu:20.04-decrypted
sha256:b0ccaddb7e7e4e702420de126468eab263eb0f3c25abf0b957ce8adcd1e82105
> nerdctl run --rm -it ubuntu:20.04-decrypted echo hello
hello

eStargzベースの遅延プルを使用したIPFSでのコンテナの実行

nerdctlは、Stargz Snapshotterを使用した遅延プルでIPFS上でのeStargzイメージの実行をサポートしています。

この構成では、Stargz Snapshotterは、遅延プルをサポートするFUSEを使用して、IPFSからコンテナのrootfsにeStargzイメージをマウントします。 したがって、コンテナーは、イメージ コンテンツ全体がローカルで使用可能になるのを待たずに起動できます。 コンテナーのコールド スタートが高速化されていることがわかります。

この機能を使用するには、stargz snapshotterによる遅延プル に従って Stargz Snapshotter を有効にする必要があります。 また、Stargz Snapshotter の config.toml (通常は /etc/containerd-stargz-grpc/config.toml にあります) に次の設定を追加する必要があります。``

ipfs = true

--estargzオプションを使用してeStargzに変換することで、任意のイメージをIPFSにプッシュできます。

nerdctl push --estargz ipfs://fedora:36

そのeStargzイメージを遅延プルでプルして実行できます。

nerdctl run --rm -it ipfs://bafkreibp2ncujcia663uum25ustwvmyoguxqyzjnxnlhebhsgk2zowscye echo hello