wasmCloudを使ってみる
はじめに
近年、仮想マシン、コンテナに続いて WebAssembly (WASM)、というようにアプリ実行には本来不要な要素が分離されてきています。すると果たしてコンテナ実行基盤 kubernetes に代わって WASM 実行基盤が台頭してくるのか、というのは関心を集めている話題ではないでしょうか。
今回は WASM の実行基盤を提供する OSS であり、CNCF Sandbox プロジェクトにもなっている wasmCloud を Windows 上で試しに動かしてみて、wasmCloud に対する理解を深めます。
そのうえで、他の WASM 実行基盤である Krustlet と簡単に比較してみます。
およそ次の手順に沿って行います。
- Rust のインストール
 - NATS サーバのインストール
 - wasmCloud のチュートリアル
 
事前準備
チュートリアルの実施にあたって Rust と NATS が必要なので、先にインストールします。
Rust は Rust のインストールページ に従ってインストールします。Windows では実行ファイルをダウンロードし、実行すればインストールできます。
NATS は NATS のインストールページ に従ってインストールします。Windows では ZIP ファイルを GitHub のリリースページからダウンロードし、適当なフォルダに解凍しましょう。ここでは次のように C:\nats-server に配置したものとします:
❯ dir C:\nats-server\
    Directory: C:\nats-server
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2022/04/25    20:34          11357 LICENSE
-a---          2022/04/25    20:34       12166656 nats-server.exe
-a---          2022/04/25    20:34           3622 README.md
NATS は次のように実行します:
❯ C:\nats-server\nats-server.exe --jetstream
コマンド実行後、ファイアウォールの警告が出たら、問題なければ許可します。
NATS を実行すると、次のように出力されます:
[30324] 2022/04/25 20:36:30.642927 [INF] Starting nats-server
[30324] 2022/04/25 20:36:30.692577 [INF]   Version:  2.8.1
[30324] 2022/04/25 20:36:30.692577 [INF]   Git:      [23b41bb]
[30324] 2022/04/25 20:36:30.692577 [INF]   Name:     NBRGTABAO25OI4SBQ6DYJIQBBFYKKKZNIHCKBBDERMGXAJPUPBK7I2HA
[30324] 2022/04/25 20:36:30.692577 [INF]   Node:     cD3jUs0w
[30324] 2022/04/25 20:36:30.692577 [INF]   ID:       NBRGTABAO25OI4SBQ6DYJIQBBFYKKKZNIHCKBBDERMGXAJPUPBK7I2HA
[30324] 2022/04/25 20:36:30.693622 [INF] Starting JetStream
[30324] 2022/04/25 20:36:30.694857 [INF]     _ ___ _____ ___ _____ ___ ___   _   __  __
[30324] 2022/04/25 20:36:30.695376 [INF]  _ | | __|_   _/ __|_   _| _ \ __| /_\ |  \/  |
[30324] 2022/04/25 20:36:30.695376 [INF] | || | _|  | | \__ \ | | |   / _| / _ \| |\/| |
[30324] 2022/04/25 20:36:30.695376 [INF]  \__/|___| |_| |___/ |_| |_|_\___/_/ \_\_|  |_|
[30324] 2022/04/25 20:36:30.695376 [INF]
[30324] 2022/04/25 20:36:30.695376 [INF]          https://docs.nats.io/jetstream
[30324] 2022/04/25 20:36:30.695376 [INF]
[30324] 2022/04/25 20:36:30.695376 [INF] ---------------- JETSTREAM ----------------
[30324] 2022/04/25 20:36:30.695376 [INF]   Max Memory:      23.94 GB
[30324] 2022/04/25 20:36:30.695376 [INF]   Max Storage:     1.00 TB
[30324] 2022/04/25 20:36:30.695885 [INF]   Store Directory: "C:\Users\****\AppData\Local\Temp\nats\jetstream"
[30324] 2022/04/25 20:36:30.695948 [INF] -------------------------------------------
[30324] 2022/04/25 20:36:30.698348 [INF] Listening for client connections on 0.0.0.0:4222
[30324] 2022/04/25 20:36:30.743571 [INF] Server is ready
プロンプトは戻ってこないので、別のウィンドウで作業します。
wash のインストール
wasmCloud の CLI である wash を、インストールページ に従ってインストールします。Windows では、次のコマンドを実行して Rust でビルドすることになり、なかなか時間がかかります:
❯ cargo install wash-cli
wash コマンドが実行できれば完了です。
❯ wash -V
wash 0.10.0
wasmCloud の起動
wasmCloud は wasmCloud のインストールページ に従ってインストールします。Windows では tar.gz ファイルを GitHub のリリースページ からダウンロードし、適当なフォルダに解凍しましょう。ここでは次のように C:\wasmCloud に配置したものとします:
❯ dir C:\wasmCloud\
    Directory: C:\wasmCloud
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2022/04/25    20:34                bin
d----          2022/04/25    20:34                erts-12.3.1
d----          2022/04/25    20:34                lib
d----          2022/04/25    20:34                releases
d----          2022/04/25    20:37                var
-a---          2022/04/25    20:38            643 host_config.json
次のコマンドを実行すると、別のウィンドウでコマンドプロンプトが立ち上がり、 wasmCloud が起動します:
❯ C:\wasmCloud\bin\wasmcloud_host foreground
コマンド実行後、ファイアウォールの警告が出たら、問題なければ許可します。
Web ブラウザを開いて、http://localhost:4000 にアクセスすると、 wasmCloud の UI が見られます。

これで wasmCloud が起動しました。
wasmCloud でのワークロード実行を体験
wasmCloud には アクター とプロバイダー、リンク という概念があります。
これらの概念は Getting started に従ってワークロードを実行するにあたって、登場してきます。
アクターが WASM です。
本記事執筆時点ではRustによる実装がサポートされています。
プロバイダーは HTTP サーバやデータベースなど、ビジネスロジックと切り離された役割を担います。
本記事執筆時点では WebAssembly System Interface (WASI) にネットワーク機能が不足していますが、プロバイダーの実現にはネットワーク機能が不可欠なので、プロバイダーは WASM ではありません。
WASM が OCI レジストリに登録可能であるように、プロバイダーも プロバイダーアーカイブ という形式を用意して、OCI レジストリに登録できるようになっています。
プロバイダーアーカイブは Linux や Mac 用など複数の実行ファイルを含んでいるようです。
WASI が今後拡張されたら、プロバイダーの形式も変わることになりそうです。
リンクはアクターとプロバイダーを結びつける役割を担います。
まずはアクターを作成してみます。
wasmCloud の UI から作業していきます。

Start Actor ボタンをクリックし、From Registry をクリックします。

OCI reference に wasmcloud.azurecr.io/echo:0.3.4 を入力し、Submit をクリックします。

Status が Healthy になるのを確認します。
なお、削除は一番右のボタンから Replicas を0にすることで行えそうです。
次に、プロバイダーを作成してみます。

Start Provider ボタンをクリックし、From Registry をクリックします。

OCI reference に wasmcloud.azurecr.io/httpserver:0.14.10 を入力し、Submit をクリックします。

Status が Healthy になるのを確認します。
なお、削除は一番右のボタンをクリックすることで行えそうです。
最後に、リンクを作成してみます。


Actor に先ほど作成したアクターを選択しています。
Provider に先ほど作成したプロバイダーを選択しています。
Contract ID に wasmcloud:httpserver を入力しています。
Values に address=0.0.0.0:8080 を入力しています。8080は、空いているポート番号を選択します。
これらを入力し終えたら、Submit をクリックします。

ファイアウォールの警告が出たら、問題なければ許可します。
すると、http://localhost:8080 にアクセスすると作成したリンク、プロバイダーを介し、アクターが応答するようになります。
❯ curl http://localhost:8080
{"body":[],"method":"GET","path":"/","query_string":""}
❯ curl -XPOST http://localhost:8080/echo?q=test -d 'test'
{"body":[116,101,115,116],"method":"POST","path":"/echo","query_string":"q=test"}
アクターはいわゆるエコーサーバで、リクエスト情報を返してくれます。
これで、wasmCloud でワークロードをどのような形で実行するのかが体験できました。
さらに理解を深めるため、別の方法でアクターを呼び出してみます。
アクターは wash call コマンドを使うことで、リンクとプロパイダーを介さずに呼び出すこともできます。
そのことを確かめるために、リンクとプロバイダそれぞれの右側にあるゴミ箱のボタンをクリックして、削除します。

すると、http://localhost:8000 にアクセスできなくなります。
❯ curl -XPOST http://localhost:8080/echo?q=test -d 'test'
curl: (7) Failed to connect to localhost port 8080 after 2242 ms: Connection refused
wash call のコマンドの引数に用いるため、アクターの Actions にある青いボタンをクリックして、アクターの ID MBCFOPM6JW2APJLXJD3Z5O4CN7CPYJ2B4FTKLJUR5YR5MITIU7HD3WD5 を取得します。
次のような JSON を wash call コマンドで送りますが、Windows だと引数に記載できなかったので、適当なファイル (ここでは test.json) に出力します:
{"method": "GET", "path": "/echo", "body": "", "queryString":"","header":{}}
次のように wash call コマンドを実行すると、一部文字化けしている箇所もありますが、どのような結果が返るのか予想ができます:
❯ wash call MBCFOPM6JW2APJLXJD3Z5O4CN7CPYJ2B4FTKLJUR5YR5MITIU7HD3WD5 HttpServer.HandleRequest -d test.json
Call response (raw): ��statusCode�Ȧheader��body�;{"body":[],"method":"GET","path":"/echo","query_string":""}
このあたりの処理(HTTP 接続を受け付け、HTTP リクエストの情報を test.json の内容相当に変換して、指定したアクターに渡し、アクターから受け取ったデータから HTTP レスポンスの生成をしてクライアントに返す)をしているのがリンクとプロバイダであるという想像もつきそうです。
他の WASM 実行基盤との比較
Krustlet は kubernetes のコンポーネント kubelet の Rust 実装であり、WASM を実行する機能を持っています。
WASM は OCI レジストリに登録できるため、コンテナイメージの代わりに WASM を指定すると、動かしてくれるという寸法です。
既存の kubernetes があれば同じように管理でき、kubernetes 自体の利点(IaC など)を活かせて、kubernetes のエコシステムを利用できるという利点があるでしょう。
ただし、先述した通り、本記事執筆時点では WebAssembly System Interface (WASI) にネットワーク機能が不足しているため、実現できることは限られています。
wasmCloud は足りない部分をプロバイダーで補う形で、現時点でも十分な機能を実現できるようになっています。
まとめ
今回は wasmCloud を実行し、wasmCloud が提供している簡単なワークロードを動かしてみました。
wasmCloud の重要な概念について、少し触れることができたと思います。
さらに理解を深めるには アクターの作成 や プロバイダーの作成 についてのチュートリアルを実施するのがよさそうです。
WASM 実行基盤についてはネットワーク機能に関する WASI など、まだまだ今後の動向が気になるところです。
Discussion