EXERCISE 60分

ストーリー

佐藤CTO
アラート設計、オンコール体制、ランブック、カオスエンジニアリング — Step 4の理論を全て学んだ。ここからは実践だ
佐藤CTO
OrderFlowシステムに対して、効果的なアラート体系、持続可能なオンコール体制、実用的なランブック、そしてカオス実験の計画を設計してほしい

ミッション概要

ミッションテーマ目安時間
Mission 1アラートルールの設計15分
Mission 2オンコールローテーション計画15分
Mission 3ランブックの作成15分
Mission 4カオス実験の設計15分

前提条件

system: "OrderFlow - 注文処理システム"
team:
  sre_engineers: 5
  developers: 12
  sre_lead: 1

services:
  - name: "order-api"
    slo: "99.9% availability, p99 < 500ms"
  - name: "inventory-service"
    slo: "99.9% availability, p99 < 300ms"
  - name: "payment-service"
    slo: "99.95% availability, p99 < 2s"
  - name: "notification-service"
    slo: "99.5% availability (非クリティカル)"

current_issues:
  - "1日に40件以上のアラートが通知され、8割が対応不要"
  - "オンコールは2名で回しており、2週間に1回の頻度"
  - "ランブックが存在しないため、障害対応が属人的"
  - "本番環境での障害対応テストが一度も実施されていない"

Mission 1: アラートルールの設計(15分)

要件

OrderFlowシステムの現在のアラート40件を見直し、効果的なアラート体系を設計してください。

  1. 既存アラートの分類(Page / Ticket / Log / Suppress)
  2. SLOベースのバーンレートアラートルール(Prometheusルール)
  3. Alertmanagerのルーティング設定
  4. アラートの定期レビュープロセス

現在のアラート例:

- CPU使用率 > 70%(全サービス・全Pod): 16件/日
- メモリ使用率 > 80%: 8件/日
- 5xxエラー発生: 6件/日
- レイテンシ > 1s: 5件/日
- ディスク使用率 > 60%: 3件/日
- Pod再起動: 2件/日
解答例

1. 既存アラートの分類:

アラート現在の通知見直し後理由
CPU > 70%PageSuppress閾値が低すぎる。SLIに直接影響しない
CPU > 90% (5分以上)-Logリソース計画の参考に
メモリ > 80%PageLog即時対応不要、トレンド監視
メモリ > 95%-TicketOOMリスク、計画的対応
5xxエラー(単発)PageLog単発エラーは対応不要
エラー率 > SLO閾値-Page (バーンレート)SLOベースに変更
レイテンシ > 1sPageLog閾値をSLO基準に変更
レイテンシ > SLO p99-Page (バーンレート)SLOベースに変更
ディスク > 60%PageSuppress閾値が低すぎる
ディスク > 85%-Ticket計画的に拡張
Pod再起動PageLog単発の再起動は正常動作
Pod再起動 > 3回/10分-PageCrashLoopBackOffの可能性

結果: 40件/日 → 推定2〜3件/日(アクション率80%以上を目標)

2. バーンレートアラートルール:

groups:
  - name: orderflow_slo_alerts
    rules:
      # order-api: 可用性SLO 99.9%
      - alert: OrderAPI_SLO_BurnRate_Critical
        expr: |
          (
            sum(rate(http_requests_total{service="order-api",status=~"5.."}[1h]))
            / sum(rate(http_requests_total{service="order-api"}[1h]))
          ) > (14.4 * 0.001)
          and
          (
            sum(rate(http_requests_total{service="order-api",status=~"5.."}[5m]))
            / sum(rate(http_requests_total{service="order-api"}[5m]))
          ) > (14.4 * 0.001)
        labels:
          severity: critical
          service: order-api
        annotations:
          summary: "order-api SLOバーンレートCritical"
          runbook_url: "https://wiki.example.com/runbooks/order-api-slo-critical"

      # payment-service: 可用性SLO 99.95%
      - alert: Payment_SLO_BurnRate_Critical
        expr: |
          (
            sum(rate(http_requests_total{service="payment-service",status=~"5.."}[1h]))
            / sum(rate(http_requests_total{service="payment-service"}[1h]))
          ) > (14.4 * 0.0005)
          and
          (
            sum(rate(http_requests_total{service="payment-service",status=~"5.."}[5m]))
            / sum(rate(http_requests_total{service="payment-service"}[5m]))
          ) > (14.4 * 0.0005)
        labels:
          severity: critical
          service: payment-service
        annotations:
          summary: "payment-service SLOバーンレートCritical"
          runbook_url: "https://wiki.example.com/runbooks/payment-slo-critical"

3. Alertmanagerルーティング:

route:
  group_by: ['alertname', 'service']
  group_wait: 30s
  receiver: 'slack-info'
  routes:
    - match:
        severity: critical
      receiver: 'pagerduty-primary'
    - match:
        severity: warning
      receiver: 'slack-warning'
    - match:
        severity: info
      receiver: 'slack-info'

inhibit_rules:
  - source_match: { severity: critical }
    target_match: { severity: warning }
    equal: ['service']

