Skip to content

Instantly share code, notes, and snippets.

@saku3
Last active September 12, 2025 23:22
Show Gist options
  • Select an option

  • Save saku3/9a3d45e61e329a29a3214cdff0797193 to your computer and use it in GitHub Desktop.

Select an option

Save saku3/9a3d45e61e329a29a3214cdff0797193 to your computer and use it in GitHub Desktop.
youki + libkrun

youki + libkrun

Overview

youkiとlibkrunを利用したVM型のコンテナの起動について説明する

全体像

  • youki

    • ContainerBuilderがbuild関数を実行するときにpre_exec関数を実行する
    • 通常のコンテナと同じく, Main Process, Intermediate Process, Init Processを実行する
    • 最後にInit Processでlibkrun用のexec関数を実行する
  • Executor(libkrun 用)

    • run.oci.handler=krun の OCI annotations が付いているコンテナだけを担当(それ以外は CantHandle を返してフォールバック)。
    • pre_exec(spec): 実行前の準備(libkrun.so ロード, krun_create_ctx で ctx 生成, spec の調整 と .krun_config.json の出力 など)
      • config.jsonを読み込んだ後, 且つ コンテナ作成操作(namespace作成, pivot_root)する前にExecutorで設定する必要のある処理があるためこの関数を作成した
    • exec(spec): libkrun API を呼んで VM を実際に起動(krun_set_vm_config, krun_set_root, krun_start_enter)
  • libkrun

    • KVMを利用してVMを起動する

影響範囲

  • libcontainer
    • ContainerBuilderがbuild関数を実行するときにpre_exec関数を実行するように変更
    • この変更は通常のコンテナ起動処理に影響は与えない想定
  • Executor
    • features flagを利用し、libkrun用のコンテナを起動する時のみに実行するexec関数を用意した.この変更による影響はない。
    • Executorでlibkrunに関する値(lib, ctx_id)を保持したいので、DefaultExecutorに修正を加えた.
      • 現状のget_executorを毎回実行する方式では値が初期化されてしまうため

Container Creation

youki と libkrun を利用して VM 型コンテナを起動する手順を示す。

  1. youki を実行する

    • OCI バンドルの config.jsonannotations."run.oci.handler" = "krun" を設定
  2. libcontainer で InitContainerBuilder/TenantContainerBuilderのbuild を実行する

    • Executor の pre_exec を呼ぶ
      • init_builder.rs / tenant_builder.rsbuild 内で実行する想定
      • config.json を読み込んだ直後かつ pivot_root より前に実行する
      • wasm 系と同様に features flag で有効化
      • can_handle で実行可否を判定
    • libkrun をロードし、コンテキストを作成する
      • 名前空間切替前 & pivot_root 前libkrun.soのロード と krun_create_ctx() を行う
      • そうしないとバンドルされたファームウェア(libkrunfw)等が見つからない場合がある(crun 実装に準拠)
    • /dev/kvm を使うために config.json を更新する
      • 存在しない場合、linux.devices/dev/kvm を追加
      • デバイス制限がある場合resources.devices/dev/kvm の allow ルールを追加
    • config.json を複製して rootfs/.krun_config.json を作成する
  3. 通常どおり Main / Intermediate / Init の各プロセスを生成する

  4. Init Process で executor.exec を呼ぶ

    • feature = libkrun の時は libkrun 用 Executor を実行する(CantHandle の場合はフォールバック)
  5. libkrun の起動前設定を行う(Init 側)

    • krun_set_vm_config(ctx, vcpus, ram_mib):VM に割り当てる vCPU 数とメモリを設定
    • krun_set_root(ctx, "/"):ゲスト OS のルートを設定(pivot_root 済みのため "/" を渡す)
    • krun_set_log_level(ctx, 1):ログレベルを設定(例:1=error)
  6. VM を起動する

    • krun_start_enter(ctx) を呼ぶ。
sequenceDiagram
    participant youki
    participant Main Process
    participant Intermediate Process
    participant Init Process
    participant Executor
    participant libkrun
    participant kvm

    Note over youki: load config.json
    rect rgb(235,250,235) 
        youki->>Executor: pre_exec()
        opt feature "libkrun"
            Executor->>libkrun: load libkrun.so
            Executor->>libkrun: krun_create_ctx()
            Note over Executor: modify config.json
            Note over Executor: setup .krun_config.json
        end
    end
    youki->>Main Process: container_main_process()
    Main Process->>Intermediate Process: clone3
    Intermediate Process->>Init Process: clone3
    Note over Init Process: pivot_root
    Init Process->>Executor: exec()
    rect rgb(235,250,235)
        opt feature "libkrun"
            Executor->>libkrun: krun_set_vm_config()
            Executor->>libkrun: krun_set_root()
            Executor->>libkrun: krun_set_log_level(1)
            Executor->>libkrun: krun_start_enter()
            libkrun->>kvm: start
        end
    end
Loading

実行方法

kvmが有効になっていることを確認する

lsmod | grep kvm
kvm_intel             483328  0
kvm                  1425408  1 kvm_intel
irqbypass              12288  1 kvm

libkrunとlibkrunfwをインストールする

https://github.com/containers/libkrun

https://github.com/containers/libkrunfw

ls /usr/local/lib64 | grep libkrun
libkrun.so
libkrun.so.1
libkrun.so.1.15.0
libkrunfw.so
libkrunfw.so.4
libkrunfw.so.4.10.0

edit config.json

  "annotations": {
    "run.oci.handler": "krun"
  }
cd crate/youki
LD_LIBRARY_PATH=/usr/local/lib64 cargo run --features libkrun --features systemd run -b ../../tutorial/  container
DEBUG libcontainer::user_ns: this container does NOT create a new user namespace
DEBUG youki::workload::libkrun: executing libkrun pre executer
...
DEBUG libcontainer::notify_socket: notify container start
DEBUG libcontainer::notify_socket: notify finished
DEBUG libcontainer::notify_socket: received: start container
DEBUG libcontainer::container::container: Save container status: Container { state: State { oci_version: "v1.0.2", id: "container", status: Running, pid: Some(31812), bundle: "/home/ubuntu/workspace/youki/tutorial", annotations: Some({"run.oci.handler": "krun"}), created: Some(2025-09-02T23:26:08.276279669Z), creator: Some(0), use_systemd: false, clean_up_intel_rdt_subdirectory: Some(false) }, root: "/run/youki/container" } in "/run/youki/container"
DEBUG youki::workload::libkrun: executing libkrun executer
~ # 

another terminal

ps aux | grep youki
root       31735  0.3  0.0  38144 14000 pts/1    S+   23:26   0:00 /home/ubuntu/workspace/youki/target/debug/youki run -b ../../tutorial/ container
root       31812  0.1  0.0 1512708 63472 ?       Ssl  23:26   0:00 /home/ubuntu/workspace/youki/target/debug/youki run -b ../../tutorial/ container
root       31981  0.0  0.0   7076  1868 pts/3    S+   23:27   0:00 grep --color=auto youki

$ pstree -p  31735
4(31735)───libkrun VM(31812)─┬─{libkrun VM}(31814)
                             ├─{libkrun VM}(31815)
                             ├─{libkrun VM}(31817)
                             ├─{libkrun VM}(31818)
                             ├─{libkrun VM}(31819)
                             ├─{libkrun VM}(31820)
                             └─{libkrun VM}(31821)

TODO

  • youki run以外
  • テスト libkrunがない環境でもできるようにしたい
  • ルートレスコンテナ(何か追加が必要か)
  • サポート like crun
    • SEV, Nitro Enclaves virtio-gpu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment