ポストモーテム
ポストモーテム(事後検証)は、本番環境で発生した重大インシデントについて、問題解決後にその原因分析や対応内容のふりかえりなどを行い、再び同じ問題を起こさないために、もし問題が発生しても速く対応できたり、影響を最小限に抑えたりするために、アクションプランを作って組織的な改善につなげるための活動である。昔から行われていることではあるが、SRE文化の形成とともに、外部向けよりも内部向け、即時性、組織的な学習がより強調され、体系だった手法も公開されるようになってきている。
即時性
ポストモーテムは、インシデントの経験がみんなの心に新鮮なうちにやった方が良い。
Operations Anti-Patterns, DevOps Solutions の書籍では24h以内にポストモーテムを実施せよとしている。
PagerDuty社でも5日以内には ポストモーテムが実行されている。 ポストモーテム集
GitHubにGoogleやMicrosoftなどポストモーテムを公表しているものへのリンク集がある。
ポストモーテムのテンプレート
障害サマリ
障害のサマリを短い文で記述する。重大性がどれくらいで、何故発生し、どれくらい影響が続いたかを含む。
きっかけ
この障害につながった状況を記述する。例えば、潜在的なバグを混入させた以前のコード変更など。
事象
期待と異なる動作を記述する。異常な状態を示す関連するグラフやデータのスクリーンショットがあれば添付する。
影響
障害発生中に内部・外部問わずシステム利用者に与えた影響を記述する。何件のサポートが発生したかを含む。
対応
誰が、いつ、どのように対応したか? 対応の遅れや障壁があったか?
検知
障害にいつ、どうやって気づいたか?
リカバリ
サービスをいつどのように復旧させたかを記述する。どうやって、影響を緩和する方法に辿り着いたか?
タイムライン
障害原因の混入~障害の発生~対処完了までを時系列に記述する。
Five Whys
根本原因にたどりつくための一連の問い。
根本原因
根本原因は何だったのか?を記述する。同種の障害を再発させないためには、この点を変えなくてはならない。
根本原因は「人」に起因するものではなく、
バックログチェック
バックログの中に、これを防げた、あるいは影響を大幅に軽減できたものはあるだろうか? もしあるなら、なぜそれをしなかったのか? を記述する。
ここで正直に評価することで、優先度やリスクに関する過去の判断が明確になる。
再現性
この障害(同じ根本原因)は、以前にも発生したことがあるか? もしそうであれば、なぜそれが再び発生したのか?
学んだこと
この障害から学んだことは何か?
上手く行ったことはあるか? どこに改善のチャンスがあるか?
改善アクション
アクションアイテムを列挙する。
誰がいつまでに、どのようなアクションをとるか?
ポストモーテム記述例
※ この例では省いてありますが「事実」に関しては、わかっていればタイムスタンプも入れるようにする
障害サマリ: トラフィックの多い時間帯にTomcatが無反応になり、システム全体が停止した。
きっかけ: Webサーバ-APサーバそれぞれ2台構成に変えたが、Tomcatのserver.xmlの設定値は見直すことなく以前のままだった。
事象
Tomcatの前にはApacheを配置しており、mod_jkによって接続している
Apache、Tomcatは別サーバとなっており、それぞれ2台構成である
トラフィックが多いときに無応答となる
問題が発生しているときに内部セグメントから直接Tomcatにアクセスすると、応答がある
DBサーバで取得しているスロークエリーのログには何も出力されていない
CPUやメモリ使用率、GC(ガベージ・コレクション)のログは整理済み。そのほかのログファイルは大量の出力があるため、現在整理を行っている
影響
本事象発生後は、全ユーザがページを開くとLoading状態のブラウザ側のタイムアウトまで待たされ、システムの全機能が利用不可となる。
対応
原因判明までは無反応になったかを、インシデント対応者が人力で監視し、検知し次第Tomcatを再起動した。
原因判明後は、Tomcatの設定を見直して(maxThreadsを350に設定)再起動し、事象が再発しないことを確認
検知
ユーザからの問い合わせで判明。以降再起動後、
リカバリ
タイムライン
(略)
Five Whys
maxThreadsの設定値が不適切だった。
→ サーバ構成が変更されたのに、設定値を見直さなかった
→ サーバ構成を変更した際に、やらなくてはいけないことが明示されていない
根本原因
サーバ構成変更時の手順不足
バックログチェック
プロセスの死活監視だけでなく、外形監視をやろうというIssueはあがっていたが、特別なモニタリングツールが必要だという思い込みと、その選定作業にあてれる人がいないという理由から「保留」にしてしまっていた。
再現性
本事象は初めてのことだが、以前もプロセスは活きているが、サーバが応答を返さないということはあった。
Web - APサーバ間のタイムアウト値を設定すれば、ずっと応答を返さない状態になることは防げるね、という検証はしていた。
改善アクション
【P1】 期限: x月x日 外形監視を追加する。
【P0】 期限: x月x日 サーバ構成変更時の設定値見直しと本番相当構成でのテスト(負荷テストを含む)をルールとして明文化する。
【P1】 期限: x月x日 Web-APサーバ間のタイムアウトを設定する(30s; サーバの処理時間のログを確認し、通常処理に影響を与えない範囲の設定値)。
アクションアイテム
アクションアイテムの分類
アクションアイテムは以下の項目に分類できる。洗い出すときに、それぞれの軸で考えてみよう。
障害の調査
根本原因を突き止めるために、さらなる調査が必要ならば、それをアクションアイテムとする。
例: ログを分析する、リクエストパスを図にしてみる、ヒープダンプをレビューする
障害影響の緩和策
今回の発生した障害の影響を、緩和する手立てがないか?
例: ロールバック、影響を受けたユーザとのコミュニケーション
被害の修復
今回の障害による直接的な被害や巻き添えをどのように解決するか?
例: データのリストア、マシンの修理
今後の障害の検知
同種の障害が起きたときに、より速く正確に検知するためにできることはないか?
例: 監視、アラート、入出力の妥当性チェック
今後の障害発生時の緩和策
万が一同種の障害が発生した際に、影響を最小限に抑えるための対策
例: グレースフルデグラデーション、隔壁、タイムアウト
今後の障害発生の防止
同種の障害を再び発生させないためにできること
例: コードベースの安定性改善、ユニットテストの強化、入力チェックの強化、変更のプロビジョニング
アクションアイテムを記述するときの注意
以下の3点を満たすようにアクションアイテムは記述する。
アクション可能であること
【悪い例】このシナリオのために監視についてしたべる
【良い例】このサービスで、リクエストの1%以上エラーが発生するすべてのケースを警告あがるようにする
具体的であること
【悪い例】障害の原因となった問題を解決する
【良い例】ユーザの住所入力フォームにおいて、不正な郵便番号が入力されても大丈夫なようにハンドリングする
完了が判定可能であること
【悪い例】エンジニアは最新のデータベーススキーマを参照していることを、プログラム修正前にチェックする。
【良い例】スキーマ定義をモジュール化し、依存ライブラリとしてバージョン管理し、最新の定義が自動的に参照されるようにする。
アクションアイテムの優先度
以下の基準にそって、アクションアイテムに優先度をつける。
P0
このアクションアイテムが解決されないと、インシデントが未解決のままで再発リスクが高い。
このアクションアイテムの解決は、根本原因に直接的な対処になる
このアクションアイテムを実施すれば、再発を完全に防げたり、発生時の影響を無視できるレベルまで大きく低減できたりする。
P1
このアクションアイテムが解決されないと、インシデントが未解決のままで再発リスクがそれなりにある。
このアクションアイテムは、根本原因に直接的な対処になる
このアクションアイテムを実施すれば、再発時の影響を大きく緩和したり、再発防止に大きく寄与したりする。
P2
このアクションアイテムが解決されなくても、再発リスクはそれほど高くはない。
このアクションアイテムは、再発を表面的に軽減するだけ、または根本原因ではなく周辺の原因に対処するものである。
P3
このアクションアイテムが解決されなくても、再発リスクはほとんどない。
個人の責任を追求しない
個人の責任を追求しないポストモーテム(Blameless Postmortem) は、ポストモーテムに関する記事でたいてい言及されている。
特にFive Whysなどで根本原因を探る際には、「人」ではなく「仕組み」にフォーカスし、そこにたどり着くまで原因を追求することにしよう。