インラインコード
前置き
今回は、カオス実験による気付きと、そこから経た学びを通して、CI/CDパイプラインをどう扱うのか?を扱っていきます。
もしもPod_Aへのインフラ層への障害注入を行い、その結果別のPod_Bに影響が伝搬した時、
仮にもう図のようにパイプライン構造がE2Eで独立したパイプライン構造になってしまっていたらどう対処するのでしょうか?
またインフラ層で集約するようなファンイン構造に戻すべきと考えられますか?
それともパイプラインの構造はこのままであるべきでしょうか?
カオス実験がアーキテクチャ改善のヒントとなる
カオス実験の「失敗」(=Pod_Bへの影響伝搬)は、CI/CDパイプラインの設計が間違っていたことを示すシグナルではありません。
CI/CDパイプライン(理想)と、システムアーキテクチャ(現実)の間に、
意図していない致命的な“矛盾”がある
という、テストだけでは考慮しきれなかったことを発見してくれた、最大の「成功」です。
なので、パイプライン構造はそのままE2Eの構造を維持します。
アンチパターン:パイプラインを「現実」に合わせる
もし、この発見を受けて「ファンイン構造に戻す」という決断をした場合、それは
「現実(=密結合なアーキテクチャ)は変えられないから、
理想(=独立したパイプライン)の方を諦めよう」
という、アーキテクチャの敗北を意味します。
その結果
そのチームは、確実に 独立デプロイ(アジリティ) を失います。
「隠れたインフラ依存」という技術的負債を、公式に「許容」 したことになります。
アーキテクチャは「分散モノリス」のまま固定化されます。
アンチパターンのアナロジー
カオス実験により、パイプラインの方を後退させるというのは、喩えるならば無理やりTDDのテストを通したいから、
「既存のプロダクトコードをテストを通るように設計する」のではなく、
『既存のプロダクトコードを無理やり通すために、テスト自体を変えてしまう』
という最大のアンチパターンに他なりません。
TDDの「テスト」とは?
「Pod_AとPod_Bは独立している」ことを検証する、「独立E2Eパイプライン(とカオス実験)」 です。(あるべき形を表現する)
TDDの「プロダクトコード」とは?
Pod_AとPod_Bがインフラで密結合している、「現在のシステムアーキテクチャ」 です。
「Red(失敗)」の状態
カオス実験が失敗し、「独立している」というテスト(パイプライン)が失敗しました。
「アンチパターン」
『既存のプロダクトコードを無理やり通すために、テスト自体を変えてしまう』
「密結合なアーキテクチャ(プロダクトコード)を無理やり通すために、“独立性”のテスト(E2Eパイプライン)自体を“集約”のテスト(ファンインパイプライン)に変えてしまう」
TDDの「正しい道」
「既存のプロダクトコードをテストを通るように設計する」
「“独立性”のテスト(E2Eパイプライン)をパスできるように、密結合なアーキテクチャ(プロダクトコード)を疎結合にリファクタリングする」
結論
パイプラインを後退させる(ファンインに戻す)ことは、アーキテクチャの根本的な欠陥(密結合)を
「テスト(パイプライン)の方を修正して、見て見ぬふりをする」
という、最も危険な技術的負債の隠蔽です。
よって、開発者やアーキテクチャを編集できる権限を持った者が、勝手にパイプライン構造を無理やりいじるという、暴挙に出ないように、私ならその者にパイプライン構造の編集権限は絶対に付与しません。
正しい対処:パイプラインを「TDDのテスト」として使う
チームが目指しているのは、「独立したE2Eパイプライン」(=真のマイクロサービス)です。
カオス実験の失敗(Red)は、
「プロダクションコード(アーキテクチャ)は、まだそのテスト(独立性)をパスできていませんよ」というTDDの「Red(失敗)」 という明確なシグナルです。
TDDのサイクルに従えば、Redの次に行うのは「テストを削除(=ファンインに戻す)」ことではありません。
「テストをパス(Green)させるために、プロダクションコード(アーキテクチャ)をリファクタリングする」 ことです。
具体的な対処ステップ
では、いくつかのステップに分解して、アーキテクチャテストであるパイプラインを通過できるまでの一連の流れを見てみましょう。
ステップ1:パイプラインを「Red(失敗)」のままにする
目的:安全機構の作動
活動
カオス実験で発見された「隠れた依存関係」が修正されるまで、Pipe-A(あるいはPipe-Bも)の本番デプロイは、このカオス実験の失敗によって自動的にブロックされなければなりません。
ステップ2:根本原因(隠れたインフラ結合)を特定する
目的
なぜPod_Aのインフラ障害がPod_Bに伝搬したのか?明らかにする。
活動
・共有DBのロック
Pod_AがDB障害でロックを掴んだまま停止し、同じDBのテーブルを見ているPod_Bが道連れになった。
・共有キャッシュ(Redis)の枯渇
Pod_Aが依存するRedisが応答不能になり、Pod_Bも同じRedisを使っていたため道連れになった。
・共有メッセージブローカーの詰まり
Pod_A(消費者)がメッセージをAckできず、キューが詰まり、Pod_B(別の消費者)も処理不能になった。
ステップ3:アーキテクチャをリファクタリングする(Greenを目指す)
目的
ステップ2で見つけた、「隠れたインフラ結合」を断ち切る。
活動
(A) レジリエンスパターンの導入
Pod_Bのコードを修正し、Pod_Aと共有しているインフラ(DBやキャッシュ)へのアクセス部分に、サーキットブレーカーや厳格なタイムアウト、バルクヘッド(リソース隔離) を導入し、Pod_A側の障害に「道連れ」にされないようにする。
(B) インフラの完全分離(理想)
より根本的な解決策として、Pod_AとPod_Bが依存するDBやキャッシュを、物理的に別々のインスタンス(Pod)に分離する。
ステップ4:パイプラインを再実行し、「Green」を確認する
目的:修正の検証
活動
アーキテクチャの修正(ステップ3)をコミットし、パイプラインを再実行します。
結果
先程と同じカオス実験(Pod_Aへのインフラ障害注入)が実行されても、Pod_Bは(サーキットブレーカーが作動するなどして)正常に動作し続けます。
これにより、
パイプラインが「Green(成功)」
します。
これで無事に、アーキテクチャが意図しないインフラ結合を引き起こしていない、
パイプライン構造と矛盾のない構造により洗練させたことになります。
結論
独立E2Eパイプラインが「Red(失敗)」になったのは、パイプラインが「現実(密結合なアーキテクチャ)」を正しく検知したからです。
そのシグナルに対して、パイプラインを「後退(ファンイン)」させるのではなく、
アーキテクチャを「前進(疎結合化)」させる
ことこそが、チームが目指す「独立したE2Eパイプライン」という理想のアーキテクチャを、安全に実現するための唯一の道筋です。
