TT Lab
はじめる
学ぶ 学習パス コース

CNPE — クラウドネイティブプラットフォームエンジニア

発火したアラートと届いた通知を区別する

TT Labで続きを見る

一言でいうと

Prometheusのfiring、Alertmanagerの受信、Webhookの到着、業務の復旧は、別々の証拠です。アラート名が同じでも、別のPodの復旧を、今回の障害の復旧として数えてはいけません。

なぜ必要なのか

払い出しプラットフォームのルールを、ようやくロードしました。今度は、Prometheusがfiringを示します。運用者は「これでアラートは正常だ」とレポートを閉じましたが、通知サーバーにはリクエストが来ませんでした。PrometheusからAlertmanagerへ送る構成がなかったからです。接続を直すと、今度はAlertmanager APIにアラートができました。それでも、Webhookには何も届きませんでした。選択されたreceiverが、実際の送信先を持たない空の受信構成だったのです。

前の境界で成功した根拠で、後ろの境界まで承認する習慣は、デプロイでも、アラートでも、同じように問題を生みます。今回は、障害をもっと大きくしたり、しきい値を下げたりする必要はありません。アラートが最後に確認された位置と、最初に消えた位置の間を調べることが、先です。

どう動くのか

ルールの式が、あるラベルの集合に対して結果を出すと、その対象のアラートが有効な状態になります。forを指定したなら、条件が評価のたびに続くかを待ってから、firingに移ります。したがって、for: 10sは、単にインストールコマンドのあと10秒を測るという意味ではありません。最初に有効な評価がいつあったかも影響します。pendingとfiringの関係は、Prometheusルールのドキュメントを参照してください。

PrometheusからAlertmanagerへの接続と、Alertmanagerから実際の受信者への通知は、別々に設定します。Alertmanagerは、グルーピング、抑制、サイレンスの処理と、送信を担当します。この区別は、公式アラート概要に出ています。ラボでは、外部メッセンジャーの代わりに、個人VM内のHTTP Webhookを使って、実際のリクエストが入ってきたかを確認します。ツールの設定画面や成功メッセージではなく、受信したリクエストの内容を見ます。

診断の順序を、問いとして書いてみると、次のようになります。

最後に確認したこと まだないもの 優先して調べる境界
ルールが保存された 実行中のインスタンスのルールグループ 選択範囲と構成の反映
Prometheusがfiring Alertmanagerの該当の対象 接続・検出の権限・アクセス経路
Alertmanagerが受信 Webhookのリクエスト route・receiver・送信の失敗
Webhookにfiringが到着 同じ対象の復旧と業務の成功 依存関係の復旧・新しい評価・復旧の送信

受信者がなければ、空のreceiverも有効な構成でありえます。文法上正しい構成が、業務上望む送信を実行するかどうかは、別にテストする必要があります。Secretを使うときは、名前と内部のキーが、利用者が期待する契約と合っている必要があります。このラボの構成には秘密の値はありませんが、実際にAPIキーやパスワードを入れる場合は、ソース・スクリーンショット・観測記録にコピーしません。

現場での姿

準備実験で、アプリを新しいPodに置き換えたあと、同じ障害をもう一度作りました。Webhookの1つのグループの中に、新しいPodのfiringと、以前のPodのresolvedが一緒に入ってきました。アラート名とlabラベルは同じでした。「resolvedが1つでもあれば復旧」という判定は、この瞬間に間違います。現在のPodのラベルを基準に、それぞれのalertsの項目を比較する必要がありました。

グループのstatus 1つの値と、グループ内の個々のアラートのstatusも区別します。複数の対象が1つのグループにまとめられると、グループの状態1つで、すべての対象の状態を代表することはできません。実際の環境では、どのラベルをインシデントの識別子にするか、再起動前後のインシデントをつなげるか分けるかも、契約として決める必要があります。今回の課題は、rule UIDとpod UIDを観測ファイルに入れて、別の実行の記録を誤って再利用しないようにします。これは、ファイルの真正性を証明する電子署名ではありません。

観測の空白にも名前を付けます。APIエラーのあとで空のオブジェクトを正常と解釈すると、「障害がない」という誤った結論が生まれます。入力がないか、互いに矛盾していれば、unknownを返し、必要な参照からやり直します。数字の0と実際のbool Falseを同じものとして扱わない理由も、ここにあります。誤ったデータ形式が、偶然合っている状態に見えないようにします。

過去の障害の記録と現在の状態は、用途が違います。復旧したあとは、現在のAPIにアクティブなアラートがないかもしれませんが、インシデントレポートには、先に発火して受信した記録が残っている必要があります。保存したJSONを、現在の状態ですべて上書きすると、原因を説明する資料がなくなります。逆に、古い正常なJSONだけを持って、現在のサービスが正常だと言ってもいけません。最後の復旧のステップは、保存した記録だけでなく、現在の業務レスポンスとアクティブなアラートの状態を、もう一度確認します。

次のラボですること

払い出しの依存関係を故障させ、Prometheusの発火だけがある時点、Alertmanagerまでだけ到達した時点、Webhookの受信と復旧の時点を、それぞれ残します。最後に、厳格なbool契約で状態を分類する診断ツールを作ります。成功のケース1つだけを入れるのではなく、欠落・矛盾・誤った型を入れて、拒否されることを確認します。外部への通知送信、複数ノードの高可用性、本番SLOの達成は、今回のラボの証明範囲ではありません。