CL LAB

HOME > CL LAB > k0s 1.27の新機能: コンテナランタイムプラグインでWASMを簡単に動かそう #k0s #kubernetes #k8s #webassembly #wasm #wasi

k0s 1.27の新機能: コンテナランタイムプラグインでWASMを簡単に動かそう #k0s #kubernetes #k8s #webassembly #wasm #wasi

 ★ 13

k0sとは、軽量かつ使いやすい、100%オープンソースのKubernetesディストリビューションです。主な特徴としては、

  • フル機能のKubernetesを構築するために必要なすべてを単一バイナリに同梱
  •  k0s特有の改変を加えていない、CNCF認定の純正なKubernetesをデプロイ
  • 最低必要リソース1vCPU・1GBメモリ・2GBストレージのシングルノードから、HA構成の大規模クラスタまでサポート
  • Konnectivityをデフォルトで有効化

などが挙げられます。より詳しい情報はホワイトペーパーや「5分でわかるk0s」動画シリーズをご覧ください。

2023年4月26日にリリースされたk0s 1.27には、k0s managed dynamic runtime configuration という新機能が追加されています。これは /etc/k0s/containerd.d/ ディレクトリに contained の設定スニペットを投入すると、動的にそれを読み込んで反映させるという機能です。これにより、 containerd の設定ファイル全体を適切に書き換えたりする必要がなくなりました。

本稿では k0s managed dynamic runtime configuration を利用して、過去記事「KubernetesでWASMを動かそう」よりも簡単にKubernetes (k0s)でWASMを動かしてみます。

仮想マシン環境の準備

まず仮想マシン環境をVagrant + VirtualBoxで準備しましょう。コントロールプレーン用VMを1つ、ワーカーノード用VMを2つです。

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "rockylinux/9"
  config.vm.box_check_update = false
  
  config.vm.define "main" do |cf|
    cf.vm.hostname = "main"
    cf.vm.network "private_network", ip: "192.168.56.101"
    cf.vm.provider "virtualbox" do |vb|
      vb.memory = 4096
    end
  end

  ( 1..2 ).each do |i|
    config.vm.define "node0#{i}" do |cf|
      cf.vm.hostname = "node0#{i}"
      cf.vm.network "private_network", ip: "192.168.56.20#{i}"
      cf.vm.provider "virtualbox" do |vb|
        vb.memory = 4096
      end
    end
  end
end

k0sによるKubernetesのインストール

コントロールプレーン側

公式ドキュメントをもとにk0s v1.27.1をコントロールプレーン用VMにインストールします。

[vagrant@main ~]$ curl -sSLf https://get.k0s.sh | sudo sh
Downloading k0s from URL: https://github.com/k0sproject/k0s/releases/download/v1.27.1+k0s.0/k0s-v1.27.1+k0s.0-amd64
k0s is now executable in /usr/local/bin
[vagrant@main ~]$ k0s version
v1.27.1+k0s.0
[vagrant@main ~]$ 

k0s設定ファイルを作成します。ここではIPアドレスの変更のみを行っており、他はデフォルト設定です。

[vagrant@main ~]$ k0s config create > k0s.yaml.orig
[vagrant@main ~]$ cp -a k0s.yaml.orig k0s.yaml
[vagrant@main ~]$ vi k0s.yaml
[vagrant@main ~]$ diff -u k0s.yaml.orig k0s.yaml
--- k0s.yaml.orig	2023-04-27 08:16:32.898589360 +0000
+++ k0s.yaml	2023-04-27 08:17:41.367440655 +0000
@@ -5,11 +5,10 @@
   name: k0s
 spec:
   api:
-    address: 10.0.2.15
+    address: 192.168.56.101
     k0sApiPort: 9443
     port: 6443
     sans:
-    - 10.0.2.15
     - 192.168.56.101
     - fe80::a00:27ff:fefc:e996
     - fe80::a00:27ff:fee4:c9e9
@@ -72,7 +71,7 @@
   storage:
     etcd:
       externalCluster: null
-      peerAddress: 10.0.2.15
+      peerAddress: 192.168.56.101
     type: etcd
   telemetry:
     enabled: true
[vagrant@main ~]$ 

この設定ファイルをもとに、コントロールプレーン用VMにKubernetesをインストールします。

[vagrant@main ~]$ sudo mkdir /etc/k0s
[vagrant@main ~]$ sudo mv k0s.yaml /etc/k0s/
[vagrant@main ~]$ sudo /usr/local/bin/k0s install controller -c /etc/k0s/k0s.yaml 
[vagrant@main ~]$ sudo /usr/local/bin/k0s start
[vagrant@main ~]$ sudo /usr/local/bin/k0s status
Version: v1.27.1+k0s.0
Process ID: 4094
Role: controller
Workloads: false
SingleNode: false
[vagrant@main ~]$ 

