運用における障害対応の基本 - システム障害といかに向き合い、チームとして対処するか


はじめに

  • システム開発をしていると、初期構築フェーズが終わった後に必ず保守・運用フェーズがやってくる。
  • 本番運用をしているシステムで障害が発生した時に、いかに向き合い、対処するかという考え方とアクションをまとめた。
  • これから運用を始めたばかりという方や、障害対応にあまり慣れていない方が対象。

障害とは何か

  • システムにおける障害とはそもそも何か。
  • 非常にざっくり分類すると、一般的には下図の黄色で塗りつぶしたところのどれかに該当すると思う。

  • 何をもって障害とするか、はサービスやユーザーの性質により判断が分かれると思うが、「エンドユーザーがサービスを利用する上で不都合を感じ、かつ、それがサービスプロバイダの想定外の事象であった場合」とすることが多いのではないか。
  • よくある話で、「これ障害だよね?」「いえ、仕様です」という会話が生まれることがある。入力に対して適切な応答を返しているが、そもそもその仕様が間違っていたというケース。こういう時は、必要であれば保守として対応することになると思う。おそらく人類の歴史が続く限りこの議論が無くなることはない。

障害検知(そもそもどうやって障害に気づくか)

  • だいたいにおいて、以下のようなパターン。
  1. 障害検知ツール(newrelic、 zabbixなど)
  2. ベンダーの障害情報
  3. バッチスクリプトなどが失敗した場合に開発者が仕込んでいた通知
  4. エンドユーザーからの通報(あるいは、開発者が自分で気づく)
  • ツールやスクリプトで通知を飛ばす場合は、誰に飛ばすかをきちんと考えて仕込んでおく。
    • スクリプトの開発者にしかメールが届かず、その人が休みで誰も気づかなかった、、ということは避ける。
  • ベンダー(例えば、AWSやherokuのような)の障害情報は必ずウォッチしておく

障害対応フロー

  • 以下のようなフローで進めるとスムーズ。
  1. 障害検知
  2. 直接原因の突き止め
  3. 暫定対応方針の決定
  4. 暫定対応の実施
  5. 根本原因の突き止め
  6. 本格対応の実施
  • 直接原因と暫定対応
    • 暫定対応とは、「数字の計算が明らかにおかしく見える」というような外部から見える障害の原因のことを指す(数値計算ロジックのバグがあった、とか)。
    • この直接原因に対して対応するのが暫定対応。
  • 根本原因と本格対応
    • 根本原因とは、上記の例で言うと、そもそもロジックのバグはなぜ生まれたのか?ということ。テストケースに誤りがあったのか、レビュー体制が良くなかったのか、など。
    • この根本原因に対して対応するのが本格対応。
  • サービス復旧としては4で一応達成されるが、6の本格対応まで実施することで障害対応としては完了する。
  • よくある話として、「障害対応に夢中になってしまい、各フェーズで必要な関係者への連絡が漏れる」ということがあるため、普段から障害発生時のレポートラインや連絡内容を整理しておくと良い。

直接原因と暫定対応

  • 直接原因の突き止めは、主にログが起点となる。
  • このため、そもそもログを適切に出力していることが重要となる。
    • サーバー台数が複数に渡る場合は、ログ確認自体が非常に手間になるため、集約化しておくと良い。
    • スクリプトの実行ログなどは、日時を入れるなど障害発生タイミングがわかるようにし、合わせて適切なメッセージを出すようにしておく。
  • 本番のみで発生すようなバグがある場合は、再現環境をあらかじめ用意しておき、そこで再現するかどうかを検証する。

根本原因と本格対応

  • 根本原因は上述のように、チーム体制やルール、ガイドラインなどが問題となっていることが多い。
  • チームとして議論をし、解決策を模索していく必要がある。

障害票を作り、ナレッジを共有する

  • ここまでにたどってきた以下の項目について整理しておくと、チームとしてナレッジをストックできる。
  • ツールはチームとして使いやすいものであれば良いと思う。
XXシステムにおける◯◯障害 #障害についてのわかりやすいタイトル

発生日/起票者

1. 直接原因
2. 暫定対応
3. 根本原因
4. 本格対応

# まだ対応できていない、究明できていない項目があるときは、対応方針などだけでも書いておく

障害対応に強いチームの作り方

  • 個人的に一番重要だと考えているのはこの点

障害対応に弱い(と思う)チーム

  • 障害が発生したことでチームの雰囲気が悪くなる(あ〜あ、やっちゃった、という空気になる)。
  • マネージャーなどが犯人探しを行う。また、通常時でも、悪い報告に耳を貸そうとしない。
  • 障害対応をとにかく急かす(何ですぐ直らないんだ!となる)。
  • 場当たり的に対処しようとする(好き勝手にメンバーが対応しようとしたりする)。

障害対応に強い(と思う)チーム

  • 障害が発生すると祭りのような状態になる(チームとして事象にあたろうとする)
    • チームとして一丸となってナレッジを持ち寄らないと解決できない場合もある。
    • 常にそうした助け合いの姿勢があるチーム作りをする。
  • 障害が発生するプロセスを究明しようとするが、ミスをした人を責めない。
    • 人が作ったものであれば必ずミスはある。
    • ミスがなぜ起こるのか?を明らかにせずに人を責めても根本的な解決にならない。
  • 実際に対応に当たっている担当者を急かさない
    • 障害を実際に起こすと精神的に動揺する。ミスがミスを生む状況を防ぐため、ある程度の時間枠は決めるが焦らせない。
  • あらかじめ障害発生時の対応フローが用意されている。
    • 障害発生時のレポートライン、対応者などがチームで整理されている。
    • バックアップ取得や再起動作業などがスクリプト化され、メンテされている。
    • ログ出力ルールや出力ポイント、エラー時の通知先などが整理され、徹底されている。

おわりに

  • こう書くと不謹慎に思われるかもしれないが、障害対応は楽しい。
  • 人が作ったものに完璧はない。原因を追究して、対処していくときのチーム一丸となる雰囲気は非常にわくわくする。
  • 失敗から人は学ぶのだから、繰り返し数をこなしていけば良い。