記事一覧

毎晩1,000回のクラッシュでAGELAIOSの障害封じ込めを検証する

AGELAIOS

エンジニアリング

連続する分離境界の内側に障害モジュールを封じ込め、戦術ノードの他の機能が稼働を続ける様子。

戦術指揮ノードでは、1件のソフトウェア障害が、それを引き起こしたプロセスをはるかに超える影響を及ぼすことがあります。地図モジュールがメモリを使い果たす。サードパーティーサービスが再起動ループに陥る。センサーアダプターがネットワークインターフェースを解放せず停止する。プラットフォームがこれらを封じ込められなければ、1つの不良コンポーネントが他のすべてのサービスを劣化させ、最終的には共通作戦状況図を損ないます。

AGELAIOSは、このリスクを約束ではなく工学要件として扱います。モジュールの障害は、割り当てられた境界内に留まらなければなりません。監視機構は障害を検出し、リソースを回収し、設定された再起動または失効ポリシーを適用します。その間、無関係なモジュールと共通作戦状況図は利用可能であり続けなければなりません。

これが障害波及防止要件です。参照用の継続的インテグレーション環境では、毎晩、制御された障害によってこの要件を試します。目を引く数値は1,000回のクラッシュと再起動ですが、数値そのものが証拠ではありません。キャンペーンが何を測定するか、障害をどう再現するか、意図的に壊した構成をテストが検出できるかによって、証拠としての価値が決まります。

再現できる判断から始める

復旧は監視機構から始まります。このコンポーネントは、モジュールをいつ起動し、いつ再起動を許可し、いつ遅延を増やし、反復障害をいつ失効へ移行すべきかを判断します。

AGELAIOSの中核では、これらの判断を純粋な状態機械として表現します。現在状態とイベントを受け取り、新しい状態とアクション一覧を返します。システムクロックを直接参照せず、ソケットを開かず、ファイルシステムも変更しません。時間さえ明示的なイベントとしてモデルに入ります。

この設計には2つの実務上の利点があります。

1つ目は決定性です。同じ初期状態に同じイベントを入力すれば、監視機構は同じ判断をしなければなりません。したがって、短時間の連続クラッシュ、重複するタイムアウト、復旧中の失効といったシーケンスを、メモリ上で高速かつ反復的に試験できます。

2つ目は再現性です。テストキャンペーンで予期しない判断が見つかった場合、該当するイベントとタイミングを記録し、回帰テストとして再生できます。難しいシーケンスをログで説明するだけでも、偶然の再発を待つだけでもありません。プロジェクトが保持できる実行可能なケースになります。

このレベルの試験は必要ですが、十分ではありません。状態機械は判断を検証できても、解放されなかったマウントポイント、孤立したcgroup、突然終了したプロセスが残した仮想インターフェースを検出できません。こうした障害は、ソフトウェアが実際の運用環境に接したときに初めて現れます。そこからカオスキャンペーンが始まります。

Chaos v0:小さなリークを見逃せない大きさにする

最初のキャンペーンは、基本的なモジュールライフサイクルに焦点を当てます。エミュレートされたx86-64およびARM64ノード上で、ハーネスが実際のモジュールプロセスを起動し、予告なく終了させます。モジュールには正常終了の猶予も、自身を後処理する機会も与えません。

その後、監視機構は次の復旧手順を正確に完了しなければなりません。

  1. 終了を検出する。
  2. モジュールの状態を分類する。
  3. そのインスタンスに関連するリソースを回収する。
  4. モジュールの再起動ポリシーを適用する。
  5. ノードを定義済みの定常状態へ戻す。

継続的インテグレーションのキャンペーンは、このシーケンスを1,000回繰り返します。実行中は2つの不変条件を検証します。

無関係なサービスが利用可能であり続けること。 ハーネスは、ノード上の他のサービスと共通作戦状況図を継続的にプローブします。復旧操作がプラットフォームの他の部分を妨げるなら、モジュール単体が復旧しても不十分です。

リソース一覧が基準状態へ戻ること。 キャンペーンの前後で、プロセス、マウントポイント、仮想ネットワークインターフェース、cgroupを棚卸しします。最終一覧は初期一覧と一致しなければなりません。

これが、キャンペーンを1,000サイクル実行する理由です。1,000件の障害ですべての運用条件を代表できると示唆するものではありません。反復によって、累積する欠陥が増幅されます。再起動ごとにオブジェクトを1つ漏らす障害は、単独試験では無害に見えても、長いシーケンスの後には明白になります。

Chaos v1:並行負荷の下で復旧する

実際のインシデントが都合のよい順序で到来することはほとんどありません。電源の不安定、共通依存先、不良更新によって、同じ時間帯に複数のモジュールが影響を受けることがあります。先行障害の復旧中に、新たな障害が重なる可能性もあります。

Chaos v1は、その圧力を再現します。ノードに16個のモジュールを配置し、ハーネスが無作為な部分集合を同時に強制終了します。一部の障害は、それ以前の再起動がまだ進行中に発生します。この組み合わせにより、イベントキュー、ロック境界、リソース会計、再起動の抑制を並行状態で試験します。