ワーカーノード参加用トークンを払い出します。

[vagrant@main ~]$ sudo /usr/local/bin/k0s token create --role=worker /etc/k0s/k0s.yaml > join-token
[vagrant@main ~]$ 

この join-token ファイルをワーカーノード用VMにコピーします。

ワーカーノード側

コントロールプレーン用VMからコピーした join-token ファイルをもとにクラスタに参加させます。node01 と node02 で --node-ip オプションに与えるIPアドレスが異なることに注意しましょう。それぞれのVMのIPアドレスになります。

[vagrant@node01 ~]$ curl -sSLf https://get.k0s.sh | sudo sh
Downloading k0s from URL: https://github.com/k0sproject/k0s/releases/download/v1.27.1+k0s.0/k0s-v1.27.1+k0s.0-amd64
k0s is now executable in /usr/local/bin
[vagrant@node01 ~]$ sudo mkdir /etc/k0s
[vagrant@node01 ~]$ sudo mv join-token /etc/k0s/
[vagrant@node01 ~]$ sudo /usr/local/bin/k0s install worker --token-file /etc/k0s/join-token --kubelet-extra-args '--node-ip=192.168.56.201'
[vagrant@node01 ~]$ sudo /usr/local/bin/k0s start
[vagrant@node01 ~]$ sudo /usr/local/bin/k0s status
Version: v1.27.1+k0s.0
Process ID: 3992
Role: worker
Workloads: true
SingleNode: false
Kube-api probing successful: true
Kube-api probing last error:  
[vagrant@node01 ~]$ 
[vagrant@node02 ~]$ curl -sSLf https://get.k0s.sh | sudo sh
Downloading k0s from URL: https://github.com/k0sproject/k0s/releases/download/v1.27.1+k0s.0/k0s-v1.27.1+k0s.0-amd64
k0s is now executable in /usr/local/bin
[vagrant@node02 ~]$ sudo mkdir /etc/k0s
[vagrant@node02 ~]$ sudo mv join-token /etc/k0s/
[vagrant@node02 ~]$ sudo /usr/local/bin/k0s install worker --token-file /etc/k0s/join-token --kubelet-extra-args '--node-ip=192.168.56.202'
[vagrant@node02 ~]$ sudo /usr/local/bin/k0s start
[vagrant@node02 ~]$ sudo /usr/local/bin/k0s status
Version: v1.27.1+k0s.0
Process ID: 3993
Role: worker
Workloads: true
SingleNode: false
Kube-api probing successful: true
Kube-api probing last error:  
[vagrant@node02 ~]$ 

クラスタの確認

コントロールプレーン用VMでクラスタの状態を確認します。

[vagrant@main ~]$ sudo /usr/local/bin/k0s kubectl get nodes
NAME     STATUS   ROLES    AGE     VERSION
node01   Ready    <none>   4m14s   v1.27.1+k0s
node02   Ready    <none>   110s    v1.27.1+k0s
[vagrant@main ~]$ 

これでk0sによるKubernetesクラスタが準備できました。

wasm-enablerのデプロイ

過去記事「KubernetesでWASMを動かそう」では手動で WasmEdgerunwasi のインストール、containerd の設定変更を行って、WASMを動かせるようにしていました。

ここでは wasm-enabler をデプロイするだけでWASMを動かせるようにしてみます。wasm-enabler は、次の作業を自動化する DaemonSet として動作します。

これにより、Kubernetes上で Spinフレームワーク によってビルドされたWASMを動作させられるようになります(※過去記事「KubernetesでWASMを動かそう」とは shim や WASM ランタイムが異なることに注意してください)。

では、wasm-enabler をクラスタにデプロイしてみましょう。にある次のマニフェストをapplyすればOKです。

[vagrant@main ~]$ vi wasm-enabler.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: wasm-enabler
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k0s-app: wasm-enabler
  template:
    metadata:
      labels:
        k0s-app: wasm-enabler
    spec:
      initContainers:
        - name: wasm-enabler
          image: quay.io/k0sproject/k0s-wasm-plugin:main
          securityContext:
            privileged: true
          volumeMounts:
            - name: bin
              mountPath: /var/lib/k0s/bin
            - name: imports
              mountPath: /etc/k0s/containerd.d/
      containers:
        # We need one dummy container as DaemonSet do not allow to
        # run pods with restartPolicy other than Always ¯\_(ツ)_/¯
        - name: dummy
          image: registry.k8s.io/pause:3.6
      volumes:
        - name: bin
          hostPath:
            path: /var/lib/k0s/bin
            type: Directory
        - name: imports
          hostPath:
            path: /etc/k0s/containerd.d/
            type: Directory
