Files
awoooi/docs/adr/ADR-025-alert-chain-e2e-validation.md
OG T 14c81f728f docs: 新增 ADR-025 告警鏈路 E2E 驗證 + 更新 Skills
新增:
- ADR-025: 告警鏈路 E2E 驗證架構 (2026-03-26 事故教訓)

更新:
- ADR-011: 新增 DNS 規則最佳實踐 (附錄 B)
- Skill 04: 新增 NetworkPolicy DNS 規則 + CoreDNS 設定
- Skill 05: 新增告警鏈路 Smoke Test 要求
- CLAUDE.md: 新增告警鏈路驗證到任務前必讀

事故根因:
1. URL 路徑錯誤 (webhook vs webhooks)
2. NetworkPolicy DNS 規則標籤不匹配
3. CoreDNS 上游 DNS 依賴 systemd-resolved

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-26 15:34:12 +08:00

8.8 KiB
Raw Blame History

ADR-025: 告警鏈路 E2E 驗證架構

狀態: 批准 日期: 2026-03-26 決策者: 統帥 觸發: URL 路徑錯誤 + NetworkPolicy DNS 規則錯誤導致 2 天無告警

問題陳述

事故時間線 (2026-03-26):
├── Alertmanager 設定 /api/v1/webhook/alertmanager (單數)
├── API 實際路徑 /api/v1/webhooks/alertmanager (複數)
├── 結果: 404 Not Found所有告警丟失
├── 同時: NetworkPolicy DNS 規則使用錯誤標籤
├── CoreDNS 無法解析外部 DNS (使用 127.0.0.53)
└── 後果: 2 天完全無 Telegram 告警

根本原因:

  1. 沒有 E2E 測試驗證 Alertmanager → API → Telegram 鏈路
  2. 部署後沒有 Smoke Test 確認端點可達
  3. NetworkPolicy DNS 規則標籤與 CoreDNS 不匹配
  4. CoreDNS 上游 DNS 設定依賴 systemd-resolved (容器內無效)

決策:四層驗證架構

┌──────────────────────────────────────────────────────────────────────┐
│                   告警鏈路 E2E 驗證架構                                │
├──────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  Layer 1: 部署後 Smoke Test (強制)                                   │
│  ═══════════════════════════════════                                 │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │  每次部署後自動執行:                                          │    │
│  │  1. curl POST /api/v1/webhooks/alertmanager (測試告警)       │    │
│  │  2. 驗證回應 success=true                                    │    │
│  │  3. 驗證 Telegram message_id 存在                            │    │
│  │  4. 失敗 → 部署回滾                                          │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                       │
│  Layer 2: DNS 連通性檢查                                             │
│  ══════════════════════════                                          │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │  Health Probe 必須包含:                                       │    │
│  │  - 內部 DNS: kubernetes.default.svc.cluster.local            │    │
│  │  - 外部 DNS: api.telegram.org                                │    │
│  │  任一失敗 → Pod 標記 Not Ready                               │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                       │
│  Layer 3: 鏈路心跳監控                                               │
│  ════════════════════════                                            │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │  Prometheus 規則:                                             │    │
│  │  - awoooi_alerts_received_total                              │    │
│  │  - awoooi_telegram_sent_total                                │    │
│  │  連續 1 小時為 0 → 觸發 CRITICAL 告警                        │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                       │
│  Layer 4: ConfigMap 驗證 Hook                                        │
│  ════════════════════════════                                        │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │  Alertmanager ConfigMap 修改前:                               │    │
│  │  1. 提取 webhook URL                                         │    │
│  │  2. curl 測試 URL 可達性                                     │    │
│  │  3. 必須收到 200 或 422 (格式錯但端點存在)                   │    │
│  │  4. 驗證失敗 → 阻止 apply                                    │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                       │
└──────────────────────────────────────────────────────────────────────┘

實施細節

1. 部署後 Smoke Test

# CI/CD 強制步驟
- name: Alert Chain Smoke Test
  run: |
    # 發送測試告警
    RESPONSE=$(curl -s -X POST "$API_URL/api/v1/webhooks/alertmanager" \
      -H 'Content-Type: application/json' \
      -d '{"receiver":"smoke-test","status":"firing","alerts":[{"status":"firing","labels":{"alertname":"SmokeTest","severity":"info"},"annotations":{"summary":"CI Smoke Test"}}]}')

    # 驗證成功
    echo "$RESPONSE" | jq -e '.success == true' || exit 1
    echo "Alert chain smoke test passed"

2. NetworkPolicy DNS 規則 (正確寫法)

# ❌ 錯誤: 使用不存在的標籤
- ports:
    - port: 53
  to:
    - podSelector:
        matchLabels:
          environment: prod    # CoreDNS 沒有這個標籤!
          k8s-app: kube-dns
          system: awoooi       # CoreDNS 沒有這個標籤!

# ✅ 正確: 使用 namespace selector
- ports:
    - port: 53
      protocol: UDP
    - port: 53
      protocol: TCP
  to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns

3. CoreDNS 上游 DNS 設定

# ❌ 錯誤: 使用 /etc/resolv.conf (指向 127.0.0.53)
forward . /etc/resolv.conf

# ✅ 正確: 使用真實 DNS 伺服器
forward . 8.8.8.8 1.1.1.1

4. Prometheus 鏈路監控規則

groups:
  - name: alert-chain-health
    rules:
      - alert: AlertChainBroken
        expr: increase(awoooi_alerts_received_total[1h]) == 0
        for: 1h
        labels:
          severity: critical
        annotations:
          summary: "告警鏈路斷裂1 小時內沒有收到任何告警"

      - alert: TelegramNotificationFailed
        expr: increase(awoooi_telegram_sent_total[1h]) == 0 and increase(awoooi_alerts_received_total[1h]) > 0
        for: 30m
        labels:
          severity: critical
        annotations:
          summary: "Telegram 通知失敗!有告警但沒有發送成功"

URL 路徑規範

正確 錯誤
/api/v1/webhooks/alertmanager /api/v1/webhook/alertmanager
複數形式 webhooks 單數形式 webhook
/api/v1/approvals /api/v1/approval
/api/v1/incidents /api/v1/incident

原則: API Router 統一使用複數命名


驗收標準

項目 狀態
CI/CD 包含 Alert Chain Smoke Test
NetworkPolicy DNS 規則使用正確標籤
CoreDNS 使用真實上游 DNS
Prometheus 鏈路監控規則已部署
ConfigMap 修改前驗證 Hook

教訓

"路徑差一個 s所以 404" — 這種低級錯誤絕對不能再犯。 必須靠自動化驗證,不能靠人眼審查。


關聯文件

  • Memory: feedback_alertchain_e2e_validation.md
  • ADR-011: NetworkPolicy 變更治理架構
  • Skill 04: DevOps Commander
  • Skill 05: SRE QA