WebAssembly is powering the next wave of cloud computing, and thanks to runwasi, WebAssembly is coming to Kubernetes!
This article demystifies runwasi and explains how it’s bringing WebAssembly to Kubernetes.
A big shoutout to Ralph Squillace for helping me get the technical stuff right. He’s a great example of how helpful the Wasm community is. Any mistakes in the article are mine.
Kubernetes isn't just containers
Kubernetes orchestrates containers. Only… Kubernetes doesn’t care about containers and doesn’t even know how to start and stop them. It relies on a technology called a container runtime to do all the container work.
This raises the question — If Kubernetes doesn’t care about containers and needs a container runtime to deploy containers to Kubernetes… can we use a Wasm runtime to deploy WebAssembly to Kubernetes?
The answer is “Heck yes!”.
The most popular container runtime on modern Kubernetes clusters is containerd (pronounced “container dee”). Despite being low-level plumbing technology, containerd is a big deal when it comes to Kubernetes!
containerd is what we sometimes call a high-level runtime. This means it sits in a comfy office calling the shots while a low-level runtime does the actual work.
As a quick example, containerd defaults to using runc as its low-level runtime. In this setup, containerd pulls the images but runc creates and starts the containers.
The architecture is shown below. Notice how a single containerd instance is calling the shots for multiple containers, whereas each container has its own runc and shim process.
containerd has a first-class shim API making it easy to swap-out runc for a different runtime. More on this in a minute.
Kubernetes and containerd
The following workflow oultines the roles of containerd and runc when starting a container on Kubernetes.
- The kubelet on the node watches the API server for new tasks
- The kubelet is assigned a task
- The task is to run a container
- containerd pulls the required container image
- containerd instructs runc to create the container
- runc creates the required namespaces and cgroups etc.
- runc starts the container’s main process in the required namespace
- runc exits
- The shim becomes the container’s parent process
The importance of shims
Shims do a lot of things, such as keeping containers alive and reporting exit codes to containerd.
Shims also abstract the machinery of low-level runtimes. This, coupled with the v2 containerd shim API, should allow us to swap-out low-level container runtimes for Wasm runtimes.
Bringing Wasm to Kubernetes with runwasi
runwasi is part of the official CNCF containerd project and is all about integrating Wasm runtimes with containerd.
Architecturally, runwasi operates as a containerd shim — sitting in between containerd and a Wasm runtime. The high-level architecture looks like this, and everything below containerd in the diagram is opaque to Kubernetes.
This containerd shim approach provides an easy path for getting Wasm workloads into Kubernetes by leveraging containerd’s massive install base.
“Easy” is a relative term as there is still a lot of work to be done with runwasi. However…
Azure AKS is previewing Wasm node pools that use runwasi. These support application frameworks based on the wasmtime runtime such as Fermyon’s Spin and Deislabs’s Slight.
Docker Desktop also uses runwasi to support Wasm workloads.
Both are significant in the development and adoption of runwasi
Peaking under the hood
Running Wasm workloads inside of containers might seem counter-intuitive — why take something smaller, faster, and more portable than a container and run it inside something that looks a lot like a container (namespaces and cgroups)?!
At least one answer is platforms and tooling — you get some of the goodness of Wasm without having to build new platforms and learn new tooling. This is a big deal if you’ve invested heavily into things such as Kubernetes and OCI registries.
Anyway, containers are a collection of namespaces with cgroups and other security technologies layered on. Wasm is a stack-based VM that implements a secure-by-default sanbox that isolates apps from the kernel and only possesses the capabilities needed by the app.
Sooooo… running Wasm apps inside of container-like constructs gets you the security benefits of the Wasm sandbox and namespaces and cgroups.
runwasi pros and cons
The runwasi approach has pros and cons.
The pros include an easy path to Kubernetes that works with existing K8s primitives such as Pods, Deployments, RuntimeClasses, etc. It allows Wasm to ride the Kubernetes wave, as well as enabling Kubernetes to boldly go where it couldn’t go with containers – resource constrained edge environments…
The cons include the fact that existing platforms and tools weren’t designed for Wasm and may limit the benefits you get. Also, the developer experience for Wasm and components is a long way behind containers.
Other WebAssembly/Wasm articles
If you liked this article, check out some of my other WebAssembly articles.
- WebAssembly: The future of cloud computing
- What is cloud native WebAssembly
- Getting started with Docker and Wasm
You can also subscribe to my Word on the cloud newsletter. It’s short and keeps you up-to-date with the best stuff going on around cloud native.