Writing your first app, part 1
Let’s learn by example.
Throughout this tutorial, we’ll walk you through the creation of a basic WASI application. Once ready, we will package that application and install it onto the Kubernetes cluster using krustlet.
The tutorial will consist of three parts:
- Building the application
- Publishing the application to a registry
- Running the application with Krustlet
Prerequisites
We’ll assume you have Cargo (a package management system for Rust) installed already.
If you’re compiling the application written in C, you’ll want to install the WASI SDK, though if you’re following the tutorial with the Rust example, this step is optional.
In part 2 of this tutorial, we will be publishing our application to a registry
hosted on Microsoft Azure. The steps assume you have an Azure account and the
az
CLI installed. However, there are other cloud providers available with
their own solutions, and if you’re feeling particularly brave, you can run your
own registry on your own
infrastructure. You’ll also need
wasm-to-oci (a tool for publishing
WebAssembly modules to a registry).
We’ll assume you have Krustlet installed already. See the quickstart guide for advice on how to boot a Kubernetes cluster and install Krustlet.
If you’re having trouble going through this tutorial, please post an issue to krustlet/krustlet to chat with other Krustlet users who might be able to help.
Creating your first application
For this tutorial, we’ll be creating an example application written either in C or in Rust.
The application a very simple “hello world” application, running forever and printing “hello world!” every 5 seconds to standard output.
Option 1: From C
First, let’s write the application in C. To create your app, type this command:
$ mkdir demo
$ cd demo
$ touch main.c
The C code here uses standard POSIX APIs, and doesn’t have any knowledge of WASI internals.
#include <stdio.h>
#include <unistd.h>
int main() {
while(1) {
printf("Hello, World!\n");
sleep(5);
}
return 0;
}
The wasi-sdk provides a clang which is configured to target WASI. We can compile our program like so:
$ clang main.c -o demo.wasm
This is just regular clang, configured to use a WebAssembly target and sysroot. The output of clang here is a standard WebAssembly module:
$ file demo.wasm
demo.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)
Option 2: From Rust
The same application can be written in Rust. First, go ahead and start a new project:
$ cargo new --bin demo
Now, let’s port the C program defined earlier to Rust. In src/main.rs
:
use std::time::Duration;
use std::thread::sleep;
fn main() {
loop {
println!("Hello, World!");
sleep(Duration::from_secs(5));
}
}
In order to build it, we first need to install a WASI-enabled Rust toolchain:
$ rustup target add wasm32-wasi
$ cargo build --release --target wasm32-wasi
We should now have the WebAssembly module created in target/wasm32-wasi/release
:
$ file target/wasm32-wasi/release/demo.wasm
demo.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)
Optional: executing with wasmtime
The WebAssembly module demo.wasm
we just compiled either from C or Rust is
simply a single file containing a self-contained WASM module.
wasmtime
is a standalone JIT-style runtime for WebAssembly and WASI. It runs
WebAssembly code outside of the web, and can be used both as a command-line
utility or as a library embedded in a larger application.
We can execute our application with wasmtime
directly, like so:
$ wasmtime demo.wasm
Hello, World!
Hello, World!
Hello, World!
^C
To exit the program, enter CTRL+C with your keyboard.
Great! Our program runs as expected!
When you’re comfortable with the application, read part 2 of this tutorial to learn about publishing our application to a registry, where Krustlet will be able to find it and run it.