Slide 1

Slide 1 text

自作OSでLinuxコンテナを動かす n4mlz Kernel/VM探検隊 2026/03/20 @n4mlz @n4mlz

Slide 2

Slide 2 text

2 自己紹介 ⚫ 名前: n4mlz ⚫ 読み方: Nameless ⚫ 筑波大学 情報科学類 3年 ⚫ 興味: コンテナランタイム、クラウドネイティブ技術、自作OS ⚫ 好き: 車輪の再発明 はじめに

Slide 3

Slide 3 text

3 自作OS「 Cyrius」 ⚫ Rust, x86-64, QEMU上で動作 ⚫ Linux コンテナ実行機能を充実させた 専用のカーネル設計 ⚫ Linuxのフォークやコードの転用 エミュレート 〇 ネイティブに実行 「Cyrius」の紹介

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

6 まずはデモ 自作OS上で Busybox コンテナを動作させる様子 自作OS「Cyrius」の紹介

Slide 7

Slide 7 text

7 何故作ったか? モチベーション

Slide 8

Slide 8 text

8 何故作ったか? ⇒ Linux がカス モチベーション

Slide 9

Slide 9 text

9 Linux におけるコンテナ ずばりコンテナとは:カーネルによって様々な制限がつけられた、ただのプロセス ⚫ コンテナというファイルシステムを持つサンドボックスがあって、その中にプロセスがある ⚫ 〇 ある制限がいっぱいついたプロセスがあって、そのプロセスから見えるファイルシステムが 限られているだけ Linux におけるコンテナ

Slide 10

Slide 10 text

10 コンテナはカーネルの機能を使ってユーザーランドで実現されている ⚫ カーネル側はコンテナ以外の様々な用途にも応用できるよう、環境分離用の最低限の小さい 操作群を提供している (UNIX哲学) ⚫ ユーザーランドのランタイムはそれらを組み合わせてコンテナを作るが、カーネル側はそれ がコンテナかどうかは理解しない ⚫ 例:Namespace や Cgroups, capability, mount 操作… Linux におけるコンテナ

Slide 11

Slide 11 text

11 ところでこいつらは依存関係や仕様がめっちゃ煩雑 ユーザーランドで段階的に隔離環境を構築していく都合上、不整合な状態が簡単に起こりうる ⚫ PID Namespace は unshare(2) で分離されたあと一度 fork を挟まないと新しい Namespace が適用されない (他の Namespace はそんなことはない) ⚫ User Namespace は分離した後に UID マッピングを書き込む仕様だが書き込むまでは何の user でもない (UID 65534, nobody) ⚫ しかも UID マッピング (/proc/self/uidmap) の書き込みは Namespace の外からの書 き込みが必要なので、外にいるプロセスと何らかの IPC を行って書き込んでもらう必要 がある Linux におけるコンテナ (悪口)

Slide 12

Slide 12 text

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 におけるコンテナ (悪口)

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

15 OCI Bundle コンテナイメージから生成される、限りなく実行単位に近いもの ⚫ config.json:展開するファイルシステム、分離する名前空間、実行するユーザー、ケーパビリ ティ、環境変数などの定義等 ⚫ rootfs:そのコンテナが利用するルートファイルシステム Linux 上のコンテナランタイムはこれを見て必要な syscall を叩き、コンテナを作成する 改めて: コンテナとは何か? OCI Bundle コンテナ

Slide 16

Slide 16 text

16 OCI Runtime Specification ⚫ コンテナランタイムが提供するべき機能や OCI Bundle の config.json の解釈方法、扱 われ方の定義を書いた仕様 ⚫ 例えば: コンテナランタイムは最低限 create, start, stop, ... 等の5つのサブコマンドを持つ ⚫ config.json: 起動時の uid, エントリーポイン トのバイナリへの path、ホスト名、環境変 数、等... 改めて: コンテナとは何か? https://github.com/opencontainers/runtime-spec

Slide 17

Slide 17 text

17 OCI Runtime Specification 改めて: コンテナとは何か? ところで: 仕様では、前述した Linux の複雑な機能を 使ってコンテナを作成することを必ずしも求めていない

Slide 18

Slide 18 text

18 整理すると… 1. コンテナ:制限をつけて隔離性を担保させたプロセス 2. 環境のメタ情報 config.json:起動時の uid, エントリーポイントのバイナリへの path、ホス ト名、環境変数、等... 3. コンテナの rootfs:OCI Bundle に含まれる 重要:config.json に書かれた隔離環境が実現できれば方法は何でもよい ⇒ Linux バイナリ互換さえ作れば自作OSでLinuxコンテナを動作させられるのでは 改めて: コンテナとは何か? ⇒ OCI Bundle を直接解釈してコンテナを建てる専用の OS が考えられそう?

Slide 19

Slide 19 text

19 コンテナのカーネルオブジェクト化 ⚫ コンテナはカーネルオブジェクトであり、コンテナの状態やライフサイクル等を集約して カーネルが直接管理する ⚫ Container 構造体:rootfs やcapability、リソース制限などの環境情報を持たせる ⚫ Static なフィールド:OCI Specification native な情報 (起動時に指定した config.json の内容) ⚫ Dynamic なフィールド:プロセス空間やコンテナ用いるルートファイルシステムへのハンドル等 Cyrius のカーネル設計思想

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

21 VFS の完全な分離 ⚫ Container 構造体に独立した VFS のインスタンスを持つ ⚫ プロセスは所属 Container 経由でのみ VFS にアクセスするため、chroot 的な jailbreak パ ターンを構造的に存在させない ⚫ 初めからファイルシステムがホストと完全に並列なインスタンスとして独立しているため隔 離性を扱いやすい ⚫ 参考 Linux の場合:コンテナ用 rootfs として使いたいディレクトリにマウントポイントを 作成、pivot_root でルートを張り替え、元の外側の rootfs をアンマウント… Cyrius のカーネル設計思想

Slide 22

Slide 22 text

22 コンテナを実現するコンポーネントの依存関係 ⚫ 全てが Container 構造体に集約される Linux と Cyrius の比較 Cyrius

Slide 23

Slide 23 text

23 コンテナが実行されるまでの手続き ⚫ コンテナの生成は 1 つの syscall で済み、コンテナを生成するまでに余計なカーネル間と ユーザー間の処理の往復をしない Linux と Cyrius の比較 Cyrius 引用: https://github.com/youki-dev/youki

Slide 24

Slide 24 text

24 時代は Linux バイナリ互換ではなく「Linux コンテナ互換」 ⚫ 普通に自作 OS のテーマとして面白い ⚫ 自作 OS で動かしたいアプリケーションを Linux 上でコンテナとしてビルドして、自作 OS に持って行ってしまえば良い ⚫ →あとは Linux として実行される ⚫ →自作 OS 用にコンパイルしたり、依存関係を頑張って揃えたりする必要がない ⚫ コンテナレベルの互換を作ると自作 OS の上で既存のエコシステムを活用できる・タダ乗り できる ⚫ お前もLinuxコンテナ互換を作らないか? Linuxコンテナ互換のススメ

Slide 25

Slide 25 text

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コンテナ互換のススメ

Slide 26

Slide 26 text

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