Join our Discord Server
Ajeet Raina Ajeet Singh Raina is a former Docker Captain, Community Leader and Arm Ambassador. He is a founder of Collabnix blogging site and has authored more than 570+ blogs on Docker, Kubernetes and Cloud-Native Technology. He runs a community Slack of 8900+ members and discord server close to 2200+ members. You can follow him on Twitter(@ajeetsraina).

Wasm and Kubernetes – Working Together

4 min read

WebAssembly is a binary format that allows running code written in multiple languages (C/C++, Rust, Go, etc.) on the web. This format offers a fast, efficient, and safe way to execute code in the browser, and it is becoming increasingly popular for web development.


Kubernetes, on the other hand, is a popular open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. Kubernetes is widely used for deploying and managing web applications in production environments.

Where Wasm fits into Kubernetes Architecture?


Let’s break it down step by step:

  1. Kubernetes API Server: The Kubernetes API server is the central component that exposes the Kubernetes API and serves as the primary interface for managing the Kubernetes cluster. It receives requests from various clients, including administrators and other Kubernetes components.
  2. Kubelet: The kubelet is an agent that runs on each node in the Kubernetes cluster. Its primary responsibility is to manage and maintain containers on the node. The kubelet communicates with the API server to receive instructions about which containers to run and their desired state.
  3. CRI Plugin + Containerd: Container Runtime Interface (CRI) is an API that defines the interaction between the kubelet and the container runtime. The CRI plugin acts as an intermediary between the kubelet and the container runtime, enabling them to communicate effectively. In this case, the container runtime being used is Containerd, which is a high-performance container runtime that manages the lifecycle of containers.
  4. Containerd-shim-wasm-v1: The Containerd shim for Wasm (WebAssembly) is a specific component that allows running Wasm-based containers within Containerd. It serves as an interface between Containerd and the Wasm runtime, handling the communication and container lifecycle management.
  5. Pod Sandbox (Wasm Runtime): The Wasm runtime is responsible for executing Wasm-based containers. In this context, the Wasm runtime is specifically designed to execute containers using WebAssembly as the underlying technology. The Pod Sandbox is a lightweight, isolated environment created by the Wasm runtime, where the Wasm-based container runs securely and with resource constraints imposed by Kubernetes.

The Kubernetes API server receives instructions to run a containerized workload. The kubelet, running on the node, communicates with Containerd through the CRI plugin. Containerd, in turn, uses the Containerd shim for Wasm to interface with the Wasm runtime. Finally, the Wasm runtime creates a Pod Sandbox, where the Wasm-based container is executed in an isolated environment within the Kubernetes cluster.

In this blog post, we will explore how to use WebAssembly and Kubernetes together to build and deploy a sample app. We will walk you through the steps needed to set up a local environment, build a sample app using WebAssembly, and deploy it on a Kubernetes cluster.


Set up a Local Environment


Before we can start building our sample app, we need to set up a local environment for development. Here are the prerequisites:



  • Docker

  • Kubernetes CLI (kubectl)

  • Rust programming language

  • wasm-pack


You can install Docker and kubectl by following the official documentation. For Rust and wasm-pack, you can use Rustup, which is a toolchain manager for Rust. Once you have installed Rustup, run the following commands to install Rust and wasm-pack:



rustup default nightly
rustup target add wasm32-unknown-unknown
cargo install wasm-pack



Build a Sample App using WebAssembly


In this step, we will build a simple app using Rust and WebAssembly. This app will take two numbers as input and return their sum. Create a new Rust project using the following command:



cargo new wasm-app --lib



This will create a new Rust project called wasm-app with a library crate. Open the lib.rs file and add the following code:



use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}



This code defines a function called add that takes two integers as input and returns their sum. The #[wasm_bindgen] attribute allows the function to be called from JavaScript.


Next, we need to compile the Rust code to WebAssembly. Run the following command to build the app:



wasm-pack build --target web --out-dir public



This will compile the Rust code to WebAssembly and place the output files in the public directory. The –target web option tells wasm-pack to build the app for the web, and the –out-dir public option specifies the output directory.


Create a Kubernetes Deployment


Now that we have built our sample app, it’s time to deploy it on a Kubernetes cluster. For this, we need to create a Kubernetes deployment that runs the app inside a container.


Create a new file called deployment.yaml and add the following code:



apiVersion: apps/v1
kind: Deployment
metadata:
name: wasm-app
spec:
replicas: 1
selector:
matchLabels:
app: wasm-app
template:
metadata:
labels:
app: wasm-app
spec:
containers:
- name: wasm-app
image: <DOCKER_USERNAME>/wasm-app:latest
ports:
- containerPort: 80



This code defines a Kubernetes deployment called wasm-app that runs one replica of the container image. The image field specifies the name of the Docker image that will be used to run the app, and the ports field specifies the port that the container will listen on (in this case, port 80).


Replace with your Docker Hub username. If you don’t have a Docker Hub account, you can sign up for free at https://hub.docker.com/.


Next, we need to build a Docker image for the app. Run the following command to build the image:



docker build -t <DOCKER_USERNAME>/wasm-app:latest .



This will build a Docker image for the app and tag it with your Docker Hub username and the latest tag.


Deploy the App on Kubernetes


Now that we have a Kubernetes deployment and a Docker image for the app, we can deploy the app on a Kubernetes cluster.


First, make sure that you have a Kubernetes cluster up and running. If you don’t have one, you can create a local cluster using Minikube by following the official documentation.


Next, run the following command to apply the Kubernetes deployment:



kubectl apply -f deployment.yaml



This will create a new Kubernetes deployment called wasm-app and start one replica of the container image.


Finally, expose the app to the outside world by creating a Kubernetes service. Create a new file called service.yaml and add the following code:



apiVersion: v1
kind: Service
metadata:
name: wasm-app
spec:
selector:
app: wasm-app
ports:
- name: http
port: 80
targetPort: 80
type: LoadBalancer



This code defines a Kubernetes service called wasm-app that exposes the app on port 80. The type: LoadBalancer field tells Kubernetes to create a load balancer for the service so that it can be accessed from the internet.


Run the following command to apply the Kubernetes service:



kubectl apply -f service.yaml



This will create a new Kubernetes service called wasm-app and expose it on port 80.


Test the App


Now that we have deployed the app on a Kubernetes cluster, we can test it by sending HTTP requests to the Kubernetes service.


Run the following command to get the external IP address of the Kubernetes service:



kubectl get service wasm-app



This will display the external IP address of the Kubernetes service. Copy the IP address and open it in a web browser.


You should see a simple web page that allows you to enter two numbers and get their sum. This page is served by the app running inside the Kubernetes cluster.


Conclusion


In this blog post, we have explored how to use WebAssembly and Kubernetes together to build and deploy a sample app. We have walked you through the steps needed to set up a local environment, build a sample app using Rust and WebAssembly, and deploy it on a Kubernetes cluster.


WebAssembly offers a fast and efficient way to run code on the web, and Kubernetes provides a powerful platform for deploying and managing containerized applications. By combining these technologies, we can build and deploy web apps that are fast, scalable, and easy to manage.

Have Queries? Join https://launchpass.com/collabnix

Ajeet Raina Ajeet Singh Raina is a former Docker Captain, Community Leader and Arm Ambassador. He is a founder of Collabnix blogging site and has authored more than 570+ blogs on Docker, Kubernetes and Cloud-Native Technology. He runs a community Slack of 8900+ members and discord server close to 2200+ members. You can follow him on Twitter(@ajeetsraina).
Join our Discord Server
Index