IPFSでのコンテナイメージの配布(実験的)
| nerdctl >= 0.14 | |
|---|---|
IPFSを使用して、レジストリなしでコンテナイメージを配布できます。
IPFSのサポートは完全にオプションです。IPFSデーモンのインストールと実行をオプトインしない限り、ホストはどのP2Pネットワークにも接続されていません。
前提 条件
ipfs デーモン
Kubo(旧go-ipfs)などのIPFSデーモンがホストで実行されていることを確認してください。 たとえば、次のコマンドを使用して Kubo を実行できます。
ルートレスモードでは、containerd-rootless-setuptool.sh を使用して ipfs デーモンをインストールする必要があります。
注意:上記のコマンドの出力で説明されているように、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に依存しない)ランタイムで実行できます。
 IPFS対応イメージはOCI互換ですが、containerdやpodmanなどの一部のランタイムにはバグがあり、その場合にイメージのプルに失敗することに注意してください。containerdはv1.5.8以降でこれを修正し、podmanはコミット
b55fb86c28b7d743cf59701332cd78d4294c7c54以降これを修正しました。
nerdctl build と localhost:5050/ipfs/<CID> イメージリファレンス
IPFSのベースイメージを使用してイメージを構築できます。 BuildKit >= v0.9.3 が必要です。
Dockerfile では、プレフィックスの代わりに、次のイメージ参照を使用して、IPFS 上のイメージ ipfs:// ポイントする必要があります。
ここで、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 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.次の例では、localhost:5050 ではなく 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>イメージ参照を使用できます。
注意: -
-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 にあります) に次の設定を追加する必要があります。``
--estargzオプションを使用してeStargzに変換することで、任意のイメージをIPFSにプッシュできます。
そのeStargzイメージを遅延プルでプルして実行できます。
- IPFSでの遅延プルの詳細については、stargz-snapshotterプロジェクトのドキュメントを参照してください。
- Stargz Snapshotter の nerdctl の設定の詳細については、/Startgz Snapshotterによる遅延プルを参照してください。