Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mewz on libkrun

Avatar for Naoki MATSUMOTO Naoki MATSUMOTO
May 11, 2025
320

Mewz on libkrun

2025/05/11 Kernel/VM探検隊@関西 11回目

Avatar for Naoki MATSUMOTO

Naoki MATSUMOTO

May 11, 2025
Tweet

Transcript

  1. Mewz, Wasker について Wasker: WebAssembly モジュールをオブジェクトファイルに変換する AoT コンパイラ • WASI

    の呼び出しを未解決シンボルとして変換する = リンク先は WASI 関数を実装すればよい Mewz: ↑のオブジェクトファイルをリンクし動作する unikernel • シンプルな kernel にアプリもまとめてリンクして動作する https://www.ipa.go.jp/jinzai/mitou/it/2023/m42obm000000azzl-att/seikagaiyou-sg-1.pdf より https://github.com/mewz-project/mewz https://github.com/mewz-project/wasker スライド: https://pibvt.net/kernelvm-2025-0511.pdf 2
  2. libkrun について Sergio López 氏(@RedHat) が開発する軽量 VMM • コンテナを VM

    として動作させるために開発されている • Rust で実装 • デバイスのサポートは必要最低限(virtio 系) • コンテナの RootFS を virtio-fs 経由でマウントし動作 • ネットワーク周りは意図的にホストと共有 → ホスト側の network namespace による分離(Pod としても利用可能) • passt: virtio-net 経由でやり取りされる L2 パケットをホスト側の L4 なソケット操作に置換 QEMU の user-mode networking 相当 • tsi: ゲスト内のソケット操作を virtio-vsock 経由でホストに中継(詳細は後述) 参考 • https://logmi.jp/main/technology/324735 • https://rheb.hatenablog.com/entry/libkrun-intro libkrun Linux kernel コンテナ RootFS (via virtio-fs) VM https://github.com/containers/libkrun スライド: https://pibvt.net/kernelvm-2025-0511.pdf 3
  3. libkrun の概観 “lib”krun = VMM 実体は共有ライブラリとして提供 • krun_* API を提供

    • Linux kernel も共有ライブラリ(libkrunfw)として提供 https://github.com/containers/libkrun/blob/main/examples/chroot_vm.c より https://pibvt.hateblo.jp/entry/2024/12/30/213756 スライド: https://pibvt.net/kernelvm-2025-0511.pdf 4
  4. Mewz on libkrun までの道のり 「Mewz と libkrun、軽量なもの同士相性よさそう 」 → Mewz

    on likbrun をやってみることに 本発表はブログ記事「Mewz on libkrun」シリーズに関する発表です ブログ記事: https://pibvt.hateblo.jp/entry/2024/12/30/213724 Mewz を libkrun で動かすまでの道のり 1. Linux zeropage への対応 (ここで最小限のブートが可能になる) 2. kernel command-line params への対応 3. Virtio Over MMIO への対応(virtio-net, virtio-console) スライド: https://pibvt.net/kernelvm-2025-0511.pdf 5
  5. Linux zeropage Linux zeropage: メモリ領域等各種パラメータを保持する (libkrun が情報を埋め込む) 参考: https://github.com/torvalds/linux/blob/01f95500a162fca88cefab9ed64ceded5afabc12/arch/x86/include/uapi/asm/bootparam.h#L115-L163 ※

    Mewz は multiboot protocol のみ対応 今回は E820 (利用可能なメモリ領域) についてのみ対応すれば OK 1. zeropage からE820 エントリ数 (@ 0x7000 + 0x1E8, u8) を読み取る 2. E820 のエントリ(@ 0x7000 + 0x2D0 + 20 * n)を順番に読み取る 3. type == 1 (E820 RAM) な領域を拾い集める 4. Mewz 側で利用可能な領域としてメモリ管理を初期化 multiboot との共存(QEMU での動作)は magic value で行う https://pibvt.hateblo.jp/entry/2024/12/30/213824 スライド: https://pibvt.net/kernelvm-2025-0511.pdf 6
  6. Kernel command-line params libkrun は Virtio MMIO デバイスの情報を kernel params

    として提供 ※ libkrun は Virtio PCI を利用しないためスキャンによる検出はできない(後述) zeropage から kernel params へのアドレスを取得し↓の文字列をパースする パースの手順 1. 空白区切りで取り出す 2. ネットワーク情報, Virtio MMIO デバイス関連以外はとりあえず無視 • ネットワーク(ip=192.168.10.2/24, gateway=192.168.10.1) • Virtio デバイス(virtio_mmio.device=4K@0xd0004000:9) サイズ@アドレス:IRQLine 3. 取得した情報で各種設定を行う https://pibvt.hateblo.jp/entry/2024/12/30/213824 reboot=k panic=-1 panic_print=0 nomodule console=hvc0 rootfstype=virtiofs rw quiet no-kvmapf … スライド: https://pibvt.net/kernelvm-2025-0511.pdf 7
  7. Virtio Over MMIO Kernel params の情報をもとに Virtio MMIO なデバイスを初期化する 1.

    アドレスに対して→をマップして情報取得 2. ↓にあるようにVirtqueue の初期化を行う 3. 残りの初期化は Virtio Over PCI なデバイスと 同じ手順で行う https://docs.oasis-open.org/virtio/virtio/v1.3/csd01/virtio-v1.3-csd01.html#x1-1820002 より スライド: https://pibvt.net/kernelvm-2025-0511.pdf 8 https://pibvt.hateblo.jp/entry/2024/12/30/213842
  8. 動作 現状の実装を GitHub にて公開中 $ sudo apt install -y passt

    $ git clone --recursive http://github.com/naoki9911/mewz-on-libkrun $ cd mewz-on-libkrun $ docker run --rm -v $(pwd):/work ghcr.io/naoki9911/mewz-on-libkrun:main /work/build.sh $ cd likbrun/examples $ sudo LD_LIBRARY_PATH=../lib ./chroot_vm --net=passt dummy dummy スライド: https://pibvt.net/kernelvm-2025-0511.pdf 9
  9. 発展: Transparent Socket Impersonation Transparent Socket Impersonation(TSI): ゲストはTCP/IP スタックを持たず、virtio-vsock 経由でホストの

    TCP/IP スタックを利用する • passt のようなL2<->L4 ソケット操作の変換が存在しないためシンプル • ゲストが TCP/IP スタックを持たなくてよい = シンプル ゲスト内 アプリ TCP/IP スタック (lwIP) virtio- net TSI スタック virtio- vsock libkrun passt ホスト TCP/IP スタック Tcp/Udp proxy ソ ケ ッ ト L2 パケット L4ソケット相当の操作 (read, write etc.) L2<->L4 L4<->L2 スライド: https://pibvt.net/kernelvm-2025-0511.pdf 10 L4ソケット操作
  10. TSI の実装: virtio-vsock TSI には virtio-vsock の実装が必要 → 実装した •

    ソケットに対応したパケットの振り分け機構 • 各ソケットにおけるハンドシェイク(→の流れ) • WASI (wasmedge_wasi_socket) にも対応 = WASM アプリからも AF_VSOCK を叩ける https://pibvt.hateblo.jp/entry/2025/01/07/235839 https://pibvt.hateblo.jp/entry/2025/01/13/004833 スライド: https://pibvt.net/kernelvm-2025-0511.pdf 11
  11. TSI の実装 TCP/IP スタック -> TSI への置き換えを実装 ※本来は kernel param

    で “tsi” が指定されるためそれに応じて切り替えるべき libkrun 側の TSI モジュールと通信して bind, listen 等を処理 https://pibvt.hateblo.jp/entry/2025/01/18/195434 スライド: https://pibvt.net/kernelvm-2025-0511.pdf 12
  12. まとめ Mewz on libkrun • libkrun を用いれば軽量に Mewz を動作させることが可能 •

    libkrun での動作には Linux zeropage, Virtio MMIO 等への対応が必要 • TSI を用いればゲスト側で TCP/IP スタックを持つ必要がなくなる さらに詳しい内容 • ブログ記事: https://pibvt.hateblo.jp/entry/2024/12/30/213724 • リポジトリ: https://github.com/naoki9911/mewz-on-libkrun • 蛇足: Intel64 と AMD64 の PML4 Paging 仕様の差異 https://x.com/PiBVT/status/1755141978940211595 スライド: https://pibvt.net/kernelvm-2025-0511.pdf 14