Hermit Unikernel for Rust

repository·main·Indexed 24 days ago

https://github.com/hermit-os/hermit-rs

A lightweight, Rust-based unikernel designed for high-performance and cloud computing. It allows developers to bundle applications directly with a kernel library, eliminating the need for a traditional installed operating system. The project includes the hermit-abi for kernel interfacing, Hermit-WASM for running WebAssembly modules in lightweight VMs, and a suite of TCP/UDP network performance benchmarks.

Tokens
6.7K
Snippets
14
Records
48
Agent score
83%

What's inside hermit-rs

  1. Overview of Hermit-WASM

    main

    Hermit-WASM allows you to run WebAssembly (WASM) modules on top of the Hermit Unikernel inside a lightweight virtual machine. It is designed to enable the safe execution of untrusted or third-party WASM code with very low latency and overhead.

    Key Constraints & Limitations:

    • Compiler: Requires the Rust nightly compiler.
    • WASI Support: Currently only supports the wasm32-wasip1 target.
    • Bindings: Implements only a subset of the required WASI bindings.
  2. Run Hermit-WASM using uhyve

    main

    For a simpler alternative, use uhyve, a minimal hypervisor for Hermit that provides direct access to local directories without requiring virtiofsd.

    In this example, the local WASM file is mounted to /root/wasm-test.wasm inside the VM.

    uhyve -c 1 -m 1GiB --file-isolation none --file-mapping target/wasm32-wasip1/release/wasm-test.wasm:/root/wasm-test.wasm target/aarch64-unknown-hermit/release/hermit-wasm -- -- /root/wasm-test.wasm
  3. Add Hermit to your Rust project

    main

    To build a Hermit unikernel image, you must configure your project to use the hermit crate specifically when targeting the Hermit OS.

    1. Add hermit as a dependency for the hermit target in your Cargo.toml.
    2. In your main.rs, include hermit as an empty dependency using use hermit as _; gated by the target_os = "hermit" configuration.
    [target.'cfg(target_os = "hermit")'.dependencies]
    hermit = "0.6"
    #[cfg(target_os = "hermit")]
    use hermit as _;
  4. Build a Hermit unikernel image

    main

    Building requires a target with the *-unknown-hermit triple. You have two options depending on your Rust toolchain:

    • Stable Rust: Install the rust-std-hermit component.
    • Nightly Rust: Use the -Zbuild-std=std,panic_abort flag during the build process.
  5. Build Rust applications on Hermit

    main

    To build applications for the Hermit unikernel, use the provided project template. Hermit is designed so that the build process is similar to the standard Rust workflow. Rust applications that use the Rust runtime and do not directly use OS services can run on Hermit without modifications.

    For a starting point, use the official template repository.

    https://github.com/hermit-os/hermit-rs-template
  6. Visualize benchmark results with plotter.py

    main

    To produce a Cumulative Distribution Function (CDF) plot for bandwidth or latency, use the plotter.py tool.

    Prerequisites

    • matplotlib must be installed.

    Instructions

    1. Capture Output: Redirect the output of the server or client to a file:
      • For bandwidth (bw): Redirect output from server-bw (or server.rs).
      • For latency: Redirect output from client-latency (or client.rs).
    2. Run Plotter: python plotter.py <file_with_output>

    Note: Bandwidth plots may be unreliable during two-way communication tests due to processing spikes on the server side.

    python plotter.py <file_with_server.rs_output>
  7. Run Hermit-WASM using Qemu and virtiofsd

    main

    This method assumes a Linux host on an aarch64 processor with virtiofsd and KVM installed.

    1. Build the WASM application for the wasm32-wasip1 target:

      cargo build --target wasm32-wasip1  --release -p wasm-test
    2. Start virtiofsd to share the directory containing your WASM binary:

      virtiofsd --socket-path=./vhostqemu --shared-dir ./target/wasm32-wasip1/release --announce-submounts --sandbox none --seccomp none --inode-file-handles=never
    3. Launch Qemu with the Hermit-WASM kernel and the WASM module as an argument:

      qemu-system-aarch64 --enable-kvm -display none -serial stdio -kernel hermit-loader-x86_64 -initrd target/aarch64-unknown-hermit/release/hermit-wasm -append "-- /root/wasm-test.wasm" -cpu host -device isa-debug-exit,iobase=0xf4,iosize=0x04 -smp 1 -m 2G -global virtio-mmio.force-legacy=off -chardev socket,id=char0,path=./vhostqemu -device vhost-user-fs-pci,queue-size=1024,packed=on,chardev=char0,tag=root -object memory-backend-file,id=mem,size=1024M,mem-path=/dev/shm,share=on -numa node,memdev=mem
  8. Build Hermit-WASM from source

    main

    To build Hermit-WASM, clone the hermit-rs repository with submodules and use cargo build with specific Hermit targets.

    Architecture Targets:

    • aarch64: aarch64-unknown-hermit
    • x86_64: x86_64-unknown-hermit
    • RISC-V: riscv64gc-unknown-hermit
    # clone Hermit repository
    git clone --recurse-submodules https://github.com/hermit-os/hermit-rs.git
    # switch the directory of the Hermit repository
    cd hermit-rs
    # build Hermit-WASM for aarch64
    cargo build -Zbuild-std=std,panic_abort -Zbuild-std-features=compiler-builtins-mem --target aarch64-unknown-hermit -p hermit-wasm --release
  9. Run rust-tcp-io-perf benchmarks using Python scripts

    main

    Automated benchmarks can be run using provided Python scripts. This requires a configuration file (e.g., config_bw.config or config_latency.config) containing machine names, SSH keys, and usernames.

    Prerequisites

    • Ensure you can SSH into the target machines.
    • SSH connections must be correctly configured (known hosts and SSH keys available on the local machine).

    Execution

    Run the scripts by passing the configuration file location as an argument: python <script> <config_file_location>

    Available Scripts

    • runner.py: Runs a single client and a single server remotely.
    • runner_bidirectional.py: Runs two clients and two servers (one client/server pair on each of the two machines) to test bidirectional communication.

    Plotting

    Set PLOT=1 in your configuration file to automatically generate a summary plot of the samples.