🐕

システム障害対応の歯痒さ

2023/08/06に公開

この記事の目的

今件の障害対応は、自分たちのシステムだけでなく外部起因も含んでいます。
そこでうまくいかなかったことを振り返るため、記事にしています。

障害対応は未知かつ非計画的なものなので、突然やってきます。
ただ、対応とか育成する。といったことは不可能なわけではなくて、
実際は検知してから復旧するまでに間のノウハウみたいなものはあって、
体制の組み方・報告の仕方、プロセスごとの必要なポイントがあるので、
ここを抑えるだけで、インシデントコマンダーはできます。

障害対応の辛いなと思っている点

  • 振り返りが責任追求になる点
    • 障害対応の力をつけていきたいのに、なぜそうしたのか?なぜやらなかったのか?のかを詰められても辛いんですよね。
  • 障害対応しても感謝されない
    • なぜ起きたか?いつ終わるのか?を説明しないといけないので感謝されないので進んで対応する気がなくなる

システム障害の漏れ

連絡漏れ : 連絡網がない、連絡の基準がない
影響調査漏れ : 自分たちのシステム担当外の知識不足
作業漏れ : 手順書のミス、手順通り実行していない
確認漏れ : 全機能の確認漏れ

発生時に何をすべきか

障害発生時になにをするべきなのか?

  1. 情報収集

  2. 原因の調査

  3. 影響範囲の調査

  4. 対策の検討と実施

  5. リカバリー

  6. 情報収集
    原因の特定につなげるための情報を集めます。2.原因の調査 と並行して行うこともあるかと思います。

場合によってはここはほとんど不要な場合もあります。
(発生する箇所や内容が明確な場合とか)

なかなか再現パターンが掴めない場合やバグが入り込んでから発覚までに時間が経ってそうな場合は特にここが重要になってきます。

いつ起きたのか?
どんなことが起きたのか?
類似のデータで同じことが起きているデータはないか?
できる限りたくさん情報を集めましょう。

  1. 原因の調査
    ここが最も重要な作業です。
    ここで間違うと以降の作業が全て無駄になります。

本番で動いているアプリと同じコードの環境で実施します。

1.情報収集 で集めた情報を元にまずは調査している環境で再現させます。
再現さえすればあとはデバッグなりしながら原因の特定ができます。

ここで重要になるのが
その原因で本当に間違いないのか?
他に原因となるバグが潜んでいる可能性はないか?
の検証です。

じゃあどうやって見つけた原因が正しいと判断するのか?ですが、
1.情報収集 で集めた情報全てに対してその原因で説明ができるかどうか?だと思います。

全ての説明の辻褄があえばほぼ間違いないと判断できると思います。

  1. 影響範囲の調査
    次は影響範囲を調査します。
    原因がわかると、すぐにコードをどう修正するか(対策)を考えてしまいがちですが、
    この影響範囲によって対策が変わるためまず影響範囲を調べます。

具体的には応急処置が必要かどうかが変わってきます。
毎分何百件も不具合データが新たに生み出される
画面が動かず業務が止まってしまう
などのような場合はスピードを優先した対策を打つ必要があります。

  1. 対策の検討と実施
    影響範囲によっていつまでに何をやるべきかを検討します。
    前述したようにスピードを優先する必要がある場合は、
    段階的に対策を打っていく必要があります。

  2. リカバリー
    ここは特筆すべきことはないですが、
    データが不整合な状態になってしてしまっている場合はあるべき状態に戻しましょう。

対応が終わったら
起きてしまったものは仕方がないので、
次に同じことが起こらないようにするために、
障害対応が一段落したら振り返りをしましょう。

なぜ起こったのか
気付けるポイントはどこにあったのか
どうすれば防げたのか
などいろんな観点で分析して次に繋げましょう。

個人にフォーカスすることだと思っています。プロジェクトとして、チームとしての改善策を考えましょう。

本番対応の実行

  • やることを書き出してチェックリストにする
  • 実際に行う本番操作
  • 障害が解消されたことの検証
  • 他に影響は出ていないかの検証 など
  • 可能であれば、検証環境でそのチェックリストの内容を実行して練習する
  • 本番対応を入れることを周知する
  • チェックリストの内容は一つずつ実行する
  • 絶対に一人でやらない/ダブルチェックする
  • 想定外のことが起こったら一旦対応をやめる/慌ててリカバーしようとしない
  • 障害が解決し、他に悪影響が出ていないことがわかれば、とりあえ障害対応は完了です。

おつかれ様でした✋

恒久対応をする

さて、ここまでくればもうシステムは正常に動いています。
しかし、障害対応はコレで終わりではありません。
とはいえ本番対応で疲弊しているとおもうので、翌日以降でもここは問題ないです。
「障害対応モード」から「通常モード」に戻してからでいいと思います。

  • 後片付けをしよう
  • 暫定対応が終わったあと、そこに残されたものは本来想定された仕様や設計とは異なるものになっています。
  • それを本来あるべきものに寄せていきましょう。
  • それでも、アラートが鳴り止まない暫定対応の前よりはずっと多いはずです。
  • この時間を作るために暫定対応というの急いでやったのです。いつものやり方で、プロダクトをあるべき姿に戻していきましょう。
  • 再発防止策を考えよう
  • 後片付けと並行して、「同じことを繰り返さない方法」、すなわち再発防止策を考えましょう。

