08.1
実行状態を構成する情報を集める

プロセスを再開するために、何を保存するのか

CRIUCRIULinuxプロセスやコンテナをユーザー空間から保存・復元するソフトウェア。は、Checkpoint/Restore In Userspaceの略です。Linuxカーネルが持つプロセスの状態をユーザー空間から読み出し、複数の保存ファイルへ記録します。復元時は、その記録を使ってプロセス、メモリ、ファイルディスクリプタなどを作り直します。

CRIUによる保存と復元の流れ実行中のプロセス群を停止し、状態を読み出してファイルへ保存する。そのファイルからメモリやファイルディスクリプタなどを作り直し、プロセスを再開する。実行中のプロセス群停止状態を読み出すimagefiles状態を作り直す再開checkpointrestore
CPU

レジスタとスレッド

次に実行する命令の位置、CPUレジスタ、シグナル、各スレッドの状態を記録します。

RAM

仮想メモリ

仮想アドレス空間の配置と、各pageにある内容を記録します。

カーネルが管理する対象

ファイルとsocket

ファイルディスクリプタ、パイプ、UNIX socket、TCP接続などの状態と共有関係を記録します。

プロセスの構造

PIDとnamespace

親子関係、PID、所属するnamespaceの構成を記録します。復元時は、この記録を使って同じ関係を作ります。

08.2
カーネルへ大きな機能を入れる案から、ユーザー空間中心の実装へ

CRIUが生まれた経緯

checkpoint/restoreは、メモリ管理、ファイルシステム、ネットワーク、プロセス管理など、多くのサブシステムにまたがります。2010年まで検討されたLinux-CRは、保存と復元の中心をカーネルへ置く構成でした。パッチが広範囲に及ぶことや、保存した状態を異なるカーネルバージョンで復元する互換性が課題になりました。

2010年

カーネル内のcheckpoint/restore

Linux-CRは、namespacenamespacePID、マウント、ネットワーク、ホスト名などの参照範囲を、プロセス群ごとに分ける仕組み。とfreezer cgroupfreezer cgroupcgroupに属するプロセス群をまとめて一時停止し、後で再開する機能。を土台に、カーネルがプロセスの状態を保存・復元する仕組みを提案しました。

→
2011年7月

ユーザー空間を中心に据えるRFC

Parallelsに所属していたPavel Emelyanovは、必要な情報を公開する小さなカーネルAPIを追加し、保存と復元の制御をユーザー空間へ置く案をLKMLへ投稿しました。CRIUという名前は同年11月に付けられました。

PIDを保存時の番号へ戻す

PID namespaceとns_last_pid

PID namespaceは、プロセス番号の参照範囲を分けます。同じPIDを復元するときは、CRIUが/proc/sys/kernel/ns_last_pidへ復元するPIDから1を引いた値を書き、その後にプロセスを作ります。Linuxカーネルは次のPIDを選ぶため、このAPIを使って保存時の番号を作り直せます。

08.3
保存ファイルにはプロセスの内部情報が入る

実行権限と保存先を管理する

実行する権限

対象プロセスの状態を読み出す

CRIUが使うカーネルAPIの多くは強い権限を要求します。Linux 5.9では、PIDの指定や他プロセスのメモリ情報の読み出しなど、checkpoint/restoreに関わる操作を分けるCAP_CHECKPOINT_RESTOREcapability従来rootへまとめて与えられていた権限を、操作の種類ごとに分けた単位。が追加されました。

保存ファイルの保護

メモリや認証情報を外へ漏らさない

保存ファイルにはメモリの内容、CPUレジスタ、ファイルのパス、通信中のデータなどが含まれます。アクセスできるユーザーを限定したディレクトリへ保存し、別の環境へ渡す場合も機密データとして扱います。

使われる場面

実行中のサービスを別のホストへ移すプロセスを停止し、後で同じ状態から再開する起動後の状態を保存し、起動時間を短くする障害発生時の状態を解析する