runwasi関連の基礎知識

runwasiとは

ContainerdでWasmを動かすための共通platformを提供する。WASIをターゲットにcompileされたプログラムであれば、WASIに準拠したランタイム(wasmtimeなど)で実行できる。Rustで記述されている。

runcの代わりに、WebAssemblyランタイムを可能にするshim(異なる環境での互換性を保つソフトウェア層)であるrunwasiをcontainerdで動かすことが出来る。

Container毎に1つのshim processが存在するnormal modeと、すべてのshimを実行する単一のprocessで実行されるshared modeがある。

Wasm containerはコンパイルされたWasmバイトコードのみなので、Linuxコンテナよりも非常に軽量で起動が速く可搬性も高い。

Component

containerd-shim-[ wasmedge | wasmtime | wasmer ]-v1

wasmedge, wasmtime, wasmerでwasmを実行するためのcontainer shimである。このshimはPod毎に1つ実行される。

containerd-shim-[ wasmedge | wasmtime | wasmer ]d-v1

containerdをcontainerd-[wasmedge | wasmtime | wasmer]d sandbox daemonに接続するために使われるCLI。containerdがcontainer作成を要求すると、このshimバイナリが起動され、ホスト上で実行されているcontainerd-[wasmedge | wasmtime | wasmer]dサービスに接続する。このバイナリ自体がリクエストを処理することはなく、サンドボックスの作成・破壊のリクエストをcontainerd-[wasmedge | wasmtime | wasmer]d daemonに送信する。

containerd-[ wasmedge | wasmtime | wasmer ]d

Pod毎、Container毎ではなく、Node全体で1つのwasmホストを実行できるようにするsandbox manager。Containerが作成されると、このサービスはsandboxを作成するリクエストを受け取る。

Wasmedge | wasmtime | wasmer engineは、全てのsandbox間で共有化される。

Runtime

あるソフトウェアを実行するために必要な環境のこと。Javaプログラムを実行するにはJava Runtime環境(JRE)が必要、といった意味。Containerを実行するには、Container実行環境が必要である、ということ。Container runtimeが担っている役割は、以下のcontainerdの項目で記載している。

containerd

コンテナのライフサイクルを管理するコンテナランタイムで、Linuxwindowsのデーモンとして動作する。コンテナイメージの管理、実行中のコンテナの管理・監視、ストレージからのコンテナ実行、低レベルのストレージ、ネットワークアタッチメントなど、ホストシステムのコンテナライフサイクルを管理する(厳密にはruncがサポートする部分もある)。

元々containerdはDockerの一部だったが、DockerがOCIの仕様に基づいてDockerが分割された。その一部がcontainerdとしてCNCFに寄贈された。そのため、containerdはシステムの一部として動くことを想定してデザインされている。

コンテナ実行レイヤのデフォルトのランタイムはruncを利用している。containerdが高レベルランタイム、runcが低レベルランタイムである。他の高レイヤランタイムにはcri-o, rktなどがあり、低レイヤランタイムには、gVisor, Nabla containersなどがある。

ctrコマンドで操作する。

runc

runcがカーネル機能を使ってコンテナ作成を行う。cgroups, namespaces, pivot_rootなどを操って、プロセスの隔離環境を作成して、コンテナを実行する。OCI runtime specificationに準拠している。

OCI Runtime specification

以下のライフサイクルに従う。runcは準拠している。

1 隔離環境の作成

2 コンテナ実行

3 プロセスのKill

4 コンテナの削除

CRI

criはkubernetesでcontainerdを動かすためのpluginである。cri pluginはcontainerdを介してコンテナライフサイクルなどを管理する。一方で、cri pluginがCNIを介してpod networkも管理する。

WebAssembly

Webブラウザ上でネイティブコード(CPUが直接実行可能な命令セット)に近い実行速度で高速に実行できるバイナリフォーマット。従来のJavaScriptソースコード形式で提供されていたのと違って、低レベルのバイナリで提供されるので、高速に実行できる。特定のプロセッサに依存しない。

厳密には、stack virtual machineのためのバイナリ形式の命令セット。

ちなみに、WebAssembly単体ではメモリ確保ができないため、外部プログラムが確保したメモリを渡す必要がある。このメモリは線形メモリと呼ばれる。

WASI (WebAssembly System interface)

OSのAPIを抽象化するための業界標準仕様のこと。Webブラウザだけでなく、WindowsLinuxなどのOS上にWebAssembly runtimeを配置して実行できるようになった。WebAssemblyがファイルやネットワーク、メモリなどのシステムリソースへ安全にアクセスするためのAPI標準仕様。

WASIは、特定のOSに依存した設計にしないために、System call (OS操作)に依存せず、User Land(CPU・メモリーの直接計算)上での処理だけが可能になっている。その欠点を補うために、他のプログラム(runtime)と連携して動くようになっている。WebAssemblyをwasmtimeでファイル操作をしようとすると、ファイル操作のみwasmtimeが実行する、といった仕組み。

WASIは、外部プログラム(runtime)がWebAssemblyを実行する標準仕様を定義している。WebAssemblyをどう実行するか、WebAssemblyにExportする関数の仕様などである。

WASI preview1でファイル操作規格が決められ、WASI preview2でネットワークに関する規格が追加される予定。

参考にした記事

https://qiita.com/wbcchsyn/items/153327b0946358694061

https://github.com/containerd/runwasi

https://bokuweb.github.io/undefined/articles/20230224.html