ここでのポイントは、その方法は 個人の努力に属するものであってはならない ということです。
もっと注意する / 担当者を罰する などは再発防止策ではないです。

  • バグの見落としが原因であれば、適切な検証フローの追加する。
  • 仕様の不整合であれば、適切な調査や保守計画を敷き直す。
  • エンジニアが勉強不足でよくわからないコードを本番に入れたことが原因なら、コードをレビューせずに本番に入れる体制をつくる。

再発防止策というのはそういったものです。「現在の人員が変わらなくても結果を出す」方法で解決策を考えましょう。
自分のミスが原因だとなかなか言いづらいこともあるので、再発防止策はチームで相談して行うほうが望ましいです。
(ビジネス上あまり問題がない障害の場合、「再発を許容する」という選択肢もあるので)

障害対応振り返りの進め方

障害対応が発生した時に
障害対応の全体指示をする人
バグ修正対応をする人
調査対応をする人
調査状況のサマリをドキュメントにまとめる人
という即席チームを組んで障害対応を進めることをおすすめします
なので、障害対応後は 障害対応の時に作ったドキュメントを読む事で障害発覚から修正対応までの時系列や暫定対応・恒久対応を知る事が出来る状態になっています。

ドキュメントを読むことで後から障害対応に関わってくれた方はそれを見れば現状を把握する事が出来ますし、調査対応・バグ修正対応をする人は コミュニケーションを全体指示の人に任せる事によって自分の作業にしっかり集中してもらう事が出来ます。
全体指示の人がいる事で障害の復旧に向けて即席チームの方が皆何かしらの障害復旧に向けて作業出来る状態を作る事も出来る体制というのが意図です。

振り返りはこのドキュメントをチームで読む所から始めて、
振り返りで出ていた課題としては、バグ修正や全体指示を出している人がどういう思考回路でバグの特定に至ったかどうかが把握する事が難しかったという課題があったので、 どういう風に考えればこの結論を得る事が出来るか を可能な限り言語化しながら進めていきました。

例えば、「エラーが発生したら A, B, C, D の原因が考えられそう、このテーブルにSQLを投げてデータがなければ、少なくともDの選択肢は消える」といった具合です。特に障害対応時は「仮説を立てて、それを証明出来るような事実を集めていき、原因の確度を高めていくと良い」といったような障害対応全般的に使えるようなノウハウも議論の中で得る事も出来ます。

1.調べた内容はすべてメモをとろう
「わかったこと」はもちろん「調べたけど意味がなかった」ことも、調べたことは全部メモしましょう。
「調べたけど効果がなかった」という情報は、後の調査の役に立つことが多いです。
「システムログには障害の原因が特定できるログが出ていなかった」という情報があれば、「障害の原因をすぐに特定することは困難である」という事が判断できるかもしれません。
暫定対応は時間との勝負です。障害の正確な原因が判明するまで、暫定対応の実行を待てないかもしれません。
「今はわからない」という情報は、大切な情報の一つです。

2.様子見の暫定対応という選択肢がある
先の例のようなリリース直後の障害の場合、「一旦システム旧バージョンにロールバックして様子を見る」ということをまず試すと思います。
この方針は「リリースが原因でなかった場合、システムの問題が解決しない」というリスクをはらんでいます。
しかし、その場合でも「リリースは障害の原因ではない」という情報が得られます。今回のリリースされたコード以外の原因を調査すれば良くなり、障害の解決に向けて大きく前に進みます。
発生するリスクが許容できる場合、「解決策である確率が高い暫定対応をとりあえず入れてみる」というのは、強力な選択肢です。

3.必要なら意思決定をしよう
障害の規模や原因によっては、運用担当者だけでは有効な暫定対応が取れないことがあります。
うまく意思決定者を巻き込みましょう。

1.意思決定者でないと取れない選択肢が必要なケース
これは「強い権限を持った人でないと下せない決断が最適解であるケースがあるため」です。
わかりやすい例で言うと「大規模なセキュリティインシデントが発生した場合、システムをすべて一時的に停止する」が暫定対応として最も有効なものになります。
この決断は、運用担当者の独断では下すことができないことが多いでしょう。

2.意思決定者のほうが判断に使う情報を多く持っているケース
暫定対応では「今見つかっている選択肢の中で、もっとも効率がよさそうな暫定対応」を選ぶ必要があります。
持っている情報の多い意思決定者でないと見えない影響や、懸念事項があるケースです。
「リリース後の障害で、ロールバックすればすぐに動くことがわかっている」状態でも、
「明日までに正常稼働していないと会社が潰れる」みたいな状態であれば、
「暫定対応は入れずに原因を調査する」というのが最適解になるでしょう。

最後に

本番障害というと精神的ダメージが大きいですが、運用や開発プロセスなど改善点が見つかるタイミングでもあるため、
起こってしまっても悲観的にならず、チームとして前進する策を改めて考える機会と捉えましょう。

本番障害は残念ながらどんなサービスでも起こります。
起きたときにいかに上手く対応ができるか / いかに上手く対応させることができるかが、
エンジニアのの腕の見せ所なのかなと思います。

慎重に、でも臆せずやっていきましょう。

最後までお読み頂きありがとうございました。

Discussion