4. 定期レビュー:

週次: アラート発火数・アクション率の集計(15分)
月次: 不要アラートの削除、閾値の調整(30分)
四半期: SLOの見直しに合わせてアラート体系全体をレビュー(2時間)

Mission 2: オンコールローテーション計画(15分)

要件

5名のSREエンジニアと1名のSREリードで、持続可能なオンコール体制を設計してください。

  1. ローテーションスケジュール(8週間分)
  2. エスカレーションポリシー
  3. ハンドオフプロセス
  4. オンコール負荷の計測とKPI
解答例

1. ローテーションスケジュール(8週間):

        | Primary    | Secondary  | 備考
Week 1  | Engineer A | Engineer B |
Week 2  | Engineer B | Engineer C |
Week 3  | Engineer C | Engineer D |
Week 4  | Engineer D | Engineer E |
Week 5  | Engineer E | Engineer A |
Week 6  | Engineer A | Engineer B | 2巡目
Week 7  | Engineer B | Engineer C |
Week 8  | Engineer C | Engineer D |

交代: 毎週月曜 10:00(朝会後)
年間オンコール回数: 52 / 5 ≒ 10.4回/人(許容範囲)

2. エスカレーションポリシー:

escalation:
  level_1:
    target: "Primary On-Call"
    timeout: 5min
    notification: [push, sms]
  level_2:
    target: "Secondary On-Call"
    timeout: 10min
    notification: [push, sms, phone]
  level_3:
    target: "SRE Lead"
    timeout: 15min
    notification: [phone]
  level_4:
    target: "Engineering Manager + CTO"
    timeout: 20min
    notification: [phone]
    condition: "SEV1のみ"

3. ハンドオフプロセス:

毎週月曜 10:00:
1. 前任者が「オンコールサマリー」をSlackに投稿
   - 期間中のインシデント数
   - 未解決事項
   - 注意が必要なサービス/コンポーネント
   - 直近のデプロイ情報
2. 後任者がPagerDutyの通知テスト実施
3. VPN/SSHアクセスの動作確認
4. 質疑応答(5分)

4. KPI:

KPI目標値計測方法
週間ページ数< 5件PagerDuty Analytics
深夜ページ数< 1件/週PagerDuty時間帯分析
ACK時間(中央値)< 3分PagerDuty
アクション率> 80%月次レビュー
MTTR (SEV1)< 30分インシデント記録

Mission 3: ランブックの作成(15分)

要件

OrderFlowシステムで最も頻繁に発生する障害「payment-serviceの決済処理タイムアウト」に対するランブックを作成してください。

  1. ランブックの全セクション(テンプレートに従う)
  2. 決定木(少なくとも3分岐)
  3. 自動化可能な診断ステップの特定
  4. エスカレーション基準
解答例
runbook:
  metadata:
    title: "Payment Service 決済処理タイムアウト対応"
    alert_name: "Payment_SLO_BurnRate_Critical"
    severity: "SEV1/SEV2"
    service: "payment-service"
    last_updated: "2026-02-14"
    review_date: "2026-05-14"

  overview:
    description: "決済処理のレイテンシが増加し、タイムアウトが発生している状態"
    impact: "ユーザーが決済を完了できない。注文確定率の低下"
    urgency: "高 - 売上に直接影響"

  diagnosis:
    steps:
      - order: 1
        action: "Grafanaダッシュボードで状況確認"
        command: "https://grafana.example.com/d/payment-overview"
        expected: "レイテンシのスパイク、エラー率の上昇を確認"

      - order: 2
        action: "payment-serviceのログを確認"
        command: |
          kubectl logs -l app=payment-service -n production --tail=100 | grep -E "timeout|error"
        expected: "タイムアウトのエラーメッセージと原因を特定"

      - order: 3
        action: "外部決済APIのステータスを確認"
        command: |
          curl -s https://status.stripe.com/api/v2/status.json | jq '.status'
        expected: "Stripeのステータスが正常かどうか"

  decision_tree:
    question: "タイムアウトの原因は?"
    options:
      - condition: "外部決済API(Stripe)の障害"
        actions:
          - "Stripeのステータスページを確認"
          - "サーキットブレーカーが発動しているか確認"
          - "発動していない場合、手動でサーキットブレーカーをOpen"
          - "ステータスページに障害情報を掲載"
          - "Stripe復旧後、サーキットブレーカーをリセット"

      - condition: "DB接続プール枯渇"
        actions:
          - "DB接続数を確認: kubectl exec postgres-0 -- psql -c 'SELECT count(*) FROM pg_stat_activity;'"
          - "接続数が上限の80%以上 → payment-serviceを再起動"
          - "kubectl rollout restart deployment/payment-service -n production"
          - "接続プールサイズの見直し(恒久対応)"

      - condition: "payment-service自体の問題(メモリリーク等)"
        actions:
          - "Pod のメモリ使用量確認: kubectl top pods -l app=payment-service -n production"
          - "メモリが上限に近い → Pod再起動"
          - "最新デプロイが原因の場合 → ロールバック"
          - "kubectl rollout undo deployment/payment-service -n production"

  escalation:
    when:
      - "上記手順で15分以内に改善しない"
      - "データ不整合の可能性がある"
      - "複数サービスに影響が拡大"
    contact:
      - "SREリード(5分以内に応答なければ次へ)"
      - "決済チームテックリード"
      - "エンジニアリングマネージャー"

  automation_candidates:
    - step: "外部APIステータス確認"
      current: "手動curl"
      proposed: "自動診断スクリプトで定期チェック"
    - step: "DB接続数確認"
      current: "手動kubectl exec"
      proposed: "Prometheusメトリクスで自動監視・アラート"
    - step: "Pod再起動"
      current: "手動kubectl rollout restart"
      proposed: "メモリ使用量に基づく自動再起動(VPA)"

