Cloud Native C15
Run WASM applications from Kubernetes
- Interested in running WASM workloads from Kubernetes?
- Interested in enabling your Kubernetes cluster to support multiple container shims?
- Even better, interested in WASM with Dapr support?
The steps documented here help run WASM workloads from a Kubernetes cluster, based on great work from:
Sample applications and deployment manifests are located in this repo.
The prerequisites are below:
- A Kubernetes cluster whose nodes can be accessed directly to install shims and configure containerd. For managed Kubernetes clusters, a potential workaround is to use a DaemonSet to install the shim and configure containerd. Some Kubernetes distributions, such as AKS, already provide a preview feature to enable WASM support.
WasmEdge Containerd Crun Shims
The WasmEdge containerd shim is based on the crun project. To bake the WasmEdge runtime into crun, we need to add WasmEdge to the Kubernetes cluster and build crun with WasmEdge support manually.
Install WasmEdge
Install WasmEdge on a Kubernetes node.
curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | sudo bash -s -- -p /usr/local
Build crun with WasmEdge support
Install building tools and libraries
sudo apt update
sudo apt install -y make git gcc build-essential pkgconf libtool \
libsystemd-dev libprotobuf-c-dev libcap-dev libseccomp-dev libyajl-dev \
go-md2man libtool autoconf python3 automake
Next, configure, build, and install a crun binary with WasmEdge support.
git clone https://github.com/containers/crun
cd crun
./autogen.sh
./configure --with-wasmedge
make
sudo make install
Map the runtime type to the shim binary.
vi /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun]
runtime_type = "io.containerd.runc.v2"
privileged_without_host_devices = false
pod_annotations = ["*.wasm.*", "wasm.*", "module.wasm.image/*", "*.module.wasm.image", "module.wasm.image/variant.*"]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun.options]
BinaryName = "crun"
systemctl restart containerd
systemctl status containerd
Add a RuntimeClass to support the WasmEdge crun containerd shim from the Kubernetes cluster.
# wasmedge-crun-v2.yaml
apiVersion: node.k8s.io/v1
handler: crun
kind: RuntimeClass
metadata:
name: wasmedge-crun
scheduling:
nodeSelector:
kubernetes.azure.com/wasmedge-crun: "true"
Add labels to Kubernetes nodes to mark them as supporting WasmEdge workloads.
kubectl apply -f wasmedge-crun.yaml
kubectl label nodes <NODE> kubernetes.azure.com/wasmedge-crun=true
Deploy sample WASM application
kubectl apply -f https://raw.githubusercontent.com/huangyingting/wasm/main/deploy/rust-wasmedge.yaml
To test the WASM application, open two terminal windows. In the first terminal window, run:
kubectl port-forward svc/rust-wasmedge 8080:80
In the second terminal window, run the following command and notice that the request is echoed back:
curl http://localhost:8080
# HTTP response by WASM echo application
:method: GET
Host: localhost:8080
User-Agent: curl/7.81.0
Accept: */*
Deis Labs Containerd Wasm Shims
Deis Labs provides two great containerd shims:
- Spin shim - supports the Spin framework
- Slight (SpiderLightning) shim - supports Deis Labs SpiderLightning
Install Deis Labs Containerd Wasm Shims
Using a shim in Kubernetes has brief steps to install Deis Labs containerd WASM shims.
Here are more detailed steps.
Install containerd shims on a Kubernetes node.
RELEASE=v0.9.1
wget -qO- https://github.com/deislabs/containerd-wasm-shims/releases/download/$RELEASE/containerd-wasm-shims-v1-slight-linux-x86_64.tar.gz | sudo tar -xvz -C /usr/local/bin
wget -qO- https://github.com/deislabs/containerd-wasm-shims/releases/download/$RELEASE/containerd-wasm-shims-v1-spin-linux-x86_64.tar.gz | sudo tar -xvz -C /usr/local/bin
Add the following to the containerd /etc/containerd/config.toml (The default configuration can be generated by running containerd config default) that maps the runtime type to the shim binary,
vi /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin]
runtime_type = "io.containerd.spin.v1"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.slight]
runtime_type = "io.containerd.slight.v1"
systemctl restart containerd
systemctl status containerd
Add RuntimeClass resources to support Spin and Slight from the Kubernetes cluster.
# runtimeclass.yaml
apiVersion: node.k8s.io/v1
handler: slight
kind: RuntimeClass
metadata:
name: wasmtime-slight
scheduling:
nodeSelector:
kubernetes.azure.com/wasmtime-slight: "true"
---
apiVersion: node.k8s.io/v1
handler: spin
kind: RuntimeClass
metadata:
name: wasmtime-spin
scheduling:
nodeSelector:
kubernetes.azure.com/wasmtime-spin: "true"
Label Kubernetes nodes to support Spin and Slight workloads.
kubectl apply -f runtimeclass.yaml
kubectl label nodes <NODE> kubernetes.azure.com/wasmtime-slight=true
kubectl label nodes <NODE> kubernetes.azure.com/wasmtime-spin=true
Deploy sample WASM application
kubectl apply -f https://raw.githubusercontent.com/huangyingting/wasm/main/deploy/go-spin.yaml
To test the WASM application, open two terminal windows. In the first terminal window, run:
kubectl port-forward svc/go-spin 8080:80
In the second terminal window, run the following command and notice that the request is echoed back:
curl http://localhost:8080
# HTTP response by WASM echo application
GET / HTTP/1.1
Host: localhost:8080
Accept: */*
Spin-Base-Path: /
Spin-Component-Route:
Spin-Full-Url: http://localhost:8080/
Spin-Matched-Route: /...
Spin-Path-Info: /
Spin-Raw-Component-Route: /...
User-Agent: curl/7.81.0
arch: wasm
os: linux
version: v0.1.0
Sample applications
This repo also provides a few sample applications for running WASM applications from a Kubernetes cluster.
- dotnet-spin, a simple WASM http echo server written on c# language
- go-spin, a simple WASM http echo server written on golang language
- rust-wasmedge, a simple WASM http echo server written on rust language
Build and deploy
This repo has GitHub Actions workflows to build and push images to ghcr.io. Check .github/workflows/build-spin-images.yaml and .github/workflows/build-wasmedge-images.yaml to see how those WASM container images are built.
deploy directory has all the Kubernetes manifests to deploy sample applications.
To run applications locally, you need:
- Rust
- .NET 7.0 SDK
- Go
- TinyGo
- spin
- WasmEdge
To run spin application, change directory togo-spinordotnet-spin, runspin buildandspin up
To run WasmEdge application, change directory torust-wasmedge, run
rustup target add wasm32-wasi
cargo build --release --target wasm32-wasi
wasmedge target/wasm32-wasi/release/rust-wasmedge.wasm
rust-wasmedge also supports Dapr. To add a Dapr sidecar, add the following annotations to deploy/rust-wasmedge.yaml:
...
annotations:
module.wasm.image/variant: compat-smart
# Dapr support
dapr.io/enabled: "true"
dapr.io/app-id: "rust-wasmedge"
dapr.io/app-port: "80"