Chaos Engineering やっていく宣言

技術部のヨシオリです。

Netflix が Chaos Engineering の論文を公開して 2 年ほど経ちました。
クックパッドは最近、 Chaos Engineering を導入する事を決めました。
この記事ではその背景を紹介したいと思います。

そもそも Chaos Engineering とは

Netflix では Failure Injection Testing として、営業時間中に意図的に障害を起す事をやっていました。Chaos Monkey というインスタンスとサービスを落すものから Chaos Gorilla、Kong という availability zone や region 単位で障害を発生させるものなどです。

その経験から Chaos Engineering というものが提唱されました。
Principles of Chaos Engineeringによれば

Chaos Engineering is the discipline of experimenting on a distributed system in order to build confidence in the system’s capability to withstand turbulent conditions in production.

と定義されています。
意訳すると「本番環境の分散システムが過酷な状況でも耐えれるとの確信を得るために、実験するという取り組み」とかでしょうか?

分散システムはマイクロサービスと置きかえるとイメージしやすいと思います。複数のマイクロサービスが相互に呼び出し、協調して動くシステムでは一つのサービスがクラッシュしただけでシステム全体が壊れるような事になっていてはいけません。そうなると、ユーザーに届けられる価値が減ってしまいビジネス的にも問題です。
もちろんそうならないように作るべきですが、それでも予想不可能な事は起こります。それを知るためにコントロールされた障害を投入し、知見を広げたり、確信を得たりするのです。

そのための実験は下記のステップで進めます。

  1. 正常な振る舞いをしているかどうかを測定可能な値として定義する。
  2. この正常な状態が通常時と障害エミュレート時の両方で継続することを仮定する。
  3. サーバクラッシュ、ディスク異常、ネットワークエラーなどの現実世界で起こりえる障害をエミュレートする。
  4. 1で定義した値を通常時と障害エミュレート時で比較し検証していく。

詳しくは上記論文やリンク先を見ていただくとして、凄くザックリと纏めてしまうと、
システムにコントロールされた障害をエミューレートし、それでも壊れない事を検証していく
と、思ってもらえれば良いかと思います。
元々、昔から似たような事をやっているサービスはありましたが Netflix がそこに Chaos Engineering と名前と付け原則などをわかりやすく纏めた感じですね。

必要になった背景

クックパッドでは 2014 年ころからマイクロサービスに取り組んで来ました。

そして個々の Web アプリケーションはコンテナ技術で仮想化し、コンテナオーケストレーションツールとして ECS を使い運用しています。

また、サービス間の通信に関してもサービスメッシュの導入などを行なっています。

その結果、今ではチーム数も増加し、開発規模も大きくなっています。結果として( 管理画面を提供するサービスなどを除いても) 大小 80 個近くのサービスがそれぞれお互いに緩くではありますが連携し動いています(僕も数を調べてビックリしました)。

さすがにこれだけのサービスが連携して動いているとどこかで発生した障害がどこまで影響するのか把握するのは容易ではありません。
A というモバイルアプリが叩いている B という API の裏で通信している C が必要としているデータ取得のための D のレスポンス時間が遅くなって、結果として A の応答が悪くなったのだが、原因が D だとは思っていなかった……的な事も発生します。

何故やるのか

上記ブログのマイクロサービス導入背景にもありますが、昔のようにひとつの巨大なアプリケーションを運用するようなスタイルではプロダクト開発の規模の拡大やスピードに限界があり、マイクロサービスアーキテクチャを採用するようになりました。分散システムとして Web サービスを実装する事により単一の複雑なアプリケーションからは開放されましたが個々のサービス間の連携は複雑になりました。

Chaos Engineering の導入によってサービスの耐障害性に自信を持てるようにします。日常的に障害をエミュレートする事によってサービスの耐障害性が高いことを開発者に要求します。
ソフトウェアテストなどの文脈では良く言われますが、不具合は発見が遅れれば遅れるほど、その不具合を修正するコストはかさむことになります。
可用性の高いシステムを作るために、不具合を早く発見し改善していくために Chaos Engineering を導入していきます。

付随して考えている事

人は自分が想像出来るものにしか対処出来ません。バグというのは大体が想定外の入力によって発生します。そこでもっと想像力を働かせろ的な精神論を言っていても良くはなりません。Chaos Engineering のように実際にそういった状況を作る事が大事だと思っています。
例えばクックパッドでは各サービスがどんどん AWS の Spot インスタンスで動くように移行していっています。これはサーバはいつ落ちても良いようにしておかなくてはいけないし、バックグラウンドジョブは落ちたら再実行出来るようにしておかなくてはいけない事を開発者に強制します。
でも、それらは実は Spot インスタンスで動くからやらなければいけないものではありません。耐障害性の高いシステムを作るためにはやらなければいけない事を Spot インスタンスの環境にする事によって強制するようになっただけです。
さきほども書いたように人は自分が想像出来るものにしか対処出来ません。Chad Fowler が Immutable Infrastructure を提唱したけれども、開発者がそれを真に実行出来るようになったのは Docker という環境のおかげというのと同じです。

最後に

現在、クックパッドでは Hako や ECS を使ったコンテナ環境の整備が進み、サービスメッシュの導入によりサービス間の通信を集中管理出来るようになりました。これにより、Envoy proxy を利用してサービス間通信で障害をエミュレートしたり、それらの設定を hako で行えるようになったりと環境は整いました。
まだまだクックパッドのマイクロサービス群の正常な状態( steady-state )をどう定義していくかなどやらなければいけない事は色々あります。
個人的にはこの規模のマイクロサービス群を扱っていく環境は国内ではそんなに多くはなく大変面白い環境だと思ってます。
クックパッドでは一緒に Chaos Engineering を導入していく仲間を募集しています
このエントリを読んでご興味をお持ちいただけた方は、ぜひともご応募ください。