CRIU-プロセス状態の保存と復元のための新しい野心的なプロジェクト

CRIU(アプリケーションチェックポイント/ユーザー空間での復元)は、プログラムの状態をチェックポイントとして保存し、この時点からアプリケーションを再開できる、意欲的で急速に発展しているプロジェクトです。

ソフトウェアを使用してブレークポイントを作成する可能性は非常に多様です。 たとえば、OpenVZはライブマイグレーションに同様のメカニズムを使用します。 Parallels Virtuozzoは同様のメカニズムを使用して、カーネルの更新後にコンテナをすばやく再開します。 CRIUは、障害発生時にアプリケーションを再開するために使用されるコンピューティングプロセスの中間結果を保持するために、高性能クラスターで既に使用されています。

この記事では、CRIUがプログラムの状態を保存および復元する方法と、このプロジェクトが以前のプロジェクトよりも成功する理由について説明します。





ちょっとした歴史



CRIUは、Linuxでプログラムを保存および復元するためのメカニズムを実装する最初の試みからはほど遠いものです。 OpenVZと、Oren Laadan率いるlinux-crプロジェクトの少なくとも2つのC / R実装が動作しています。

両方のプロジェクトの問題は、すべてのC / Rをカーネルスペースでほぼ完全に実装することです。 ただし、これらのプロジェクトは、大量のコードと複雑なコードのために、メインのLinuxカーネルの一部にはなりませんでした。

OpenVZ開発チームのリーダーであるPavel Emelyanovは、C / R自体へのアプローチを変更し、主な作業をユーザー空間に移行することを提案しました。 コミュニティはこのアイデアを受け入れ、CRIUプロジェクトが登場しました。



アプリケーションの状態を保存する



アプリケーションは、1つまたは複数の実行中のプロセスで構成できます。 CRIUは両方のタイプをサポートしています。

プロセスの状態に関する情報を取得するために最初に頭に浮かぶのは、デバッガー(ptrace)で使用されるメカニズムの使用です。 しかし、彼はすべての情報を提供しているわけではありません。 プロセスの状態の一部は、procfsファイルシステムとprctlシステムコールから取得できますが、これだけでは不十分です。

不足している情報を取得するために、CRIUプロジェクトは実行可能コード(いわゆるスプリアスコード)をプロセスに導入するメカニズムを使用しました。



アプリケーション状態の回復



チェックポイントからアプリケーションを復元するには、最初にそのプロセスのツリーを作成する必要があります。 これを行うために、特定の識別子を持つプロセスを作成するための個別のメカニズムがLinuxカーネルで開発されました。 開始後、各プロセスはメモリを復元し、ファイル、ソケット、パイプ、IPCなどを開きます。

ただし、実際には、リソースは複数のプロセスで共有できるため、すべてがそれほど単純ではありません。

プロセスのアドレス空間領域は一意(MAP_PRIVATE)にすることも、複数のプロセスから同時にアクセスすることもできます(MAP_SHARED)。 最初のタイプは非常に簡単に復元されます(「コピーオンライト」テクノロジについて考えていない場合-この記事の括弧の外にあります)。

2番目のオプションの問題は何ですか? ファイルにマップされたアドレス空間領域があれば、すべて問題ありません。標準のLinuxメカニズムを使用して、そのようなアドレス空間を復元できます。

しかし、地域が匿名(MAP_ANONYMOUS)の場合、つまり RAMにマップされていますか? そのような領域の復元をサポートするには、カーネルをファイルで再度トリムする必要がありました。つまり、それぞれをprocfsファイルシステムに表示する必要がありました-分散メモリ領域ごとに、カーネルは/ proc / self / map_files / <start_addr>-<end_addr>にファイルを作成します これらのファイルのおかげで、分散メモリの匿名領域をファイルとして復元できます。

行の次の問題は、開いているファイルでした。 複数のプロセス間で共有することもできます。 ここでは、Unixソケットを介してファイル記述子を転送する機能が役立ちました。 ユーザープロセスの1つがファイルを開き、その記述子を他のユーザーに送信します。

そのため、メモリが復元され、ファイルが開かれます。 プロセス制御はどのように転送されますか? コントロール転送はsigreturn()システムコールに基づいています。シグナルがプロセスに到着すると、カーネルはプロセスの状態を保存し、最後にsigreturn()を呼び出すシグナルハンドラに制御を転送します。 したがって、目的のポイントからプロセスを開始するには、目的の形式でプロセスの状態を復元し、sigreturn()を呼び出すだけで十分です。

そして今、プロセスは復元され、機能し続けています。



おもしろい



CRIUはTCP接続を保存および復元できます。 これはライブマイグレーションに使用できます。 アプリケーションが別のサーバーへのすべての接続で移動する場合、ユーザーはネットワークアクティビティのわずかな遅延にのみ気付くでしょう。

CRIUは、Googleのプロトコルバッファ形式を使用してプロセスデータをディスクに保存します。 このプロトコルを使用するためのソフトウェアライブラリは、ほとんどの一般的な言語に対応しています。

開発中、すべてのCRIU機能は、統合テストシステムによって常に監視されます。 このために、OpenVZおよびVirtuozzo開発プロジェクトから借用した再設計および改善されたフレームワークが使用されます。

CRIUは、OpenVZコードをメインLinuxカーネルに移植するプロジェクトの一環として、Parallelsによって開発されています。



目標



近い将来のプロジェクトの主な目標は、Linux Containers(LXC)の状態を維持および復元する方法を学ぶことです。 これを行うには、受信したがまだ処理されていない信号、ネットワーク名前空間の名前空間(ネットワーク名前空間)、ファイル階層(名前空間のマウント、開発中)を保存および復元する必要があります。



参照資料



en.wikipedia.org/wiki/CRIU

ckpt.wiki.kernel.org/index.php/Main_Page

wiki.openvz.org/Checkpointing_and_live_migration

www.parallels.com

code.google.com/p/protobuf




All Articles