Mission 4: カオス実験の設計(15分)

要件

OrderFlowシステムの信頼性を検証するためのカオス実験を設計してください。

  1. 3つのカオス実験シナリオ
  2. 各シナリオの定常状態仮説
  3. ゲームデイの計画書
  4. 中止基準(Abort Criteria)
解答例

1. カオス実験シナリオ:

シナリオ注入する障害検証する仮説
実験1payment-serviceのPod 50%削除残りのPodでSLO維持
実験2DBへのネットワーク遅延2000ms注入タイムアウト・リトライが適切に動作
実験3notification-service完全停止注文処理自体には影響なし(非同期連携)

2. 定常状態仮説:

experiment_1:
  name: "payment-service Pod削除耐性テスト"
  hypothesis: "payment-serviceの50%のPodが停止しても、決済成功率99.9%を維持する"
  steady_state:
    - metric: "決済成功率"
      normal: "> 99.95%"
      tolerance: "> 99.9%"
    - metric: "決済レイテンシ p99"
      normal: "< 2s"
      tolerance: "< 5s"

experiment_2:
  name: "DB遅延注入テスト"
  hypothesis: "DB応答に2000msの遅延が加わっても、サーキットブレーカーとタイムアウト設定によりエラー率が1%未満に抑えられる"
  steady_state:
    - metric: "注文処理エラー率"
      normal: "< 0.1%"
      tolerance: "< 1%"

experiment_3:
  name: "notification-service停止テスト"
  hypothesis: "notification-serviceが完全停止しても、注文処理と決済処理は影響を受けない"
  steady_state:
    - metric: "注文成功率"
      normal: "> 99.9%"
      tolerance: "> 99.9%(影響ゼロ)"

3. ゲームデイ計画書:

game_day:
  date: "2026-03-20"
  time: "10:00-13:00"
  participants:
    - "SREチーム(5名)"
    - "決済チーム(3名)"
    - "SREリード(ファシリテーター)"
  roles:
    facilitator: "SREリード"
    chaos_operator: "Engineer A(障害注入担当)"
    incident_commander: "Engineer B(対応リーダー)"
    observer: "Engineer C(記録・メトリクス監視)"

  schedule:
    - time: "10:00-10:15"
      activity: "ブリーフィング: 目的・シナリオ・中止基準の確認"
    - time: "10:15-11:00"
      activity: "実験1: payment-service Pod削除"
    - time: "11:00-11:15"
      activity: "休憩・振り返り"
    - time: "11:15-12:00"
      activity: "実験2: DB遅延注入"
    - time: "12:00-12:30"
      activity: "実験3: notification-service停止"
    - time: "12:30-13:00"
      activity: "デブリーフィング: 結果振り返り・改善点"

4. 中止基準:

abort_criteria:
  immediate_abort:
    - "注文成功率 < 99% が1分以上継続"
    - "決済処理でデータ不整合が検出された"
    - "想定外のサービスに影響が波及"
  caution:
    - "レイテンシ p99 > 10s が30秒以上継続"
    - "エラーバジェット消費量が実験前の見積もりを超過"
  rollback_procedure:
    - "kubectl delete chaosengine <experiment-name> -n production"
    - "必要に応じて kubectl rollout restart で Pod を再起動"
    - "メトリクスが定常状態に復帰することを確認(5分間監視)"

達成度チェック

ミッションテーマ完了
Mission 1アラートルールの設計
Mission 2オンコールローテーション計画
Mission 3ランブックの作成
Mission 4カオス実験の設計

まとめ

ポイント内容
アラート設計SLOベースのバーンレートアラートでノイズを大幅削減
オンコール5名以上のローテーション、エスカレーション、負荷管理
ランブックテンプレート+決定木で属人性を排除、自動化候補を特定
カオス実験定常状態仮説→障害注入→検証のサイクルで信頼性を向上

チェックリスト

  • 既存アラートを分類し、SLOベースに再設計できた
  • 持続可能なオンコールローテーションを設計できた
  • 決定木を含むランブックを作成できた
  • カオス実験とゲームデイの計画を立てられた

次のステップへ

次は理解度チェッククイズです。Step 4で学んだアラート設計、オンコール体制、ランブック、カオスエンジニアリングの理解度を確認しましょう。


推定読了時間: 60分