IPFSを使ったP2P型コンテナイメージ頒布

記事の翻訳

P2P Container Image Distribution on IPFS With Containerd

nerdctl, Docker-compatible CLI of containerd, added an experimental support of P2P container image distribution without registries, using IPFS.

nerdctl というcontainerdのDocker互換CLIにて、IPFSを利用した非レジストリ依存のP2P型コンテナイメージの配布を実験的にサポートしました。

You can handle images on IPFS through ipfs://CID image reference. For details about prerequisites, please see the later sections or the docs in nerdctl.

ipfs://CID でIPFS上のイメージを扱うことができます。前提条件の詳細については、後のセクションやnerdctlのdocsをご覧ください。

> ubuntu=bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze > nerdctl run -it ipfs://$ubuntu echo hello

The image distributed on IPFS is 100% compatible to OCI Image Spec so existing image distribution techniques like image encryption and lazy pulling can still be used.

IPFS上で配信されるイメージは、OCI Image Specと100%の互換性を持つため、イメージの暗号化やlazy pullといった既存のイメージ配信技術をそのまま利用することができます。

What’s nerdctl and containerd?

containerd is an open source container runtime project. It has been used by projects including Docker/moby and Kubernetes services including EKS, AKS and GKE.

containerdは、オープンソースのコンテナランタイムプロジェクトです。Dockerやmobyなどのプロジェクトや、EKS、AKS、GKEなどのKubernetesサービスで使用されています。

nerdctl is a Docker-compatible CLI of containerd, developed as a subproject of containerd. This has a similar UI/UX as Docker and also provides cutting-edge features including lazy pulling (eStargz) and image encryption (ocicrypt). This has been adopted by lima and Rancher Desktop.

nerdctlは、containerdのサブプロジェクトとして開発されたcontainerdのDocker互換CLIです。Dockerと同様のUI/UXを持ち、lazy pullingやイメージの暗号化などの最先端の機能も備えています。これはlimaやRancher Desktopで採用されています。

IPFS-based P2P image distribution with nerdctl

nerdctl v0.14 added an experimental support of P2P image distribution on IPFS. This provides a new simple way of sharing images among container users without depending on registries.

nerdctl v0.14では、IPFS上でのP2Pイメージ配布を実験的にサポートしました。これにより、レジストリに頼らずにコンテナユーザ間でイメージを共有する新しいシンプルな方法が提供されます。

IPFS is a peer-to-peer and content-addressable data sharing protocol. A node on an IPFS network can share data to other participants in a P2P manner without hosting a central server.

IPFSとは、ピアツーピアかつコンテンスアドレッサブルなデータ共有プロトコルです。IPFSネットワーク上のノードは、中央サーバーをホストすることなく、P2P方式で他の参加者にデータを共有することができます。
Image in a image block
registry-based image distribution and ipfs-based image distribution | レジストリベースのイメージ配信とIPFSベースのイメージ配信

When distributing an image on IPFS, nerdctl adds it to your local IPFS storage. Other nodes look up the image on the IPFS network by its CID (hash of the image) then fetch it from your node or peers caching the chunks.

IPFSでイメージを配布する場合、nerdctlはイメージをローカルのIPFSストレージに追加します。他のノードはIPFSネットワーク上でイメージをCIDで検索し、あなたのノードまたはチャンクをキャッシュしているピアからイメージを取得します。

The image distributed on IPFS is 100% compatible to OCI Image Spec. So existing image distribution techniques including image encryption and lazy pulling can be applied to IPFS-based distribution as described later.

IPFS上で配信されるイメージは、OCI Image Specと100%互換性があります。そのため、イメージの暗号化やlazy pullなどの既存のイメージ配信技術を、後述するIPFSベースの配信に適用することができます。

Getting started with IPFS-based P2P image distribution

You can quickly get started with IPFS-based P2P image distribution by launching ipfs daemon which connects your node to IPFS.

ノードをIPFSに接続する ipfs daemon を起動すれば、IPFSベースのP2Pイメージ配布をすぐに始めることができます。

ipfs daemon
Use --offline flag if you don’t want the node to connect to the public network. Please see the docs in nerdctl for details about prerequisites.
ノードをパブリックネットワークに接続させたくない場合は--offlineフラグを使用してください。詳細についてはnerdctlのドキュメントをご覧ください。

nerdctl supports the image name prefix ipfs:// to handle images on IPFS.You can push an arbitrary image to IPFS using this prefix.

nerdctlは、IPFS上のイメージを扱うために、イメージ名のプレフィックスに ipfs:// をサポートしています。このプレフィックスを使って、任意のイメージをIPFSにプッシュすることができます。

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

The last line prints the IPFS CID of the pushed image. You can use this CID to share this image with other nodes.