成功は、単に生き残ることではなく収束することとして定義されます。障害注入が止まった後、すべてのモジュールは、定められた時間内に、ポリシーで許可された状態、すなわち稼働中または意図的な停止へ到達しなければなりません。さらに、Chaos v0と同じリソース一覧の不変条件も満たす必要があります。

各実行では乱数シードを記録します。特定の障害ストームが競合状態や予期しない遷移を露出させた場合、確率的な再発を待たずに同じシーケンスを再現できます。

成功するテストには、確実に失敗させる方法が必要

自動テストは、意味のある対象を実際には試していなくても成功することがあります。障害注入器が誤ったプロセスを対象にしているかもしれません。ヘルスチェックが誤ったエンドポイントを照会しているかもしれません。収集そのものに失敗しているのに、空の一覧同士が等しいと判定されるかもしれません。

そのため、各カオスキャンペーンにはネガティブコントロールを含めます。分離保護を1つ取り除いた、意図的に弱い構成でハーネスを実行し、障害が通常の境界を越えることを期待します。この実行は失敗しなければなりません。

弱い構成が成功すれば、キャンペーンは無効です。その結果は、ハーネスが検出すると主張する欠陥を検出できないことを示します。この対照試験によってテストが無謬になるわけではありませんが、成功のみを報告できるシーケンスより、成功したキャンペーンの証拠価値を大きく高めます。

封じ込めは境界の体系である

単一の仕組みで障害波及防止全体を実現することはできません。AGELAIOSは複数の制御を組み合わせ、モジュールとリスクに応じて実行プロファイルを選択します。

  • Linux namespacesは、プロセス、マウントポイント、ネットワークリソース、識別子について、モジュールに制限された視界を与えます [2]。モジュールが観測し、影響を与えられる範囲を狭めます。
  • Cgroupsは、CPU、メモリ、プロセス数、入出力に明示的な上限を設けます [3]。暴走するワークロードは、ノードを無制限に消費するのではなく、自身の予算内に制約されます。
  • Seccompは、モジュールが使用できるシステムコールを制限します [4]。許可するカーネルインターフェースを減らすことで、障害または侵害されたコードが実行できる操作も減らします。
  • MicroVMsは、より強い分離を必要とするプロファイルにハードウェア仮想化境界を提供し、Firecrackerなどのプロジェクトが示した軽量仮想マシンモデルに従います [5]。
  • WASIは、WebAssemblyモジュールに明示的なケイパビリティモデルを適用します [6]。ファイル、ネットワーク、クロックへのアクセスは、暗黙に与えられるのではなく明示的に付与されます。

これらは、すべてのワークロードに同一に適用する5層として提示するものではありません。Namespaces、cgroups、seccompはLinux分離プロファイルを構成します。MicroVMとWASIの実行は、異なるモジュール種別と保証要件に対応します。運用上重要なのは、選択した境界が明示され、強制され、該当するテストキャンペーンに含まれることです。

ネガティブコントロールは、このアーキテクチャを観測可能な挙動へ結び付けます。保護を取り除いたなら、試験結果が変わらなければなりません。そうでなければ、その保護は図の中にしか存在しません。

評価者が結論できることと、試験範囲外に残ること

キャンペーンは、定義された範囲について再現可能な証拠を提供します。指定されたモジュール構成と不変条件の下、試験対象のエミュレート済みアーキテクチャで、注入した障害に参照実装がどう応答するかを示します。考えられるすべての障害を封じ込められると証明するものでも、対象ハードウェア上の試験や配備固有ポリシーの評価に代わるものでもありません。

本格的な調達や統合判断では、この境界が重要です。「プラットフォームはレジリエントである」という広い主張を、検証可能な問いへ変えられます。

  • どの障害を注入するのか。
  • どのサービスが利用可能であり続けなければならないのか。
  • どのリソースを棚卸しするのか。
  • ノードはどの程度の時間で収束しなければならないのか。
  • 失敗した実行を再現できるか。
  • ハーネスは既知の不良構成を拒否するか。

公開時点で、Chaos v0とv1は参照リポジトリ内の他のスイートと並行して実行されており、9本の継続的インテグレーションパイプライン全体で約930件の自動テストが報告されています。ハーネス、不変条件、ログは、検査して再実行できるようになっています。産業評価者は、自身のモジュールとポリシーを使って同じシナリオを実行し、その結果を保証記録の一部として保持できます。

エミュレータのドキュメントは、単一障害を注入するための取り組みやすい出発点です。完全なキャンペーンでは、この方法を耐久試験と並行障害ストームへ拡張します。

したがって、AGELAIOSにとって障害波及防止は、単なる機能説明ではありません。観測可能な受入基準、再現可能なキャンペーン、そしてキャンペーン自体を試すために設計された対照試験を持つ要件です。レジリエントな戦術プラットフォームは、この水準の証拠で評価されるべきです。

参考文献

  1. Principles of Chaos Engineering, “Principles of Chaos Engineering”, 2019.
  2. man7.org, “namespaces(7), Linux manual page”.
  3. man7.org, “cgroups(7), Linux manual page”.
  4. The Linux Kernel documentation, “Seccomp BPF”.
  5. Firecracker, “Secure and fast microVMs for serverless computing”.
  6. WASI, “WebAssembly System Interface”.
  7. A. Basiri et al., “Chaos Engineering”, IEEE Software, vol. 33, no. 3, 2016.