WASM + WASI + WAGI + Web Assembly Modules in Rust — Part 3

B Shyam Sundar
5 min readSep 4, 2022

--

Run your web assembly module in Kubernetes

Rust and web assembly

Introduction

This is Part — 3 in a three part series. If you haven’t, please read Part -1 and Part — 2 before reading this part.

We had built a very simple Web Assembly module in Part-1 and found a way to distribute it using wasm-to-oci in Part-2. We will look at how we can deploy the web assembly to Kubernetes using Krustlet.

Prerequisites

  1. Rust (1.60+)
  2. Docker
  3. CNCF Distribution
  4. wasm-to-oci
  5. Minikube
  6. Krustlet

Docker

You need to have docker installed and running in your local machine, minikube is booted on top of docker.

Minikube

Minikube is great for quickly setting up a local kubernetes environment quickly. In minikube we will bootstrap krustlet as a node that can run WebAssembly module.

Krustlet

From its website:

Krustlet is a Kubelet written in Rust — which listens on the event stream for new pods that the scheduler assigns to it, based on specific Kubernetes tolerations.

Krustlet lets us run web assembly workloads natively on kubernetes. After. configuration a pod scheduled with certain tolerations will be scheduled to run in the Krustlet node. Krustlet fully implements the kubelet API and will respond to all kubelet API requests.

Setting up

In order for WASM work loads to work on Kubernetes, we need to have a node that is primed for running WASM workloads. The default container runtime of Kubernetes is containerd.

Since we are using a local insecure registry, we need to need to add it to docker configuration file.

Open the docker daemon file:

#!/bin/bash~/.docker/daemon.json
Docker Daemon Edit

Replace “192.168.68.109” with your machine’s local IP.

Then install minikube on you machine and then we need to bootstrap Krustlet as node to minikube.

After installing minikube and start minikube using

#!/bin/bashminikube start --insecure-registry="192.168.68.109:5000"

Replace “192.168.68.109” with your local machine’s IP.

If all goes well, check the minikube status with

#!/bin/bashminikube status

You should see something similar to

Now that we have minikube ready. Next is to install and bootstrap krustlet. Make sure that you have kubectl command configured to be used with minikube. You can alias kubectl with minikube using the following command:

#!/bin/bashalias kubectl="minikube kubectl --"

It is a four step process. They are

1. Install krustlet:

For the sake of the our demo, please download the canary build as I faced few issues with the current version. Configure the krustlet-wasi executable to a place where $PATH is setup.

2. Generate bootstrap file for krustlet

To generate and map the krustlet bootstrap command and generate a certificate run the following command.

#!/bin/bash<(curl https://raw.githubusercontent.com/krustlet/krustlet/main/scripts/bootstrap.sh)

3. Run krustlet

To run krustlet, you need to be aware of the minikube’s default gateway address. To get the ip of minikube’s default gateway run

#!/bin/bashminikube ip

You should see something similar to

Once you have that run the following command to run krustlet. Change “192.168.49.2” to whatever ip your “minikube ip” command displayed.

#!/bin/bashKUBECONFIG=~/.krustlet/config/kubeconfig \
krustlet-wasi \
--node-ip 192.168.49.2 \
--node-name=krustlet \
--bootstrap-file=${HOME}/.krustlet/config/bootstrap.conf

If all went well then you should see

Run krustlet

4. Approving the serving csr

As we can see, the CSR certificate will not be approved automatically. We will have to do that manually by ourselves. Just run the command mentioned in the line “BOOTSTRAP”

#!/bin/bashkubectl certificate approve Shyams-MacBook-Air.local-tls

Once you run this command in a seperate window you should see

Krustlet running

Now that krustlet is running. Check if krustlet is available as a node to accept web assembly workloads using the following command.

#!/bin/bashkubectl get nodes -o wide
krustlet node

Now that we have krustlet successfully running, next step to run our workload

Run our workload

To run our workload, we will utilise the image which we pushed to the local registry in Part-2.

We need to add the image to the cache of minikube in order for it successfully schedule a pod.

#!/bin/bashminikube cache add 192.168.68.109:5000/wagi-level1-oci:latest

Now create a yaml file for scheduling a pod

./pod.yamlapiVersion: v1
kind: Pod
metadata:
name: krustlet-tutorial
spec:
containers:
- name: krustlet-tutorial
image: 192.168.68.109:5000/wagi-level1-oci:latest
tolerations:
- effect: NoExecute
key: kubernetes.io/arch
operator: Equal
value: wasm32-wasi
- effect: NoSchedule
key: kubernetes.io/arch
operator: Equal
value: wasm32-wasi

The tolerations are needed so that the pod is scheduled only on the Krustlet node.

Now schedule this file using the following file:

#!/bin/bashkubectl apply -f deploy.yml

If all went well you should see:

Success

Let us look into a little more details by running:

#!/bin/bashkubectl describe pods krustlet-tutorial
Success Run

Notice that the pod execution completed successfully. Wow, this has much more implication than what can be pictured here.

This article concludes the 3 part series for WASM-WASI.

References

Introduction to WAGI | Slides + Coverage (fettblog.eu)

https://youtu.be/9NDwHBjLlhQ — Very useful video and the main influence for this article

deislabs/wagi: Write HTTP handlers in WebAssembly with a minimal amount of work (github.com)

Wasm, WASI, Wagi: What are they? | Fermyon Technologies (@FermyonTech)

thangchung/webassembly-tour: ⚙️ Take you through a tour of WebAssembly (WASM targets on WASI) with wasmCloud, Krustlet, WAGI, etc. 🌟 Give it a star if you like it. (github.com)

Containerless! How to Run WebAssembly Workloads on Kubernetes with Rust | Okta Developer

Running Krustlet on Minikube | Krustlet

linux — Failed to pull image “<myimage>/posts:0.0.1”: rpc error: code = Unknown desc = Error response from dae… How to fix this problem with docker image? — Stack Overflow

--

--