Web Assembly are complementary to Linux container

WebAssembly is a binary or textual pre-compiled format (binary = .wasm, textual = .wat) for portable compilation-target executable basing on varies source programming languages such as ECMA-script, RUST, C(++). A runtime maps the .wasm binary code to the target machine code.

WASM has important benefits – base on the wasmer https://github.com/wasmerio/wasmer capabilities

  • Secure by default. No file, network, or environment access, unless explicitly enabled.
  • Supports WASI (WebAssembly system interface) and Emscripten (compiler toolchain based on LLVM) out of the box.
  • Fast. Run WebAssembly at near-native speeds, with > factor 100 faster bootup time as a Docker container
  • Embeddable in multiple programming languages
  • Compliant with latest WebAssembly Proposals (SIMD, Reference Types, Threads, …)

The WASM pre-compilation uses two different approaches

  1. ahead-of-time (AOT), which translates the given WASM-bytecode into the target machine code before execution.
  2. juts-in-time (JIT), which dynamically interprets the given WASM-bytecode while execution.

Let us start with a small C-program hello.c which we compile to WASM-bytecode.

#include <stdio.h>

int main() {
    printf("Hello World\n");
    return 0;
}

For the compilation we use the tool emscripten (EMCC) https://github.com/emscripten-core/emscripten

emcc -g -Oz --llvm-lto 1 -s STANDALONE_WASM -s INITIAL_MEMORY=32MB -s MAXIMUM_MEMORY=4GB   -mmutable-globals   -mnontrapping-fptoint   -msign-ext   hello.c -o hello.wasm

The resulting WASM (file hello.wasm) can be executed by e.g. the runtime wasmedge https://wasmedge.org/

Notes: There are many discussion about performance ongoing. We use wasmedge (also called SSVM). Check the performance review: https://www.secondstate.io/articles/ssvm-performance/ . My perception better fit to: https://00f.net/2021/02/22/webassembly-runtimes-benchmarks/ outcomes.

wasmedge hello.wasm

More or the same can be achieved with a RUST program hello.rs.

use std::env;

fn main() {
  println!("Hello World\n");
}

The RUST program can be compiled to a WASM as follows.

Create the RUST package manager config file Cargo.toml

[package]
name = "hello"
version = "0.1.0"
authors = ["ubuntu"]
edition = "2022"

[[bin]]
name = "hello"
path = "hello.rs"

[dependencies]

Do the compilation:

cargo build --target wasm32-wasi

The compiled WASM-bytecode hello.wasm can be shipped and managed via Linux container runtime e.g., the low-level OCI-compliant runtime crun https://github.com/containers/crun, which has given integration with e.g., wasmedge. On Ubuntu-Linux the support must be explicitelly activated. Due to that you might has to deinstall crun and re-install it.

Note: SSVM (wasmedge) is still a young project. The wasmer project is still the fastest one https://wasmer.io/

sudo apt-get remove crun 
sudo apt-get install -y make git gcc build-essential pkgconf libtool \
   libsystemd-dev libprotobuf-c-dev libcap-dev libseccomp-dev libyajl-dev \
   libgcrypt20-dev go-md2man autoconf python3 automake
git clone https://github.com/containers/crun
cd crun
./autogen.sh
./configure --with-wasmedge
make
sudo make install

Note: crun is the default OCI runtime e.g., for Podman.

Let us start with the Dockerfile

FROM scratch
COPY hello.wasm /
CMD ["/hello.wasm"]

Now use the builduh https://github.com/containers/buildah tooling for OCI container.

sudo buildah build --annotation "module.wasm.image/variant=compat" -t mywasm-image .

The output looks something like that:

STEP 1/3: FROM scratch
STEP 2/3: COPY hello.wasm /
STEP 3/3: CMD ["/hello.wasm"]
COMMIT mywasm-image
Getting image source signatures
Copying blob 4a84eb4c3649 skipped: already exists  
Copying config ddc9d831fc done  
Writing manifest to image destination
Storing signatures
--> ddc9d831fcd
Successfully tagged localhost/mywasm-image:latest
ddc9d831fcdc554b5bd7010c6184ffbcdb87f911f6522945fb8fed2f8db42dcc

Now we can run our Linux container:

sudo podman run mywasm-image:latest

The output looks like the following:

Hello World

Done. Now we have WASM manageable via Linux container tools.

Our setup looks something like the following illustration:

Interesting developments

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *