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).
If you're not interested in trying out the MicroShift portion of this tutorial, you can optionally try a slightly older version of this tutorial using Fedora. If so please see the Fedora tutorial. Otherwise, the rest of this tutorial will focus on RHEL 8, as that's where MicroShift is currently supported.
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. wasmedge, 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 RHEL 8 installation on a VM or baremetal system. Here we focus on a VM installation using the libvirt virtualization platform.
- Download the Red Hat Enterprise Linux 8.X DVD ISO image for the x86-64
architecture from the Red Hat
Developer site and copy
the file to the
/var/lib/libvirt/imagesdirectory. The latest RHEL 8 minor version at this time is 7. NOTE: This has only been tested on the x86-64 architecture. - Download the OpenShift pull secret from the
https://console.redhat.com/openshift/downloads#tool-pull-secret
page and save it into the
~/.pull-secret.jsonfile. - Run the following command to install the necessary components for the
libvirt virtualization platform and its QEMU
KVM hypervisor driver.
sudo dnf install -y libvirt virt-manager virt-install virt-viewer libvirt-client qemu-kvm qemu-img
- Run the following commands to create and run the virtual machine with the
minimum of 2 CPU cores, 2GB RAM and 20GB storage minimum. Feel free to increase the
resources if desired.
Watch the OS console of the virtual machine to see the progress of the installation, waiting until the machine is rebooted and the login prompt appears. The OS console is also accessible from the
VMNAME=microshift-starter DVDISO=/var/lib/libvirt/images/rhel-8.7-x86_64-dvd.iso KICKSTART=https://raw.githubusercontent.com/openshift/microshift/microshift-4.12.5/docs/config/microshift-starter.ks sudo -b bash -c " \ cd /var/lib/libvirt/images && \ virt-install \ --name ${VMNAME} \ --vcpus 2 \ --memory 2048 \ --disk path=./${VMNAME}.qcow2,size=20 \ --network network=default,model=virtio \ --events on_reboot=restart \ --location ${DVDISO} \ --extra-args \"inst.ks=${KICKSTART}\" \ --wait \ "
virt-managerGUI by runningsudo virt-manager. - Once the virtual machine installation is complete and boots to the login
prompt, you can now log into the machine either using the OS console, or
using SSH (preferred) and the user credentials
redhat:redhat. To log in using SSH, get the IP address of the VM with the following command:sudo virsh domifaddr microshift-starter Name MAC address Protocol Address ------------------------------------------------------------------------------- vnet2 52:54:00:d6:ab:4b ipv4 192.168.122.111/24
- Set an environment variable with the IP address of the virtual machine.
RHEL_VM_IP_ADDR=192.168.122.111
- Copy over your SSH public key over to the virtual machine for passwordless
authentication.
ssh-copy-id redhat@${RHEL_VM_IP_ADDR} - Copy your pull secret file to the MicroShift virtual machine using
redhat:redhatcredentials:scp ~/.pull-secret.json redhat@${RHEL_VM_IP_ADDR}:
- Log into the MicroShift virtual machine:
ssh redhat@${RHEL_VM_IP_ADDR} # when prompted, password is `redhat`
- Once you're logged in, register your RHEL machine and attach your
subscriptions. The credentials to use will be your username/password used
for your Red Hat account.
sudo subscription-manager register --auto-attach
Run these commands on your development machine:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-wasiThe following steps should be executed on your RHEL 8 virtual machine installation.
- On RHEL 8 users should first disable the
container-toolsmodule in order to avoid conflicts with packages from the Copr repos:sudo dnf module disable container-tools -y
- You'll need to enable the following EPEL and Copr repos:
sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm sudo dnf copr enable -y copr.fedorainfracloud.org/rhcontainerbot/podman-next - Then install
crunto getcrunbuilt withwasmedgesupport by relying on thelibwasmedge.soshared library installed by thewasmedgepackage. Here we install thecrun-wasmRPM as it contains all the right dependencies i.e.crunandwasmedge. Note thatcrun-wasmis just a symbolic link tocrun.sudo dnf install -y crun-wasm
- Verify
crunis installed that enables support forwasmedge:crun --version | grep wasmedge
NOTE: Currently the way to do this is via EPEL and 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 RHEL virtual machine:
sudo dnf install -y podmanOn your development system or wherever you will be buildling the OCI container
image with buildah, run the following command:
sudo dnf install -y buildahFrom your RHEL virtual machine, follow the below instructions to install MicroShift and CRI-O.
-
Enable the MicroShift RPM repos and install MicroShift,
cri-o, and theocandkubectlclients:sudo subscription-manager repos \ --enable rhocp-4.12-for-rhel-8-x86_64-rpms \ --enable fast-datapath-for-rhel-8-x86_64-rpms sudo dnf install -y microshift-4.12.6 openshift-clients -
Confgure the minimum required firewall rules:
sudo firewall-cmd --permanent --zone=trusted --add-source=10.42.0.0/16 sudo firewall-cmd --permanent --zone=trusted --add-source=169.254.169.1 sudo firewall-cmd --reload
-
Configure
cri-oto use the pull secret:sudo cp ~redhat/.pull-secret.json /etc/crio/openshift-pull-secret -
Configure
cri-oto usecrun:sudo sed -i 's/# default_runtime =.*/default_runtime = "crun"/' /etc/crio/crio.conf -
Start the
microshiftservice:sudo systemctl enable --now microshift.service -
Enable MicroShift access for the
redhatuser account:mkdir ~/.kube sudo cat /var/lib/microshift/resources/kubeadmin/kubeconfig > ~/.kube/config
-
Finally, check if MicroShift is up and running by executing the below
occommands.When started for the first time, it may take a few minutes to download and initialize the container images used by MicroShift. On subsequent restarts, all the MicroShift services should take a few seconds to become available.
oc get cs 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 --binCompile the rust app to the wasm32-wasi target using cargo:
cargo build --target wasm32-wasiUse the Containerfile provided in this repo to build a container image for
this wasm demo app workload using the below instructions.
buildah build --annotation "module.wasm.image/variant=compat" --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-appThere 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 wasmedge. This is ideal for
quick iterative development and testing.
First, copy over the built Wasm module from your host development system to the RHEL virtual machine:
scp ./target/wasm32-wasi/debug/wasm-demo-app.wasm redhat@${RHEL_VM_IP_ADDR}:Then execute it with the following command:
wasmedge ~/wasm-demo-app.wasmYou 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"module.wasm.image/variant": "compat"\n\t},' config.jsonThen you can run the container with:
crun run wasm-demo-appAdditionally, 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-appYou'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-appUse 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 skip the scp command. Otherwise, execute
the following command from your development system to copy over the Kubernetes
manifest to your RHEL virtual machine:
scp ./wasm-pod.yaml redhat@${RHEL_VM_IP_ADDR}:Then from your RHEL virtual machine execute the below commands:
oc apply -f ~/wasm-pod.yaml
oc get pods
oc logs -f pod-with-wasm-workloadIf 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 virtual machine
system. Both methods are documented below.
Copy over the kubeconfig using the following commands:
mkdir ~/.kube
scp redhat@${RHEL_VM_IP_ADDR}:.kube/config ~/.kube/configFrom your RHEL virtual machine, open the firewall port for the Kubernetes API
server (6443/tcp) by running the following command:
sudo firewall-cmd --permanent --zone=public --add-port=6443/tcp && sudo firewall-cmd --reloadThen on your development system replace the server field in your kubeconfig
file with the name or IP address of your RHEL virtual machine running
MicroShift by running the following command:
sed -i "s|server: https://127.0.0.1:6443|server: https://${RHEL_VM_IP_ADDR}:6443|" ~/.kube/configIf you don't want to open up the firewall port for the Kubernetes API server,
then forward port 6443 using SSH port forwarding by executing the following
command:
RHEL_VM_IP_ADDR=192.168.122.111
ssh -L 6443:${RHEL_VM_IP_ADDR}:6443 redhat@${RHEL_VM_IP_ADDR}Run the following commands and verify communication is successful:
oc cluster-info
oc get pods -A