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

197 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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