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

自作OSでLinuxコンテナを動かす

Avatar for n4mlz n4mlz
March 20, 2026
3.4k

 自作OSでLinuxコンテナを動かす

Avatar for n4mlz

n4mlz

March 20, 2026

Transcript

  1. 2 自己紹介 ⚫ 名前: n4mlz ⚫ 読み方: Nameless ⚫ 筑波大学

    情報科学類 3年 ⚫ 興味: コンテナランタイム、クラウドネイティブ技術、自作OS ⚫ 好き: 車輪の再発明 はじめに
  2. 3 自作OS「 Cyrius」 ⚫ Rust, x86-64, QEMU上で動作 ⚫ Linux コンテナ実行機能を充実させた

    専用のカーネル設計 ⚫ Linuxのフォークやコードの転用 エミュレート 〇 ネイティブに実行 「Cyrius」の紹介
  3. 4 Cyrius の特徴 ⚫ Cyrius は "Type1 Container Runtime" である

    自作OS「Cyrius」の紹介 ハイパーバイザー コンテナランタイム ユーザーランド (Type2) Type2 Hypervisor 例: QEMU, VirtualBox Type2 Container Runtime 例: runc (Docker), youki カーネル空間 (Type1) Type1 Hypervisor 例: VMware ESXi
  4. 5 Cyrius の特徴 ⚫ Cyrius は "Type1 Container Runtime" である

    自作OS「Cyrius」の紹介 ハイパーバイザー コンテナランタイム ユーザーランド (Type2) Type2 Hypervisor 例: QEMU, VirtualBox Type2 Container Runtime 例: runc (Docker), youki カーネル空間 (Type1) Type1 Hypervisor 例: VMware ESXi Type1 Container Runtime Cyrius
  5. 11 ところでこいつらは依存関係や仕様がめっちゃ煩雑 ユーザーランドで段階的に隔離環境を構築していく都合上、不整合な状態が簡単に起こりうる ⚫ PID Namespace は unshare(2) で分離されたあと一度 fork

    を挟まないと新しい Namespace が適用されない (他の Namespace はそんなことはない) ⚫ User Namespace は分離した後に UID マッピングを書き込む仕様だが書き込むまでは何の user でもない (UID 65534, nobody) ⚫ しかも UID マッピング (/proc/self/uidmap) の書き込みは Namespace の外からの書 き込みが必要なので、外にいるプロセスと何らかの IPC を行って書き込んでもらう必要 がある Linux におけるコンテナ (悪口)
  6. 12 ところでこいつらは依存関係や仕様がめっちゃ煩雑 そもそも Everything is a file という UNIX の思想はコンテナと相性が悪い

    (と、私は思っている) ⚫ UID mapping の書き込み:/proc/self/uidmap ⚫ Namespace を操作する時の fd:/proc/self/ns/ ⚫ 基本的にはそうだが Network Namespace の場合は /proc でなくとも任意の場所に作成 できる ⚫ Cgroups の操作:/sys/fs/cgroup ↑先に Mount Namespace を分離したらどうなる??/proc や /sys をマウントしなかったらど うなる?? Linux におけるコンテナ (悪口)
  7. 13 そんなこんなでコンテナを作成する場合は実質的なお作法が存在する 先程のような問題に対処していくと、結局は右のような順番 に落ち着く ⚫ 発行する syscall に結局は順序関係があって、また適切 なタイミングで何度か fork(2)

    が必要 ⚫ 複数プロセスが協調する必要があるので IPC だらけ ⚫ 最終的には 20 種類近くの syscall と最低限 4 つのプロセ スが必要 どのコンテナランタイム (runc, youki, crun) も基本的にはこ の流れである Linux におけるコンテナ (悪口) 引用: https://github.com/youki-dev/youki
  8. 14 そんなこんなでコンテナを作成する場合は実質お作法が存在する 先程のような問題に対処していくと、結局は右のような順番 に落ち着く ⚫ 発行する syscall に結局は順序関係があって、また適切 なタイミングで何度か fork(2)

    が必要 ⚫ 複数プロセスが協調する必要があるので IPC だらけ ⚫ 最終的には 20 種類近くの syscall と最低限 4 つのプロセ スが必要 どのコンテナランタイム (runc, youki, crun) も基本的にはこ の流れである Linux におけるコンテナ (悪口) 引用: https://github.com/youki-dev/youki けしからん じゃないか!! 好奇心アヒル
  9. 16 OCI Runtime Specification ⚫ コンテナランタイムが提供するべき機能や OCI Bundle の config.json

    の解釈方法、扱 われ方の定義を書いた仕様 ⚫ 例えば: コンテナランタイムは最低限 create, start, stop, ... 等の5つのサブコマンドを持つ ⚫ config.json: 起動時の uid, エントリーポイン トのバイナリへの path、ホスト名、環境変 数、等... 改めて: コンテナとは何か? https://github.com/opencontainers/runtime-spec
  10. 18 整理すると… 1. コンテナ:制限をつけて隔離性を担保させたプロセス 2. 環境のメタ情報 config.json:起動時の uid, エントリーポイントのバイナリへの path、ホス

    ト名、環境変数、等... 3. コンテナの rootfs:OCI Bundle に含まれる 重要:config.json に書かれた隔離環境が実現できれば方法は何でもよい ⇒ Linux バイナリ互換さえ作れば自作OSでLinuxコンテナを動作させられるのでは 改めて: コンテナとは何か? ⇒ OCI Bundle を直接解釈してコンテナを建てる専用の OS が考えられそう?
  11. 19 コンテナのカーネルオブジェクト化 ⚫ コンテナはカーネルオブジェクトであり、コンテナの状態やライフサイクル等を集約して カーネルが直接管理する ⚫ Container 構造体:rootfs やcapability、リソース制限などの環境情報を持たせる ⚫

    Static なフィールド:OCI Specification native な情報 (起動時に指定した config.json の内容) ⚫ Dynamic なフィールド:プロセス空間やコンテナ用いるルートファイルシステムへのハンドル等 Cyrius のカーネル設計思想
  12. 20 syscall テーブルの分離 ⚫ コンテナを管理するプロセス (Host) かコンテナプロセス (Linux) かを明確に区別する ⚫

    ホストプロセス:Linux 非互換で最小限の機能。コンテナランタイムを操作するための syscallテーブルのみに限られ、syscall は OCI ネイティブな単位である (create, start, stop 等)。ファイルシステムは最小限でほぼ何もない ⚫ コンテナプロセス:Linux バイナリ互換の syscall テーブルを用いる。ファイルシステムは プロセスが所属する Container 構造体の rootfs が使用される Process 構造体に enum(host|linux) を持たせ、プロセスによって使用する syscall テーブル を切り替える Cyrius のカーネル設計思想
  13. 21 VFS の完全な分離 ⚫ Container 構造体に独立した VFS のインスタンスを持つ ⚫ プロセスは所属

    Container 経由でのみ VFS にアクセスするため、chroot 的な jailbreak パ ターンを構造的に存在させない ⚫ 初めからファイルシステムがホストと完全に並列なインスタンスとして独立しているため隔 離性を扱いやすい ⚫ 参考 Linux の場合:コンテナ用 rootfs として使いたいディレクトリにマウントポイントを 作成、pivot_root でルートを張り替え、元の外側の rootfs をアンマウント… Cyrius のカーネル設計思想
  14. 24 時代は Linux バイナリ互換ではなく「Linux コンテナ互換」 ⚫ 普通に自作 OS のテーマとして面白い ⚫

    自作 OS で動かしたいアプリケーションを Linux 上でコンテナとしてビルドして、自作 OS に持って行ってしまえば良い ⚫ →あとは Linux として実行される ⚫ →自作 OS 用にコンパイルしたり、依存関係を頑張って揃えたりする必要がない ⚫ コンテナレベルの互換を作ると自作 OS の上で既存のエコシステムを活用できる・タダ乗り できる ⚫ お前もLinuxコンテナ互換を作らないか? Linuxコンテナ互換のススメ
  15. 25 (余談) oci-spec-rs-nostd ⚫ OCI 仕様に準拠するにあたって、Rust 製コンテナ ランタイムではoci-spec-rs クレートが使われる ⚫

    OCI Bundle 内の config.json のパーサー ⚫ 今回、自作 OS でも使えるよう no_std 環境用にフォークした ⚫ Rust で普通のコンテナランタイム自作をするのと変わらない書き味 ⚫ コントリビュート経験のある OSS を no_std 対応して自作 OS に組み込んでいるの激アツ ⚫ Rust で OS 自作しててカーネル内コンテナランタイムを自作したい人は是非使ってください (?) Linuxコンテナ互換のススメ
  16. 26 まとめ ⚫ Linux コンテナをネイティブ実行できる OS を実装した ⚫ コンテナの実行においては Linux

    よりシンプルな設計を目指した ⚫ 時代は「コンテナランタイム互換」、ですよ おわりに ご清聴ありがとうございました! スターお待ちしてます Cyrius