Krustlet with Kindでの複数WASM実行と展望

12/19変更

調査目的

複数同時にWASM(WebAssembly)を動かした場合の挙動を調べるため実施

具体的には新たにプロセルorスレッドで実行されるのか調査

Krustletについて

  • kubeletをRustで構築し、WebAssemblyを動かせるようにしたもの
  • WebAssemblyを利用する上で無駄が多いCRIなどの部分を排除し、直接kubeletAPIからWasmランタイムを扱えるようにした

通常のk8sとKrustletのアーキテクチャ比較

画像引用:コンテナランタイムの動向を整理してみた件 https://qiita.com/mamomamo/items/ed5db2ab1555078f8a24

構成

マスターをKindで構築、workerとしてKrustletを追加

環境構築に関しては以下を参考に構築

Krustletを使ってKubernetesでWebAssemblyアプリケーションを実行する - Qiita

https://docs.krustlet.dev/howto/krustlet-on-kind/

使用バージョン

hostOS : ubuntu : 20.04

kubernetes : v1.21.12(v1.22以降は別バイナリ対応

krustlet : 1.0.0-alpha.1

wasi-sdk : 14.0

wasmtime : 0.36.0

krustletでのwasmランタイム挙動確認


動作状況を可視化するために

フィボナッチ数列を無限に計算するWasmを用意し、htopのCPU使用率から一目でで動作する個数がわかるようにした

リアルタイムに標準出力(log)を追うために

fflush(stdout)で標準出力のストリームを解放する必要がある

ない場合、kubectl logs [pod name] でprintfのログがストリームがいっぱいになったタイミングでしか表示されない

コマンドラインでwasmtimeではなくても表示される。KrustletにはWebAssemblyランタイムとしてwasmtimeが組み込まれているが、コマンドラインでwasmtimeと挙動が異なる

  • fflushなしwasm yaml

krustlet-DemoWasmApp/no-fflush.yaml at main · nao-ri/krustlet-DemoWasmApp

  • WebAssembly生成用コード fibonacci.c
/*
 * C言語のサンプルプログラム - Webkaru
 * - フィボナッチ数の計算 -
 */
#include <stdio.h>
#include <unistd.h>

int main(void)
{
  /* 変数の宣言 */
  int n;
  double f0, f1, f2;

  f0 = 0;
  f1 = 1;

  /* フィボナッチ数(n=0)の出力 */
  printf("%lf\n", f0);

  /* フィボナッチ数の計算 */
  while (1)
  {
    n++;
    // フィボナッチ数の出力(n>0)
    if (n == 1000000000)
    {
      printf("%lf\n", f1);
      fflush(stdout);//標準出力
      n = 0;
    }

    // フィボナッチ数の計算
    f2 = f1 + f0;
    // 変数の代入
    f0 = f1;
    f1 = f2;
  }

  return 0;
}

複数Wasmの動作設定


wasm二つで計算

Replicasetを利用

https://blog.a-know.me/entry/2018/08/14/185324#ReplicaSet-とは

  • doubleFibonacci.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: fibonacci
spec:
  replicas: 2
  selector:
    matchLabels:
      app: wasm

  template:
    metadata:
      labels:
        app: wasm
    spec:
      nodeSelector:
        kubernetes.io/arch: wasm32-wasi
      containers:
      - name: fibonacci-wasm
        image: ghcr.io/nao-ri/fibonacci-wasm:1.0
        imagePullPolicy: Always
      imagePullSecrets:
        - name: dockerconfigjson-github-com
      tolerations:
      - effect: NoExecute
        key: kubernetes.io/arch
        operator: Equal
        value: wasm32-wasi
      - effect: NoSchedule
        key: kubernetes.io/arch
        operator: Equal
        value: wasm32-wasi

結果

kubectl から実行を確認

oss-kube@osskube-Super-Server:~$ kubectl get node -o wide
NAME                 STATUS   ROLES                  AGE    VERSION         INTERNAL-IP   EXTERNAL-IP   OS-IMAGE       KERNEL-VERSION      CONTAINER-RUNTIME
kind-control-plane   Ready    control-plane,master   197d   v1.21.12        172.18.0.2    <none>        Ubuntu 21.10   5.15.0-53-generic   containerd://1.6.4
krustlet             Ready    <none>                 197d   1.0.0-alpha.1   172.17.0.1    <none>        <unknown>      <unknown>           mvp
oss-kube@osskube-Super-Server:~$ kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE    IP           NODE                 NOMINATED NODE   READINESS GATES
fibonacci-4578v                     1/1     Running   0          29m    <none>       krustlet             <none>           <none>
fibonacci-dnfkq                     1/1     Running   0          29m    <none>       krustlet             <none>           <none>

htopで2コアを占有する二つの実行状態を確認

CPU使用状況と使用順PID

/proc でスレッドで実行されていることを確認

oss-kube@osskube-Super-Server:~$ ls /proc/73566/task/3197
319756/ 319783/

確認できたこと

  • 実行するごとにスレッドが増加
  • 二つのwasmモジュールを起動されているため、コアを二つ占有して処理
  • 個別のスレッドごとのCPU使用率は把握可能、メモリ利用については取得不可

Krustletについて今後の展望

Krustletは2021年からgithub上の更新が止まっている。さらに開発元であるDeis Labsは、OCI対応によって低レベルコンテナライムレイヤーへの変更のみでWebAssemblyに対応するrunwasiの開発に着手している。 よって、K8s上でWebAssemblyを動かすためにkubeletを改造するアプローチ(Krustlet)の開発が再開される可能性は低い。

Krustletとrunwaiのアーキテクチャ
この理由はKrustletプロジェクトのようにkubelet以下を全部WebAssembly対応に作ることはバージョン追従などメンテナンスにかかるコストが高いと推測される。そのため、K8sでwebassemblyを動かす際は、メンテナンス範囲が少なくなる低レベルコンテナライムレイヤーの実装が主流になっていくと考えられる。

実際、runwasi以外にもcrun(c言語の低レベルコンテナランタイム実装)にWebAssemblyランタイムを埋め込み利用できるOSS(wasmedge)が存在し盛んに開発行われている。

runwasi https://nigelpoulton.com/what-is-runwasi/

実行ソース

demowasmとyaml https://github.com/nao-ri/krustlet-DemoWasmApp