ADR-054: DIAGNOSE Privacy-First Routing (已批准) - _local_fallback_chain 設計決策 - NEMOTRON privacy_level=local 首席架構師裁示 - 全部 local 失敗 → REJECT + Telegram ADR-055: Knowledge Auto-Harvesting (已批准) - AUTO_RUNBOOK DRAFT + ANTI_PATTERN PUBLISHED 設計理由 - compute_hash() 碰撞風險說明 - Fire-and-forget GC 防護強制規範 ADR-056: Config Drift Detection 四層架構 (已批准) - Detector→Analyzer→Interpreter→Remediator 職責邊界 - AI 只做意圖分析不做修復決策 - adopt() 暫停 + _recent_reports Phase 1 限制 ADR-057: adopt() Gitea PR API 實作路徑 (草案,待批准) - 解決 API Pod git add -A 安全風險 - PR review 流程保障 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
124 lines
3.8 KiB
Markdown
124 lines
3.8 KiB
Markdown
# ADR-056: Config Drift Detection — GitOps 守門員架構
|
||
|
||
> **狀態**: ✅ 已批准
|
||
> **日期**: 2026-04-04
|
||
> **決策者**: 統帥 + 首席架構師
|
||
> **首席架構師評分**: 技術背書
|
||
> **關聯 ADR**: ADR-052, ADR-057 (adopt() Gitea PR API)
|
||
> **實作**: Phase 25 P2 — commit 3455044
|
||
|
||
---
|
||
|
||
## 背景
|
||
|
||
### 問題陳述
|
||
|
||
K8s 叢集實際狀態可能因以下原因與 Git YAML 產生漂移:
|
||
|
||
1. 緊急 Hotfix 直接 kubectl 操作而未提交 Git
|
||
2. 人為誤操作(kubectl edit / kubectl set image)
|
||
3. CI/CD 部分失敗導致 Rollout 中斷
|
||
|
||
目前無系統性機制偵測此類漂移,也無法自動修復。
|
||
|
||
---
|
||
|
||
## 決策
|
||
|
||
### D1: 四層架構(Detector → Analyzer → Interpreter → Remediator)
|
||
|
||
```
|
||
GitStateReader ─┐
|
||
├─→ DriftDetector.scan() → raw DriftReport
|
||
K8sStateReader ─┘
|
||
↓
|
||
DriftAnalyzer.classify() → HIGH/MEDIUM/INFO
|
||
↓
|
||
NemotronDriftInterpreter.analyze() → intent + explanation
|
||
↓
|
||
DriftRemediator.rollback() / adopt()
|
||
```
|
||
|
||
**職責邊界**:
|
||
- Detector: 事實比對(Git vs K8s),不做判斷
|
||
- Analyzer: 分級(白名單過濾、嚴重度分類)
|
||
- Interpreter: AI 意圖分析,**只輸出意圖判斷,不輸出修復指令**
|
||
- Remediator: 確定性修復執行,不使用 AI 決定修復策略
|
||
|
||
### D2: AI 只做意圖分析,確定性程式碼做修復
|
||
|
||
NemotronDriftInterpreter 分析漂移意圖(emergency_hotfix / human_error / automated_change / unknown),為人工決策提供參考。
|
||
|
||
修復由確定性程式碼執行(`kubectl apply` / `git push`),不允許 AI 生成 kubectl 指令。
|
||
|
||
**理由**: AI 生成的修復指令無法保證正確性,對 K8s 叢集的破壞難以回滾。
|
||
|
||
### D3: rollback() 使用 kubectl apply(覆蓋回 Git 狀態)
|
||
|
||
```python
|
||
cmd = ["kubectl", "apply", "-f", target, "-n", namespace, "--dry-run=none"]
|
||
```
|
||
|
||
- `resource_key` 參數支援精細範圍(按 Kind/Name 匹配 YAML 檔)
|
||
- 失敗時只通知,不重試(避免重複操作)
|
||
|
||
### D4: adopt() 端點暫停開放(見 ADR-057)
|
||
|
||
API Pod 內執行 `git add -A` 有安全風險:
|
||
|
||
1. API Pod 通常無 Git 認證(SSH key / token)
|
||
2. `git add -A` 可能誤提交敏感檔案
|
||
3. 多副本部署下 git 操作不安全
|
||
|
||
暫回傳 501,ADR-057 完成後改由 Gitea PR API 實作。
|
||
|
||
### D5: CronJob 每小時自動掃描
|
||
|
||
```yaml
|
||
schedule: "0 * * * *"
|
||
concurrencyPolicy: Forbid # 防並發
|
||
activeDeadlineSeconds: 300 # 5 分鐘超時
|
||
backoffLimit: 0 # 失敗不重試
|
||
```
|
||
|
||
### D6: 漂移報告暫存(in-process dict,Phase 1)
|
||
|
||
```python
|
||
_recent_reports: dict[str, DriftReport] = {} # 最多 50 筆,FIFO
|
||
```
|
||
|
||
此為 Phase 1 設計,多副本部署下不一致。
|
||
|
||
**升級路徑**: Phase 2 遷移至 `drift_reports` DB 表(migration phase9 已就緒)。
|
||
|
||
---
|
||
|
||
## 後果
|
||
|
||
### 正面影響
|
||
|
||
- 漂移偵測自動化,每小時一次無需人工
|
||
- 四層架構職責清晰,各層可獨立替換
|
||
- AI 只做分析不做決策,保持確定性修復
|
||
|
||
### 負面影響 / 風險
|
||
|
||
- `_recent_reports` 多副本不一致(Phase 1 已知限制)
|
||
- adopt() 功能暫停,承認漂移需要手動 git 操作
|
||
|
||
### 未決事項
|
||
|
||
- C3: `_recent_reports` 遷移至 DB(見 Phase 2 計畫)
|
||
- I4: `_is_allowlisted` / `_is_critical` field_path 比對邏輯需整合測試覆蓋
|
||
- ADR-057: adopt() Gitea PR API 實作
|
||
|
||
---
|
||
|
||
## 替代方案
|
||
|
||
| 方案 | 理由未採用 |
|
||
|------|-----------|
|
||
| AI 生成 kubectl patch 指令執行修復 | AI 生成指令不可控,破壞難以回滾 |
|
||
| 只記錄漂移不修復 | 缺少閉環,漂移長期積累 |
|
||
| GitOps operator (Flux/ArgoCD) 完全接管 | 引入外部依賴,與現有架構整合成本高 |
|