はじめに
先日開催されたKernel/VM探検隊online part2ではWASMが大きなトピックの1つでした。
僕はWASMに関して一切話しませんでしたが、以前からKubernetesにおけるWASMの活用の話や、CDNなどのエッジクラウド環境におけるWASMの活用については情報を集めていました。
TechFeed Summit#3 - コンテナ技術を語り尽くす!では、エッジにおけるKubernetes利用のこれからについてもLTでお話させていただき、その中で一つの利用例としてKrustletとWASMの話も言及しています。
下記スライドではKrustletのアーキテクチャをKubeletと比較していますが、見ての通り、これまで「コンテナ」が動いたPodを置き換える形として「WASM」が動いていることがわかります。
WASMはコンテナか?
端的にみれば、この図はコンテナ→WASMという対比構造になるわけですが、果たして技術的に見てこれは正しいのでしょうか。答えは否、WASMはコンテナ技術とは異質のものです。
感覚的にはこれは知っていたのですが、僕自身WASMに関して知見がほぼないことから、@nullpo_headさんともお話したり、KrustletのリポジトリにIssueを立てて質問してみたりしたところ、以下のような議論が得られました。
厳密に言えばネームスペース使ったosレベルの隔離技術ではないからコンテナではないかもしれないっすね oci的な意味でのコンテナだとは思うので(コンテナと同じレイヤの同じ機能なので)深く考えずにコンテナって紹介しました https://t.co/i0Ks3lE3ME
— ぬるぽへ (@nullpo_head) March 22, 2021
@nullpo_head https://t.co/2CIeqzT24J 答えもらったんですが、「Wasm Instance」と呼ぶのがWasm way的には正しいらしいです
— inductor (@_inductor_) March 23, 2021
該当Issueでは以下のような議論をしました。
- WASMはインスタンス?プロセス?
- Kubeletではワークロードの単位としてLinuxプロセスでもあるコンテナを動かしている
- Krustletではアプリケーションが動くときどういう説明ができる?これはコンテナ?それともインスタンス?そもそもホストプロセス?
KrustletではWebAssemblyモジュールをスケジュールする。下回りで動くWasmプロバイダにもよるが、ランタイムではWasmtimeというWASI仕様のリファレンス実装を用いてWebAseemblyモジュールのインスタンスを作成する。WASIプロバイダにおいては、各モジュールはRustのTokioタスク(一般に「Green thread」として扱われている)として生成され、WASMサンドボックスを実行する。このサンドボックスは実行されるモジュールに独自の線形メモリスペースがあり、ファイル、デバイス、またはネットワーク(実際には現在のWASIの制限)にアクセスできないことを保証する分離レイヤーである。
これはコンテナと似通った部分もあるように見えるが、実際には全く異なるものである。Linux(Windows)コンテナはOSレベルによる分離であるのに対し、WebAssemblyはWasmバイトコードを実行するための仮想マシンを提供しており、Javaバイトコードを実行するJVMや.NET ILを実行する.NET CLRに近いものである。 Runtime Structure — WebAssembly 1.1にもある通り、実行される実態のことは「インスタンス」と呼ぶことにしている。
というわけで、Wasmの場合はインスタンスと呼ぶそうです。