Project Description

This project aims to build a unikernel that has a sole purpose: run WebAssembly applications.

Unikernels offer a limited attack surface and theoretically can provide better performance compared to running the same application on top of a regular operating system. However, running applications on top of unikernels is not an easy tasks. Some might just work out of the box, others will require quite some efforts to be ported.

WebAssembly is a binary application format. A developer write their application using their favorite programming language, then compile it using the WebAssembly target. This produces a Wasm module, that can be run on top of a WebAssembly runtime. The runtime abstracts the underlying operating system and architecture, making the Wasm module capable of running everywhere. The WebAssembly runtime is also in charge of exposing a series of capabilities that can be leveraged by the WebAssembly guest. These capabilities could be system-related (like interacting with the filesystem, this is what WASI does) or could be functionalities provided by a specific platform (like accessing Key/Value stores, implementing http endpoints,... this is what platforms like Spin or Spiderlightning offer).

Why should we have a unikernel that runs WebAssembly:

  • To improve security. Each WebAssembly runtime executes the WebAssembly code inside of a dedicated sandbox. This isolates the Wasm workloads from each other and from the host. However this is all done in software. By using a unikernel, we will be running the application on a host (the unikernel) that as a limited attack surface, plus it will be placed inside of a traditional VM that offers better isolation capabilities.
  • To go fast. We could just place a regular WebAssembly runtime inside of a VM and call it a day (like running that inside of kata for example). However, having a super limited use case, I think we can build a really optimized system (à la firecraker)

Why I think this has higher chances of adoption compared to traditional "wanna run everything" unikernels:

  • WebAssembly modules have clear boundaries. The set of capabilities offered is set by the platform (Spin, Spiderlightning) is limited. That reduces the amount of scenarios the unikernel must support.
  • A better developer experience. A developer will build an application targeting a certain platform (Spin, Spiderlightning). This will produce a Wasm module that can be run, unchanged, by a regular WebAssembly runtime, including this unikernel. Both the regular WebAssembly runtime and the unikernel will implement the same set of capabilities. The WebAssembly guest won't even notice where its being ran.

Why am I doing this

I've always been fascinated by unikernels and I'm deeply into WebAssembly. I think there's a purpose for the two things to play together, as described above.

State of the project

I've a running POC. The unikernel is based on rusty-hermit, a unikernel written in Rust.

I've a unikernel application that is capable of running the unmodified WebAssembly module produced by the Spiderlightning key-value demo.

The unikernel is running inside of qemu, using kvm.

Goal for this Hackweek

Main goal - run WebAssembly

The main goal is be able to run the http server demo from Spiderlightning. I don't care about being able to run WASI modules, right now I just want to target some of the interfaces offered by Spiderlightning.

I don't need external help to achieve this goal.

Virtualization goals - HELP NEEDED

As an additional goal, I would like to replace the usage of qemu with something that is custom built.

We need a stripped down hypervisor that:

  • Offers a network stack based on virtio - this is what hermit supports
  • [Optional] offers a virtio disk backed by virtiofs - that's the only type of disk supported by hermit unikernel

We could leverage the Rust VMM libraries (the ones used by firecraker and crosvm) to build it, use cloud-hypervisor or other things you have in mind. It would be great to have all of that written in Rust, because it would allow me to reuse other Wasm/OCI-related things I'm already using inside of other projects I maintain/contribute to.

First step

Have a cli program that works in this way:

<our binary> run <unikernel image>

This would setup the network stack and run the unikernel image provided by the cli.

In this case we don't care about the unikernel being run. It could be the "hello world" example from hermit or it could be the wasm unikernel I'm building. In the latter case, the unikernel image would also bundle inside of itself the actual WebAssembly module.

Second step

Have a cli program that works in this way:

<our binary> run <module.wasm>

The binary will now bundle the wasm unikernel application, hence it's no longer required to specify that on the cli. Instead, on the cli the user will point us to the WebAssembly module to run. The module will somehow be injected into the VM and consumed by the unikernel. How to do that, I have some ideas, but you're the virtualization expert, I rely on you to help me with that add-emoji .

This makes the unikernel image generic, because there's no need to bundle the actual WebAssembly module to execute inside of it.

[comment]: # (Please link to sources and other data here.) [comment]: # (Prefer public repositories, such as GitHub!)

Resources

I've still to upload the POC on GitHub. In the meantime these are the Virtualization related links:

[comment]: # (After creating the project, please add some keywords:) [comment]: # (* What type of project mates are you looking for, which skills do you need or lack?) [comment]: # (* Which keywords will help other people to find your project?)

Looking for hackers with the skills:

virtualization rust

This project is part of:

Hack Week 22

Activity

  • over 1 year ago: paulgonin liked this project.
  • over 1 year ago: ademicev0 liked this project.
  • over 1 year ago: moio liked this project.
  • over 1 year ago: rcase liked this project.
  • over 1 year ago: mberti liked this project.
  • over 1 year ago: flavio_castelli started this project.
  • over 1 year ago: flavio_castelli added keyword "virtualization" to this project.
  • over 1 year ago: flavio_castelli added keyword "rust" to this project.
  • over 1 year ago: flavio_castelli originated this project.

  • Comments

    • flavio_castelli
      over 1 year ago by flavio_castelli | Reply

      Project update

      I started writing a series of blog post about this project. You can find the first one here.

      I got a POC working, I managed to achieve the "main" goal, but I didn't have time/help to accomplish the secondary virtualization goals.

      You can find the working prototype here

    Similar Projects

    mikrolite - a cli to create lighweight Kubernetes clusters using microvms by rcase

    [comment]: # (Please use the project descriptio...


    Plan 9 filesystem support in GRUB by ptesarik

    [comment]: # (Please use the project descriptio...


    Kanidm - Account Policy by firstyear

    Project Description

    Kanidm is a identity ...


    Create a new markup language with parser in rust by nkrapp

    Project Description

    Write a parser for my...


    (Rust) Manage systems in NetBox using NetBox-Sync by chock

    [comment]: # (Please use the project descriptio...


    Relm4-based user interface for Agama by IGonzalezSosa

    Motivation

    Disclaimer: the idea of this pr...


    Waysettings by dspinella

    [comment]: # (Please use the project descriptio...