最後の行は、プッシュされたイメージのIPFS CID を表示します。このCIDを使って、他のノードとこのイメージを共有することができます。

The following command runs that image with pulling it from IPFS.

以下のコマンドでイメージをIPFSからプルし実行します。

> ubuntu=bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze > nerdctl run -it ipfs://$ubuntu echo hello hello
The above image may become unavailable on IPFS (because we don’t pin it) before you try nerdctl run so ensure to push the image to IPFS in advance.
上記のイメージはピンしていないので nerdctl run を実行する前にIPFS上で利用できなくなる可能性があります。なので、事前にIPFSにイメージをプッシュしておいてください。

You can build a new image based on images on IPFS. In Dockerfile, instead of ipfs:// prefix, nerdctl supports the image reference formatted as localhost:5050/ipfs/CID to specify an image on IPFS.

IPFS上のイメージを元に新しいイメージを構築することができます。nerdctl は Dockerfile において ipfs:// というプレフィックスの代わりに localhost:5050/ipfs/CID という形式でIPFS上のイメージを指定するイメージリファレンスをサポートしています。

ARG BASE=bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze FROM localhost:5050/ipfs/$BASE RUN echo hello > /hello
In the future version of nerdctl, ipfs:// prefix should be supported in Dockerfile.
nerdctlの将来のバージョンではDockerfileの ipfs:// プレフィックスをサポートする予定です。

IPFS-enabled image is OCI compatible so it can also be pushed to container registries. This is useful to ship the image to hosts that don’t support IPFS.

IPFS上のイメージはOCI互換なので、コンテナレジストリにプッシュすることもできます。これは、IPFS をサポートしていないホストにイメージを渡す際に便利です。

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

Image encryption and lazy pulling

Because of the OCI-compatibility of the image pushed to IPFS, you can use existing image distribution techniques. This section describes image encryption (ocicrypt) and lazy pulling (eStargz).

IPFSにプッシュされたイメージにはOCI互換性があるため、既存のイメージ配布技術を利用することができます。ここでは、イメージの暗号化(ocicrypt)とlazy pulling (eStargz)について説明します。

Note that image encryption and lazy pulling are exclusive i.e. they can’t be enabled together.
なお、イメージの暗号化とlazy pulling は排他的であり、同時に有効にすることはできません。

If you want to keep your image being secret on IPFS, you can encrypt the image using ocicrypt.

イメージをIPFS上で秘密にしておきたい場合は、ocicryptを使ってイメージを暗号化することができます。

> nerdctl image encrypt --recipient=jwe:mypubkey.pem \ ubuntu:20.04 ubuntu:20.04-encrypted > nerdctl push ipfs://ubuntu:20.04-encrypted

To maximize the efficiency of image distribution, you can enable lazy pulling based on eStargz. This allows nerdctl to startup a container without waiting for the entire image contents becoming locally available. This can improve the cold-start performance for large images.

イメージ配布の効率を最大化するために、eStargzをベースにしたlazy pullingを有効にすることができます。これにより、nerdctlはイメージコンテンツ全体がローカルで利用可能になるのを待たずにコンテナを起動することができます。これにより、大きなイメージのコールドスタートのパフォーマンスが向上します。

The following command pushes an image with formatting it as eStargz.

次のコマンドは、eStargzフォーマットのイメージをプッシュします。

nerdctl push --estargz ipfs://ubuntu:20.04

nerdctl starts the container immediately after fetching necessary chunks of the image (e.g. entrypoint binary) without waiting for the entire contents.

nerdctlは、イメージの必要なチャンク(エントリポイントのバイナリなど)をフェッチした後、コンテンツ全体を待たずにコンテナを直ちに起動します。

nerdctl run --snapshotter=stargz -it ipfs://$ubuntu_esgz echo hello

Please visit our repo for more information about nerdctl and IPFS-based image distribution.

nerdctlやIPFSベースのイメージ配布の詳細については、私たちのレポジトリをご覧ください。

追記

より詳しい内容は下記に載ってる

技術的に新しいことは特にしてないけど試みとしてとても面白そう。

Ubuntuレベルのイメージならいいけど、個人的なイメージとかになるとやっぱり引っ張ってくる時間がかかりそう。プライベートでクラスタリングとかすれば話はまた別だろうけど、そこまでするならレジストリベースでいいのではないかと。と考えるとやはりIPFSの根本的な弱点は解消されないし、Ubuntuレベルの「大衆に同一のイメージが利用される」ようなシーンでしか活用方法が見出せない。

ただcontainerdの元来もつ暗号化技術などに直接繋げられるのはとてもよさそう。つまりはシステム的に大きな改変を必要とせず、レジストリを変更するくらいのノリでP2Pネットワーク上のイメージ頒布が可能であると考えるとすごい。

ただ業務などで使えるかというと微妙。