エラーバジェットを数字で計算する
目標
実際のPrometheusで直近のエラー速度を観察し、別の合成30日集計を使って機能デプロイの判断プログラムを作ります。消費速度と期間使用量、凍結とデータ不足を区別します。
なぜ重要なのか
12時間のエラー率を許容エラー率で割った値は、12時間のバーンレートです。その値1つから、30日分のバジェットをすでに使い切ったと結論することはできません。観測がないときに0を代わりに入れるのも、安全な判断ではありません。実際のデータの単位と範囲を確認したうえで、明示的なポリシーをコードとして実行します。
所要時間の目安は75分です。標準の60分のセッションが終わる前に、+時間で延長します(最大180分)。セッション終了時には/root/obsのファイルが消えるので、必要なコードは別に保管してください。Pythonの条件文・辞書・JSON入出力が前提知識です。
ステップ
- 5xxだけを失敗と定めた合成サービスの、成功率SLIを/root/obs/slo-01-sli.promqlに書きます。直近1時間のrateを合算して、成功リクエスト/全リクエストを求めます。この定義を、他のサービスの4xxに一般化してはいけません。
- 時間ベースの99.9% SLOにおける30日間の許容利用不可時間を分で計算し、/root/obs/slo-02-budget.txtに数字だけを書きます。リクエストのエラー件数には換算しません。
- 直近12時間のエラー率を0.001で割ったバーンレートのクエリを、/root/obs/slo-03-consumed.promqlに書きます。ファイル名は既存ラボとの互換のために維持していますが、値は月間使用量ではありません。
- 直近1時間のバーンレートのクエリを/root/obs/slo-04-burn1h.promqlに書きます。ステップ3とはウィンドウの長さが違い、どちらも速度の指標です。
- 1時間と5分のバーンレートがそれぞれ14.4を超える条件をandでつないで、/root/obs/slo-05-multi.promqlに書きます。回復した短いウィンドウを無視してはいけません。
- /etc/prometheus/rules/slo.ymlに、ErrorBudgetBurnFastというマルチウィンドウのアラートルールを書きます。alert・expr・for・labels.severity・annotations.summaryを含め、promtool check rulesで検査します。アラートの配信と、機能デプロイを許可するポリシーは別物です。
- Prometheusをreloadしたあと、ルールAPIでアラートが登録されたかを確認します。登録されたという事実だけでは、実際の発火や運用での対応が検証されたことにはなりません。
- /opt/lab/slo_release/contract.mdを読み、/root/obs/slo-gate.pyを完成させます。stdinの合成観測JSON 1つから、期間バジェット使用率と2つのウィンドウのバーンレートを計算します。データ不十分はhold、バジェット使用率が1以上ならfreeze、それ以外でも2つのウィンドウがともに14.4を超えていればfreeze、残りはallowです。出力はdecision・reason・budget_used・burn_hour・burn_five_minutesの5つのフィールドで、終了コードはallow=0、freeze=2、hold=3です。データ検査の順序と詳細なreasonは、実行契約に従います。
参考
- 開始ファイル: /opt/lab/slo_release/starter.py。なければmkdir -p /root/obsを実行してから、slo-gate.pyとしてコピーします。
- 入力の確認: python3 /opt/lab/slo_release/evaluate.py sample healthy
- 全体の検証: python3 /opt/lab/slo_release/evaluate.py check /root/obs/slo-gate.py
- ステップ5・6の時系列検査の案内: /opt/lab/slo_release/promql.md。偽の条件は、値が0の要素ではなく空のベクトルを返さないと、アラートが消えません。
- Prometheusの約12時間の合成履歴と、プログラム入力の30日合成集計は、別々のデータです。実際の運用記録ではありません。
- データがない場合、数字はnullであり0ではありません。月間の比率20%は20ではなく0.2です。
- プログラムは、外部サービスへの接続や、実際のデプロイ・ロールバックの実行をしません。allowはこの合成ポリシーの通過であり、運用上の安全を保証するものではありません。
SLIをクエリで定義する
成功率SLI → /root/obs/slo-01-sli.promql
この合成サービスは、観測された5xxだけを失敗として数えます。成功リクエストのrateの合計を、全体のrateの合計で割ってください。他のサービスの4xxを、無条件に成功へ分類してはいけません。
30日分のエラーバジェットを分で求める
時間ベースの30日バジェット(分) → /root/obs/slo-02-budget.txt
時間ベースの99.9% SLOです。30日の分数に許容される利用不可の割合を掛けて、小数第1位まで書きます。リクエスト件数のバジェットと混同しないでください。
12時間の消費速度を観察する
12時間の消費速度の観察 → /root/obs/slo-03-consumed.promql
12時間のエラー率を、許容エラー率の0.001で割ります。1を超えたことは、そのウィンドウの速度が許容速度より速いという意味であり、30日分のバジェットをすでに使い切ったという意味ではありません。
1時間の消費速度を観察する
1時間の消費速度の観察 → /root/obs/slo-04-burn1h.promql
同じエラー定義のまま、ウィンドウを1hに変えます。長いウィンドウも短いウィンドウもバーンレートであり、バジェット使用量とは区別します。
マルチウィンドウ条件
マルチウィンドウ条件 → /root/obs/slo-05-multi.promql
1時間と5分がそれぞれ14.4を超える条件を、andでつなぎます。偽の要素は取り除かなければなりません。bool比較の0でも、アラートが点灯することがあります。/opt/lab/slo_release/promql.mdの時系列検査で、回復と欠落を確認してください。
アラートルールを書く
ErrorBudgetBurnFastのマルチウィンドウアラートルール → /etc/prometheus/rules/slo.yml
alert・expr・for・labels.severity・annotations.summaryを含めてください。for: 0sは、追加の継続待ちなしに2つのウィンドウ条件を評価します。長いforは、深刻な失敗のアラートまで遅らせることがあります。
ルールの登録を確認する
ErrorBudgetBurnFastルールがPrometheusに登録されたことを確認
設定を検査してからreloadし、rules APIで名前を確認してください。inactiveでも登録の確認は通りますが、実際の発火やアラート配信のテストの代わりにはなりません。
デプロイ判断をコードで検証する
判断プログラム → /root/obs/slo-gate.py
実行契約にあるデータ検査から実装してください。月間バジェットの超過、直近2つのウィンドウでの障害、未確認のデータを、それぞれ別の理由と終了コードで残します。