Nitro: 小型で柔軟な init システムおよびプロセススーパーバイザー
(git.vuxu.org)- Nitro は、組み込み、サーバー、デスクトップ、コンテナのすべてに適用できる超小型プロセススーパーバイザー兼 init システム
- システム状態を RAM にのみ保存するため、読み取り専用ファイルシステムでも問題なく動作し、高速で効率的なイベント駆動設計を提供
- 構成方式はシンプルなスクリプトディレクトリ構造で、複雑な設定ファイルや追加のビルド工程なしにサービス管理が可能
- パラメータ化サービス、堅牢な再起動、個別サービスごとの信頼性の高いロギング機能など、コンテナや組み込み環境に最適化された機能をサポート
- nitroctl ツールによるリモート制御、シグナルベースの動作制御など、高い柔軟性と制御性を保証
概要
Nitro は、Linux で pid 1 としても使用できる超小型プロセススーパーバイザー
主な適用分野は以下の通り
- 組み込み、デスクトップ、サーバーなど多様な用途の Linux マシン向け init
- Linux initramfs の init
- Docker/Podman/LXC/Kubernetes などコンテナ環境の init
- POSIX システムで権限なしに動作するスーパービジョンデーモン
構成はディレクトリベースのスクリプト構造を使用し、デフォルトの場所は /etc/nitro
要件
- カーネルの Unix ソケット サポートが必要
tmpfsまたは書き込み可能な/runディレクトリが必要
他システムに対する利点
- すべての状態情報は RAM にのみ保持されるため、読み取り専用ルートファイルシステムでも特別な工夫なしで動作
- イベント駆動でポーリングなしの動作方式により効率性を提供
- ランタイム中にメモリの動的確保がない
- ファイルディスクリプタが無制限に消費されない
- 1 つの**self-contained バイナリ(オプションで制御バイナリを追加)**だけでよい
- 設定ファイルの変換やコンパイルは不要で、サービスはスクリプトが入ったシンプルなディレクトリ
- サービス再起動とロギングチェーンをサポート
- システムクロックが正確でなくても正常動作
- FreeBSD では
/etc/ttysを通じて実行可能 - musl libc 使用時は超小型の static バイナリを作成可能
サービス管理
-
各サービスディレクトリ(デフォルトでは
/etc/nitro配下)は以下のファイルを含められるsetup: サービス開始前に実行される(任意の)スクリプト。正常終了(0)の場合にのみサービス開始可能run: サービス本体のスクリプト。終了しない限りサービスが生存していると見なされる。未実装の場合は one-shot サービスとして扱われるfinish:run終了後に実行される(任意の)スクリプト。終了状態とシグナル値を引数として受け取るlog: 別のサービスディレクトリを指すシンボリックリンク。run の出力をそのサービスの入力へパイプ接続する(ロギングチェーンに活用可能)down: このファイルが存在すると、nitro はデフォルトでこのサービスを起動しない- ディレクトリ名が
@で終わる場合は無視され、パラメータサービスとして活用可能 - サービス名は 64 文字未満で、
/、,、改行文字を含めることはできない
-
runit の
chpstユーティリティはrunスクリプト作成時に役立つ
特殊サービス
LOG: log リンクを持たないすべてのサービスのログ記録用デフォルトサービスSYS:SYS/setupはすべてのサービス起動前に実行され、順序付きサービス起動を実装可能SYS/finish: 全体の終了段階に入る前に実行SYS/final: すべてのプロセス終了後に実行SYS/fatal: 致命的エラー発生時に終了の代わりに実行(存在する場合)SYS/reincarnate: shutdown の代わりに実行され、たとえば initramfs の再実装などに活用可能
パラメータ化サービス
@で終わるサービスディレクトリは nitro からは無視されるが、シンボリックリンクまたはnitroctlコマンドで直接指定可能@の後ろのパラメータは各スクリプトに第 1 引数として渡される- 例:
agetty@/runとagetty@tty1のシンボリックリンクがある場合、agetty@/run tty1を実行 nitroctl up agetty@tty2を入力するとagetty@/run tty2を実行可能(ディレクトリの存在有無は不問)
- 例:
動作モード
- ライフサイクル全体は起動、サービス実行(スーパービジョン)、終了の 3 段階で構成
- 起動: 特殊サービス
SYSが存在する場合はsetupから実行し、その後すべての non-down サービスを実行 - サービスが終了すると再起動し、直近の再起動が速すぎる場合は 2 秒待機
nitroctl RebootまたはShutdownで終了シグナルを送信可能- この場合
SYS/finish→ 全サービスへ SIGTERM(最大 7 秒待機)→ SIGKILL →SYS/final→ 終了シーケンス
- この場合
- コンテナや権限のないスーパーバイザー用途ではプロセスのみ終了
- 起動: 特殊サービス
nitroctl による制御
- nitroctl CLI ツールで離れた場所から nitro を制御可能
コマンド例:
- list: サービス一覧、状態、PID、uptime、最後の終了状態を表示
- up/down/start/stop/restart: サービスの起動・停止・再起動などを制御
- シグナル送信: p(SIGSTOP), c(SIGCONT), h(SIGHUP), a(SIGALRM), i(SIGINT), q(SIGQUIT), 1(SIGUSR1), 2(SIGUSR2), t(SIGTERM), k(SIGKILL)
- pidof: 指定サービスの PID を表示
- rescan: サービスディレクトリを再読み込みし、追加・削除されたサービスを反映
- Shutdown/Reboot: システム全体の停止・再起動
シグナルによる制御
- nitro プロセスへシグナルを直接送って制御可能
- SIGHUP: サービス再スキャン(rescan)
- SIGINT: 再起動
- SIGTERM: 終了(nitro が pid 1 でない場合)
Linux で init として使う nitro
- Nitro は自己完結型バイナリとして Linux の pid 1 に直接ブート可能
/dev、/runを必要に応じてマウントし、その他の処理はSYS/setupで行う- Ctrl-Alt-Del イベントで秩序ある再起動をトリガー
Docker コンテナで init として Nitro を使う
- Nitro は静的にビルドでき、コンテナへ簡単に組み込める
- デフォルトのソケットパスを使うにはコンテナ内に
/runが存在する必要がある - 制御ソケットをバインドマウントすれば、外部から nitroctl でリモート制御可能
FreeBSD での Nitro
/etc/ttysに次の行を追加すると、FreeBSD init から nitro をスーパーバイズ可能/etc/nitro "/usr/local/sbin/nitro" "" on
著者
- Leah Neukirchen leah@vuxu.org
謝辞
- daemontools, freedt, runit, perp, s6 など既存のプロセススーパービジョンシステムを詳細に分析した上で開発
ライセンス
- 0BSD ライセンス(詳細は LICENSE ファイルを参照)
まだコメントはありません。