オンコールアラートを設定しようと考えた際に考慮すべき点を自分なりにアンチパターンとしてまとめたなにかです。
ホワイトボックスモニタリングにより得られたメトリクス、ログなどからアラーティングを行う、または併用する環境を想定しています、ブラックボックスモニタリングによるアラート、SLOベースのアラートのみでうまく運用されているサービスにはあてはまらないと考えてます。
参考書籍は色々あり、最後に記載していますが提示されてるプラクティス通りではないものもあります 。自組織、システムにあった設計をしましょう。
システムの監視がまったくありませんみたいな状況であればまずはサービスのURLに対する外形監視からはじめましょう。
言葉の定義
- オンコールアラート:ここではSRE本でいうところのページ、担当エンジニアに電話をかけるなど即座に対応を求めることを目的としたアラート
- runbook:ここでは発生したアラートに対してより詳細な文脈を与え、問題特定のためのステップ、想定される対応方法などを記載したドキュメント
アンチパターン
サービスに対する外形監視が設定されていない
- その他のオンコールアラートを設定する前にまずサービスに対する外形監視を入れましょう
- 監視先はサービスが機能していることを確認できる(機能するために必要なデータベースなどにもアクセスする)エンドポイントを用意し、ロードバランサーで使うヘルスチェックエンドポイントとは分け、dbアクセスなどを伴いある程度のコードパスを通るよう設計しましょう
- よほどの理由がなければ自前運用よりはSaaSを使いましょう、クラウドベンダーの提供するものでも良いです
- 可能であれば複数のロケーションから監視できると良いですが、最低限複数回のチェックがサポートされていれば良いでしょう(一発NGを避ける、後述
- 外形監視によるアラートの通知経路はその他のアラートとは分け、監視システムそのもののダウンによるリスクを分離し相互に補完できるよう設計しましょう
- サービスに対する外形監視が設定できていれば、後述のそれ以外のアラート設定で問題があった場合でもカバーできますし、サービスに問題があった時に見落としてしまう->アラートを厳しく設定しなければならないという欲求を抑えることができます
アラートを受け取って直ちに何かアクションを行う必要がない
- アラートを設定したい理由が「検知をしたい」であればまずは流量に気をつけつつチャットへの通知など情報を伝えるだけでよくオンコールアラートである必要はありません
- 検知してから判断したい、でオンコールアラートを設定してしまうと大半は実際にアクションを行うことなく終わるのでアラート疲れを招きます
- 近いうちにアクションしなければならないが、直ちに行う必要がない(例えばストレージの不足が近い将来に起こる場合など)ケースは運用者が利用しているチケットシステムへ連携、それが難しい場合はチャットにアクションを行うための専用のチャンネルを用してそこに通知するなどすると良いでしょう
- チャット通知を利用する場合、必ずアクションのいる通知とそうでないものを分けるのがおすすめです
- 単に気になる情報を流しているチャンネルと同一のチャンネルを利用すると要アクションな通知が埋もれてしまいます、可能であれば担当者が見落とさないよう明示的な通知にしておくのがよいでしょう
アラートに対応するrunbookが存在しない
- 新規のオンコールアラートを追加する前に必ず対応するrunbookを用意しましょう
- テンプレートが存在しない場合はgitlabのテンプレなど既存のテンプレートを参考に作成しましょう、自組織に合わせて必須項目は少なく設計するのが良いです
- 必須項目が多く、完璧さを求められると記載のためのハードルがあがりrunbook自体の運用が滞る危険性があります
- 最小の項目で追加し改善のサイクルを早く回せるようにする方が良いでしょう
- runbookで完全な復旧手順を目指す必要はありません、エンジニアがオンコールアラートを受けて対応するということは対応にスキルをもったエンジニアの能力が必要であるということで、誰でも実行可能なコマンドの指示で対応できるのであればそれは自動化可能なものです
- 長期的に機能し、詳細すぎず、対応するエンジニアにとって復旧のための調査に必要となる情報が記載されているrunbookを用意しましょう
- 短期的な問題に対するアドホックな対応を記載する場合、そのことをrunbook自体にも明示しておくと良いでしょう
- 問題解決時にアラート自体をなくせる、将来的に内容が役立たなくなる可能性があることがわかります
- 過去に担当したチームメンバーが設定したアラートは消していいのか判断が難しくなるため、そういった文脈を付与するためにも有用です
- 用意したrunbookは必ずアラートとセットで通知できるようにしましょう、アラートのmetadataなどを利用してメッセージに含めるのも良いですし、特定の命名規則に応じて自動でドキュメントにマッピングできるとなお良いです
自動対応可能なアラートである
- runbookの内容が決まりきった復旧手順(特定のプロセスの再起動を行う、インスタンスなどを単純に入れ替えるなど)となる場合それは自動化可能かもしれません
- 自動化というと敷居が高い感じがしますが、例えばAWSであればssm-documentなどを経由してインスタンスで特定のコマンド群を実行するといったことはそれほど難しくありません
- 例えばAWSであればまずrunbookに記載する-> 一連のコマンド群をssm documentで用意して手動実行可能にする->自動実行にする といった段階的なフローで導入していくことができます
- いきなりの自動化は難しくても、まずrunbookに手順を示し、必要に応じて将来的に自動化を行うのも良いでしょう
しきい値を設定するのに十分な情報がない
- しきい値を設定するのに十分なデータが集まっていない状態でオンコールアラートを設定すべきではありません
- いきなりオンコールアラートを設定するのではなくまずはwarningレベルでアラートを設定し、最低でも一ヶ月以上(サービスによっては大きなイベントが一巡するくらいの期間)運用しfalse positiveなアラートが発生していないか確認しましょう
- false positiveが含まれる場合はしきい値を調整し確実にまずいと判断できるものだけを捉えられるよう調整しましょう
一回のNG判定で発報される
- しきい値を超えた/ログが出力されたらいきなりアラートが発報される設定になっている
- 複数回連続して発生したら、一定時間続いたら(prometheusのalertruleにおけるfor: N、CloudWatch AlarmのDatapoints to Alarmなど)という条件を基本として設定しましょう
- 一回のチェックに失敗したら即発報といった設定はクラウドサービス上のインスタンスで一時的にネットワークが不安定になったというだけで深夜にエンジニアを起こすことになり、そういったことは実際のところ結構な頻度で発生します
- 発見が遅くなるのではという不安はもっともですが、深夜にアラートを受けて対応を開始するまでにはそもそも時間がかかりますし、実際のところ即時に発報されたアラートに対して対応者が最初に取るであろうアクションは「継続してるかどうかメトリクスを確認する」になりがちです
- 結局のところ機械的な対応は機械がやる方がぶれがなく、人間に負荷をかけることもありません
追加(のみ)されていくアラートルール
- アラートルールは定期的に見直され、不要なアラートは削除され、しきい値は調整される必要があります
- アラートはなにか問題があった際、とりわけ既存ルールで見落とされたタイミングで追加されていきますが、意図的に機会を作らない限りなかなか減らされることはありません
- アラートルールもメンテナンスコストがかかりますし、多すぎるアラートルールはやはりアラート疲れを招きます
- 定期的なフローにアラートの見直しを含めましょう