SpinKube WASM in Kubernetes

SpinKube is a new open-source project that is tailored to deploying WASM (WebAssembly) workloads on Kubernetes. SpinKube enhances the ability of scalability of WASM applications this tool allows integration with kubernetes primitives and use of conversion of application using the spin-plugin to make it effective conversion of YAML to interpret by the cluster and serve serverless applications. I’ve previously viewed a session on this topic and felt like it was worth covering further as the expansion of using WASM in production expand how can we integrate this to get the best of Kubernetes and WASM working together.

Spinkube.dev (image credit)

Under the hood

The Spin Operator which sits in the cluster is built as a operator that allows the automation of new objects without modifying the Kubernetes API this allows for the workload life cycle management.

Spinkube.dev (image credit)

The capabilities of spin kube scaffold can generate Spin applications to transform to YAML manifests or you can also compose manually. The operator acts on the deployment and send this to the runtime class manager.

Runtime-class-manager

Known as the containerd shim lifecycle operator, the Runtime-class-manager automates and streamlines the lifecycle management of containerd shims. This tool is crucial for the backend operations, including the installation, updating, removal, and configuration of shims. Each function is designed to ensure that your containerd environment remains robust and responsive to the needs of your applications.

A key feature of the Runtime-class-manager is its ability to manage node labels and runtime classes effectively. In production environments, where precision and reliability are paramount, it is essential to assign specific labels to nodes designated for running WebAssembly (WASM) applications. This targeted labeling allows for optimal deployment and operation of applications across various nodes, enhancing performance and scalability.

Containerd-shim-spin

Containerd-shim-spin serves as a pivotal bridge enabling WebAssembly (WASM) workloads to be efficiently managed within Kubernetes environments. This tool utilizes ‘runwasi’, a library specifically designed to harness the capabilities of WASM, thereby integrating these workloads seamlessly with the robust container management features offered by containerd. This integration allows for enhanced scalability, security, and manageability of WASM applications in complex, distributed systems like Kubernetes.

Getting Started

To leverage this tool a few pre-requisites should be implemented for this post I’m going to keep this minimal to understand the concepts but pay close attention to the syntax.

Requirements

  • Kubernetes Cluster
  • Kubectl Installed (Kubernetes Client CLI)
  • Helm Installed (Package Manager for K8s)
  • Bombardier (Cross-platform HTTP Benchmarking CLI)

While this can be achieved in other Kubernetes distributions as however I couldn’t find any documentation related to deploying the containerd-shim-spin on other distributions.

For the following depending on what cluster your running if you prefer to follow along with k3d run this syntax for the containerd-shim-spin pre-requisitie.

k3d cluster create wasm-cluster-scale \
  --image ghcr.io/spinkube/containerd-shim-spin/k3d:v0.13.1 \
  -p "8081:80@loadbalancer" \
  --agents 2

We’ll need to also deploy the Spin Operator and its dependencies

# Install cert-manager CRDs
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.3/cert-manager.crds.yaml

# Add and update Jetstack repository
helm repo add jetstack https://charts.jetstack.io
helm repo update

# Install the cert-manager Helm chart
helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.14.3

After this finishes we will need to install the following Runtime Class and Spin Operator CRDs.

# Install the RuntimeClass
kubectl apply -f https://github.com/spinkube/spin-operator/releases/download/v0.1.0/spin-operator.runtime-class.yaml

# Install the CRDs
kubectl apply -f https://github.com/spinkube/spin-operator/releases/download/v0.1.0/spin-operator.crds.yaml

Last of the installation is the Spin Operator using helm.

# Install the RuntimeClass
kubectl apply -f https://github.com/spinkube/spin-operator/releases/download/v0.1.0/spin-operator.runtime-class.yaml

# Install the CRDs
kubectl apply -f https://github.com/spinkube/spin-operator/releases/download/v0.1.0/spin-operator.crds.yaml

Setting up the Ingress

Following along with the Scaling with HPA uses a ingress resource for our spin app to be reached use the following.

# Setup ingress following this tutorial https://k3d.io/v5.4.6/usage/exposing_services/
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  annotations:
    ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: hpa-spinapp
            port:
              number: 80
EOF

The ingress will show as follows as you can see we’ve declared the name nginx and the ports the are accessible from this portion.

I’m deploying the app listed below here is the link to the repo. Repo

Now we can notice the following based on our YAML Manifest we are targeting the limits of 500m in the CPU space along with memory requirements. The second half of the manifest declares the maximum replica count to a maximum of 10 and a minimum count of 1.

apiVersion: core.spinoperator.dev/v1alpha1
kind: SpinApp
metadata:
  name: hpa-spinapp
spec:
  image: ghcr.io/spinkube/spin-operator/cpu-load-gen:20240311-163328-g1121986
  enableAutoscaling: true
  resources:
    limits:
      cpu: 500m
      memory: 500Mi
    requests:
      cpu: 100m
      memory: 400Mi
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: spinapp-autoscaler
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hpa-spinapp
  minReplicas: 1
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50

So I’ll run this as the following I’ll do a touch main.yaml and insert this code to apply to our cluster.

I’ve ran the kubectl get spinapps we can see the application we’ve just applied shows up.

If I run a kubectl get hpa

I’ve had to install bombardier but if you haven’t you can with the following command.

wget https://github.com/codesenberg/bombardier/releases/download/v1.2.6/bombardier-linux-386
chmod +x bombardier-linux-386
sudo mv bombardier-linux-386 /usr/local/bin/bombardier

We can now leverage this tool to run against our local host and trigger the Horizontal Pod Autoscaler.

bombardier -c 40 -t 5s -d 3m http://localhost:8081

In the above command we are pushing out 40 connections in a timeout session of 5 seconds and a duration 3 minutes to be in total of the test.

I believe this gave me this visual since I’ve skipped a step but to show the output of what this command will look like on your screen.

kubectl describe deploy hpa-spinapp

As we’ve sent the request we can see our Horizontal Pod Autoscaler is adjusting based on the requests.

If we then move to our resource ReplicaSets we can see that this has gone up even further.

Based on our requests from bomardier we’ve scaled up based on the traffic using the HPA.

Summary

WebAssembly is experiencing a boom in the CNCF space particularly as the use of this in kubernetes. Its important to remember WASM is a modern binary instruction format optimized for the web this is relatively light weight. This is also platform independent and able to maintain security in efficiency given the sandboxed execution that separates from the host runtime which has limited access to the underlying system resources. While this isn’t exhaustingly all the features of WebAssembly this shows how you can run a application on kubernetes leveraging Spinkube which is relatively easy to use.

For developers and organizations looking to leverage WASM in kubernetes clusters, understanding the elements of tools such as SpinKube will significantly ease the transition to familiarity. While still in the early stages I can see this project expanding and simplifying WASM deployment leveraging Kubernetes primitives as a integration further with hyperscalers as well.