Files
awoooi/docs/adr/ADR-056-config-drift-detection.md
OG T 15c7f6fcd3 docs(adr): 起草 ADR-054/055/056/057 — Phase 25 三方向架構決策
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>
2026-04-05 00:24:50 +08:00

3.8 KiB
Raw Blame History

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 狀態)

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 操作不安全

暫回傳 501ADR-057 完成後改由 Gitea PR API 實作。

D5: CronJob 每小時自動掃描

schedule: "0 * * * *"
concurrencyPolicy: Forbid        # 防並發
activeDeadlineSeconds: 300       # 5 分鐘超時
backoffLimit: 0                  # 失敗不重試

D6: 漂移報告暫存in-process dictPhase 1

_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) 完全接管 引入外部依賴,與現有架構整合成本高