Kwasm review: run WebAssembly apps in Kubernetes clusters
This article written by our DevOps engineer Dmitry Silkin is a continuation of our series on reviewing WebAssembly applications tools in Kubernetes clusters. In our previous piece, we deployed a Wasm application to a cluster managed by Deckhouse Kubernetes Platform using the platform’s built-in tools. This time, we will use an off-the-shelf operator called Kwasm.

What is Kwasm?
Kwasm is a Kubernetes operator that supports running WebAssembly applications on Kubernetes cluster nodes. Kwasm-node-installer — a component of the operator — installs the containerd binaries and makes the necessary configuration changes. It is run on nodes labeled with kwasm.sh/kwasm-node=true
.
The module then downloads the required containerd-shim binaries to the cluster nodes and makes changes to the containerd configuration (refer to this article to learn more about WebAssembly). After that, you can run Wasm applications on those nodes.
Kwasm supports a plethora of cloud platforms as well as local installations ranging from kind to AWS, GCP, and Azure clouds:

Installing Kwasm
Let’s install the operator in a Kubernetes cluster. First, we have to create a cluster. Let’s use the kind tool. Our cluster will consist of three nodes:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
Create a cluster:
kind create cluster --config=./kind.yaml
Ascertain that the cluster has been created:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 59s v1.24.0
kind-worker Ready <none> 40s v1.24.0
kind-worker2 Ready <none> 40s v1.24.0
Once the cluster is ready, proceed to install the Kwasm operator:
helm repo add kwasm http://kwasm.sh/kwasm-operator/
helm install -n kwasm --create-namespace kwasm-operator kwasm/kwasm-operator
kubectl annotate node --all kwasm.sh/kwasm-node=true
Make sure that the operator has been installed:
kubectl get pods -n kwasm -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kind-control-plane-provision-kwasm-cfbvg 0/1 Completed 0 55s 10.244.0.5 kind-control-plane <none> <none>
kind-worker-provision-kwasm-n5c95 0/1 Completed 0 55s 10.244.1.3 kind-worker <none> <none>
kind-worker2-provision-kwasm-zqj5z 0/1 Completed 0 55s 10.244.2.2 kind-worker2 <none> <none>
kwasm-operator-7f7d456678-hxsgx 1/1 Running 0 72s 10.244.1.2 kind-worker <none> <none>
Running a sample Wasm application
Once the operator has made changes to the containerd configuration on the nodes, create a separate runtime class to run the WebAssembly containers.
kubectl apply -f -<<EOF
---
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: wasmedge
handler: wasmedge
EOF
Now you are all set to run the Wasm application. Let’s run the wasi-demo pod with the wasmedge/example-wasi:latest
image as an example.
kubectl apply -f -<<EOF
---
apiVersion: v1
kind: Pod
metadata:
labels:
run: wasi-demo
name: wasi-demo
spec:
containers:
- args:
- /wasi_example_main.wasm
- "50000000"
image: wasmedge/example-wasi:latest
name: wasi-demo
restartPolicy: Never
runtimeClassName: wasmedge
EOF
Once the pod has been Completed, take a look at its logs:
kubectl logs wasi-demo
Random number: 63685983
Random bytes: [247, 43, 129, 227, 3, 56, 148, 40, 154, 241, 96, 85, 109, 140, 104, 71, 188, 245, 165, 107, 146, 202, 215, 21, 50, 33, 54, 193, 175, 35, 142, 108, 150, 30, 229, 50, 105, 139, 110, 170, 187, 234, 41, 249, 213, 65, 146, 27, 88, 115, 30, 147, 95, 155, 203, 183, 143, 0, 139, 108, 12, 141, 255, 191, 11, 254, 40, 189, 186, 19, 196, 136, 51, 114, 103, 119, 130, 105, 99, 177, 192, 158, 122, 120, 160, 9, 241, 73, 209, 235, 22, 158, 35, 6, 223, 217, 3, 215, 114, 4, 52, 11, 49, 191, 33, 253, 80, 254, 255, 176, 137, 38, 53, 190, 18, 194, 53, 143, 251, 1, 147, 254, 206, 130, 195, 77, 93, 151]
Printed from wasi: This is from a main function
This is from a main function
The env vars are as follows.
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_SERVICE_HOST: 10.96.0.1
HOSTNAME: wasi-demo
KUBERNETES_PORT: tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT: 443
KUBERNETES_SERVICE_PORT_HTTPS: 443
KUBERNETES_PORT_443_TCP_ADDR: 10.96.0.1
KUBERNETES_PORT_443_TCP_PROTO: tcp
KUBERNETES_PORT_443_TCP_PORT: 443
KUBERNETES_PORT_443_TCP: tcp://10.96.0.1:443
The args are as follows.
/wasi_example_main.wasm
50000000
File content is This is in a file
Cool, the WebAssembly application works!
Conclusion
As we’ve seen, Kwasm significantly streamlines the deployment of Wasm applications into a Kubernetes cluster. However, it is worth noting that while the operator claims support for a large number of Kubernetes distributions, the developers themselves warn that the tool should only be used for evaluation purposes.
As of now, SpinKube is well worth a good look, which is powered by Kwasm technologies. It’s exhibiting a more rapid pace of development. We’ll definitely cover it in one of our upcoming articles on WebAssembly technologies.