---
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: wasmtime-spin
handler: spin
[vagrant@main ~]$
[vagrant@main ~]$ sudo /usr/local/bin/k0s kubectl apply -f wasm-enabler.yaml 
daemonset.apps/wasm-enabler created
runtimeclass.node.k8s.io/wasmtime-spin created
[vagrant@main ~]$ sudo /usr/local/bin/k0s kubectl -n kube-system get daemonset wasm-enabler
NAME           DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
wasm-enabler   2         2         2       2            2           <none>          71s
[vagrant@main ~]$ sudo /usr/local/bin/k0s kubectl -n kube-system get pods --selector='k0s-app=wasm-enabler'
NAME                 READY   STATUS    RESTARTS   AGE
wasm-enabler-72z4n   1/1     Running   0          2m47s
wasm-enabler-g75n7   1/1     Running   0          2m47s
[vagrant@main ~]$ 

これで完了です。

wasm-enablerのインストール確認

念のため、ワーカーノードに shim バイナリや containerd 設定スニペットがインストールされたか確認してみましょう。

[vagrant@node01 ~]$ sudo ls -l /var/lib/k0s/bin/containerd*
-r-xr-x---. 1 root root 41219960 May  8 06:25 /var/lib/k0s/bin/containerd
-r-xr-x---. 1 root root  6557696 May  8 06:25 /var/lib/k0s/bin/containerd-shim
-r-xr-x---. 1 root root  8265728 May  8 06:25 /var/lib/k0s/bin/containerd-shim-runc-v1
-r-xr-x---. 1 root root 12009472 May  8 06:25 /var/lib/k0s/bin/containerd-shim-runc-v2
-rwxr-xr-x. 1 root root 48626496 May  8 06:30 /var/lib/k0s/bin/containerd-shim-slight-v1
-rwxr-xr-x. 1 root root 38593352 May  8 06:30 /var/lib/k0s/bin/containerd-shim-spin-v1
[vagrant@node01 ~]$ 

目的の containerd-shim-spin-v1 がインストールされています。

[vagrant@node01 ~]$ cat /etc/k0s/containerd.d/wasm_spin_runtime.toml ; echo
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin]
    runtime_type = "io.containerd.spin.v1"
[vagrant@node01 ~]$ 

目的の containerd 設定スニペットもインストールされています。

サンプルアプリのデプロイ

では Spinフレームワークで作成されたWASMサンプルアプリをデプロイしてみましょう(※過去記事「KubernetesでWASMを動かそう」で利用したサンプルアプリ michaelirwin244/wasm-example はSpinフレームワーク製ではないので動作しません。Cannot read manifest file from "/run/k0s/containerd/io.containerd.runtime.v2.task/k8s.io/XXXXXXXX/rootfs/spin.toml": unknown のようなエラーになります)

[vagrant@main ~]$ vi wasm-spin.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wasm-spin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wasm-spin
  template:
    metadata:
      labels:
        app: wasm-spin
    spec:
      runtimeClassName: wasmtime-spin
      containers:
        - name: spin-hello
          image: ghcr.io/deislabs/containerd-wasm-shims/examples/spin-rust-hello:v0.5.1
          command: ["/"]
          resources: # limit the resources to 128Mi of memory and 100m of CPU
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 100m
              memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
  name: wasm-spin
spec:
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: wasm-spin
[vagrant@main ~]$

デプロイします。

[vagrant@main ~]$ sudo /usr/local/bin/k0s kubectl apply -f wasm-spin.yaml 
deployment.apps/wasm-spin created
service/wasm-spin created
[vagrant@main ~]$ sudo /usr/local/bin/k0s kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
wasm-spin-5d958db977-fsfvf   1/1     Running   0          33s
[vagrant@main ~]$ sudo /usr/local/bin/k0s kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        44m
wasm-spin    NodePort    10.107.65.52   <none>        80:31976/TCP   14s
[vagrant@main ~]$ 

NodePortにアクセスしてみましょう。

[vagrant@main ~]$ curl 192.168.56.202:31976/hello ; echo
Hello world from Spin!
[vagrant@main ~]$ 

応答が返ってきました!

まとめ

本稿では Vagrant + Virtualbox でテスト環境を準備し、k0s で Kubernetes クラスタを作成し、k0s 1.27 の新機能である k0s managed dynamic runtime configuration を利用してWASIアプリケーションをデプロイできるように設定しました。この機能を利用すれば、Spinフレームワーク以外のWASM動作環境も比較的簡単に構築できるようになると思います。クリエーションラインでは引き続き WebAssmbly と Kubernetes について調査していきたいと思います。

CL LAB Mail Magazine

CL LABの情報を逃さずチェックしよう!

メールアドレスを登録すると記事が投稿されるとメールで通知します。

メールアドレス: 登録

※登録後メールに記載しているリンクをクリックして認証してください。

Related post

Neo4j[ホワイトペーパー]CCPA