# 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 ```yaml # 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 規則 (正確寫法) ```yaml # ❌ 錯誤: 使用不存在的標籤 - 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 設定 ```yaml # ❌ 錯誤: 使用 /etc/resolv.conf (指向 127.0.0.53) forward . /etc/resolv.conf # ✅ 正確: 使用真實 DNS 伺服器 forward . 8.8.8.8 1.1.1.1 ``` ### 4. Prometheus 鏈路監控規則 ```yaml 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