This repository is a tutorial for setting up a WebAssembly demo application to be executed as a container using crun, podman, and MicroShift (OpenShift optimized for edge computing).
This tutorial focuses on using Vagrant with Fedora. At the time of this writing, MicroShift is not currently supported on the latest versions of Fedora (F37). Therefore, if you'd like to try this tutorial please note that the MicroShift portion is no longer functional.
Before proceeding with this tutorial, you'll need to install various dependencies listed below. We list out all of the steps but leave it up to the user if they want to separate their environments between a development environment and a deployment environment, or they could certainly be the same system.
Additionally, not all installation steps are required below. It really depends
on which deployment examples you're interested in e.g. wasmtime
, crun
,
podman
, cri-o
, MicroShift
or all of the above. So you may want to look at the
deployment options below in Run WASM App to determine which
dependencies you should install.
First you'll need a Fedora 36 installation on a VM or baremetal system. For easy setup, this repo contains a Vagrantfile to be used for creating a Fedora 36 virtual machine quickly and easily.
-
Install vagrant on your host e.g. Fedora:
sudo dnf install vagrant
-
Enable
libvirtd
andvirtnetworkd
services:sudo systemctl enable --now libvirtd.service sudo systemctl enable --now virtnetworkd.service
-
Create and run virtual machine from the root of this repo i.e. where the
Vagrantfile
file exists:vagrant up
Run these commands on your development machine:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
curl https://wasmtime.dev/install.sh -sSf | bash
The following steps should be executed on your Fedora 36 virtual machine installation.
-
If using
vagrant
simply run:vagrant ssh
-
You'll need to enable this Copr repo:
sudo dnf copr enable -y copr.fedorainfracloud.org/rhcontainerbot/podman-next
-
Then install
crun
andwasmtime-c-api
to get bothcrun
built withwasmtime
support and thewasmtime-c-api
package that contains thelibwastime.so
wasmtime C shared library:sudo dnf install -y crun wasmtime-c-api
-
Verify
crun
is installed that enables support forwasmtime
:crun --version | grep wasmtime
NOTE: Currently the way to do this is via Copr repositories until we have official releases of these RPMs.
You'll still need crun
in order to execute the wasm app with podman
, so be
sure to install the crun
dependency in the previous step as well. Then run
the following command from your Fedora virtual machine:
sudo dnf install -y podman
On your development system or wherever you will be buildling the OCI container
image with buildah
, run the following command:
sudo dnf install -y buildah
Run through the following steps on your Fedora virtual machine:
-
Execute the following commands to install
cri-o
and verify it is enabled and running:sudo dnf module enable -y cri-o:1.21 sudo dnf install -y cri-o cri-tools sudo systemctl enable crio --now sudo systemctl status crio
-
Enable
cri-o
to usecrun
:sudo sed -i '/^\[crio.runtime\]/a default_runtime = "crun"' /etc/crio/crio.conf sudo mkdir /etc/crio/crio.conf.d/ sudo sh -c "echo -e '# Add crun runtime here\n[crio.runtime.runtimes.crun]\nruntime_path = \"/usr/bin/crun\"\nruntime_type = \"oci\"\nruntime_root = \"/run/crun\"' > /etc/crio/crio.conf.d/01-crio-crun.conf"
-
Restart
cri-o
to make sure it picks up the new config:sudo systemctl restart crio
From your Fedora virtual machine, follow the below instructions to install MicroShift.
- Install and deploy MicroShift. For this step, normally you would be able to
follow the instructions directly from the MicroShift
website,
but the F36 MicroShift package is currently broken (see issues
#908 and
#1061. So instead, we
will replace the download URL to use the F35 package, which as of this
writing is still working.
sudo dnf copr enable -y @redhat-et/microshift # Next command replaces the MicroShift download URL to use the F35 package instead. sudo sed -i 's/$releasever/35/' /etc/yum.repos.d/_copr\:copr.fedorainfracloud.org\:group_redhat-et\:microshift.repo sudo dnf install -y microshift sudo firewall-cmd --zone=trusted --add-source=10.42.0.0/16 --permanent sudo firewall-cmd --zone=public --add-port=80/tcp --permanent sudo firewall-cmd --zone=public --add-port=443/tcp --permanent sudo firewall-cmd --zone=public --add-port=5353/udp --permanent sudo firewall-cmd --reload sudo systemctl enable microshift --now
- Install the OpenShift and/or kubectl clients
- Copy Kubeconfig
- Verify MicroShift is running (this could take a few minutes):
oc get nodes oc get pods -A
This example uses rust
to compile a WebAssembly module but you can use any
supported language of choice. The following instructions are executed from your
host development system where your rust
toolchain is installed.
This example app was originally created by executing:
cargo new hello_wasm --bin
# Or if already in the root directory:
cargo init --bin
Compile the rust
app to the wasm32-wasi
target using cargo
:
cargo build --target wasm32-wasi
Use the Containerfile
provided in this repo to build a container image for
this wasm demo app workload using the below instructions.
buildah build --annotation "run.oci.handler=wasmtime" --platform wasi/wasm -t <registry>/<repo>/wasm-demo-app .
This step is only necessary if you're deploying to a different system than where you built the image.
buildah login <registry>
buildah push <registry>/<repo>/wasm-demo-app
There are several ways to run the wasm binary depending on what you're interested in and each one is documented below:
You can run the built wasm app directly with wasmtime
. This is ideal for
quick iterative development and testing:
wasmtime ./target/wasm32-wasi/debug/wasm-demo-app.wasm
You can use crun
and a config.json
to execute your container manually.
First we need to create a directory that will house the container archive and extract the container image into it:
mkdir container-archive
cd ./container-archive/
mkdir rootfs
podman export $(podman create <registry>/<repo>/wasm-demo-app) | tar -C rootfs -xvf -
Then you'll need to generate and modify a config.json
container spec:
crun spec
sed -i 's|"sh"|"/wasm-demo-app.wasm"|' config.json
sed -i 's/"terminal": true/"terminal": false/' config.json
sed -i '/"linux": {/i \\t"annotations": {\n\t\t"run.oci.handler": "wasmtime"\n\t},' config.json
Then you can run the container with:
crun run wasm-demo-app
Additionally, you can use the container lifecycle operations:
crun create wasm-demo-app
# View the container is created and in the "created" state.
crun list
# Start the process inside the container.
crun start wasm-demo-app
# After 5 seconds view that the container has exited and is now in the stopped state.
crun list
# Now delete the container.
crun delete wasm-demo-app
You'll need to have crun
installed to execute the wasm app with podman
, so
be sure you install that first if you haven't already.
podman run --platform=wasi/wasm <registry>/<repo>/wasm-demo-app
Use the wasm-pod.yaml
Kubernetes manifest in this repository to deploy with
MicroShift. If you're using a single system for the development, building and
deployment of this example app, then execute the following:
sed 's|module.wasm.image/variant: compat|run.oci.handler: wasmtime|' wasm-pod.yaml | oc apply -f -
oc get pods
oc logs -f pod-with-wasm-workload
If you're preferring to run oc
and kubectl
commands from your development
system to the system running your MicroShift cluster, then copy over the
kubeconfig
and either open up port 6443
to talk to the Kube API Server, or
use SSH port forwarding from your development system to your deployment system.
If you used vagrant
to create your MicroShift cluster, then copy over the
kubeconfig
using the following commands:
mkdir ~/.kube
vagrant ssh-config --host f36 > ssh_config
scp -F ssh_config f36:.kube/config ~/.kube/config
If you used vagrant
to create your MicroShift cluster, then forward port
6443
using SSH port forwarding by executing the following command:
MICROSHIFT_HOST_IP_ADDR=$(awk '/HostName/ {print $2}' ssh_config)
ssh -F ssh_config -L 6443:${MICROSHIFT_HOST_IP_ADDR}:6443 f36
Run the following command and verify it matches the output shown:
→ oc cluster-info
Kubernetes control plane is running at https://127.0.0.1:6443
To further debug and diagnose cluster problems, use 'kubectl cluster-info
dump'.