Files
awoooi/docs/adr/ADR-016-k8s-resource-naming.md
OG T 96c3ddd8c4 feat(api): Phase 18.1 K8s 資源名稱驗證 (ADR-016)
三層防禦架構確保 kubectl 指令有效:
1. Webhook 入口正規化 (webhooks.py)
2. OpenClaw 產生指令前驗證 (openclaw.py)
3. 靜態映射表 + 模糊匹配 (k8s_naming.py, resource_resolver.py)

新增:
- src/utils/k8s_naming.py: RFC 1123 正規化 + 靜態映射
- src/services/resource_resolver.py: MCP K8s Tool 動態驗證
- docs/adr/ADR-016-k8s-resource-naming.md: 契約文檔
- scripts/e2e_tool_call_verification.py: E2E 驗證腳本 v2.0

修改:
- webhooks.py: Phase 18.1.7 入口正規化
- openclaw.py: Phase 18.1.6 產生指令前驗證
- Skill 03 v1.4: 新增 K8s 資源驗證章節

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-26 11:22:47 +08:00

6.0 KiB
Raw Blame History

ADR-016: K8s 資源名稱規範與動態驗證

狀態: Accepted 日期: 2026-03-26 決策者: 統帥 + 首席架構師

背景

在 E2E Tool Call 驗證中發現AI (OpenClaw) 產生的 kubectl 指令會執行失敗,原因是資源名稱不正確:

# AI 產生的指令 (錯誤)
kubectl rollout restart deployment/https://api.awoooi.wooo.work -n default

# 正確應該是
kubectl rollout restart deployment/awoooi-api -n awoooi-prod

根因Alert 來源的 target_resource 欄位傳入 URL 而非 K8s Deployment 名稱AI 直接使用導致無效指令。

決策

實施三層防禦架構,確保 kubectl 指令有效:

┌─────────────────────────────────────────────────────────────┐
│  Alert 來源 (Alertmanager/Sentry/UptimeKuma)                │
│  target_resource = "https://api.awoooi.wooo.work"          │
└─────────────────────┬───────────────────────────────────────┘
                      ↓
┌─────────────────────────────────────────────────────────────┐
│  第一層: 入口正規化 (k8s_naming.py)                          │
│  - 移除 URL scheme                                          │
│  - 查詢靜態映射表                                            │
│  - 轉換為 RFC 1123 合規名稱                                  │
└─────────────────────┬───────────────────────────────────────┘
                      ↓
┌─────────────────────────────────────────────────────────────┐
│  第二層: 動態驗證 (resource_resolver.py)                     │
│  - 調用 kubectl_get 驗證資源存在性                           │
│  - 模糊匹配 namespace 內的 Deployments                       │
│  - 回傳匹配結果或候選列表                                    │
└─────────────────────┬───────────────────────────────────────┘
                      ↓
┌─────────────────────────────────────────────────────────────┐
│  第三層: 執行前攔截 (Multi-Sig)                              │
│  - 若 requires_confirmation=true標記需人工確認            │
│  - 顯示候選列表讓人類選擇                                    │
└─────────────────────────────────────────────────────────────┘

K8s 命名規則 (RFC 1123)

規則 說明 範例
最大長度 63 字元 my-very-long-service-name-...
允許字元 小寫字母、數字、連字號 awoooi-api-v2
開頭結尾 必須是字母或數字 api-v1 -api-v1-
禁止 大寫、底線、點、特殊字元 API_Service.v1

靜態映射表

已知的 URL → Deployment 映射 (在 k8s_naming.py 中維護)

輸入 Deployment Namespace
api.awoooi.wooo.work awoooi-api awoooi-prod
awoooi.wooo.work awoooi-web awoooi-prod
wooo.work awoooi-web awoooi-prod

非 K8s 資源標記

以下主機不在 K8s 中,應跳過 kubectl 操作:

主機 類型 處理方式
prod-docker-188 Docker Container SKIP_K8S
192.168.0.188 VM Host SKIP_K8S
192.168.0.110 VM Host SKIP_K8S

實作檔案

檔案 功能
src/utils/k8s_naming.py 正規化函數、靜態映射表
src/services/resource_resolver.py 動態驗證器、模糊匹配
webhooks.py 入口呼叫正規化
openclaw.py 執行前驗證

API 契約

輸入格式

target_resource 欄位應盡可能使用 K8s 資源名稱:

{
  "target_resource": "awoooi-api",  // ✅ 優先
  "target_resource": "api.awoooi.wooo.work",  // ⚠️ 會被轉換
  "namespace": "awoooi-prod"
}

輸出格式 (ResolveResult)

@dataclass
class ResolveResult:
    success: bool              # 是否成功解析
    resource_name: str | None  # 解析後的名稱
    namespace: str | None      # 命名空間
    resource_type: ResourceType  # deployment/statefulset/pod
    confidence: float          # 0.0 - 1.0
    is_k8s_resource: bool      # 是否為 K8s 資源
    requires_confirmation: bool  # 是否需人工確認
    candidates: list[str]      # 候選列表 (多重匹配時)
    note: str | None           # 備註

後果

優點

  • 消除無效指令:所有 kubectl 指令在執行前都經過驗證
  • 智能容錯URL/域名自動轉換為正確的 K8s 名稱
  • 可觀測性:日誌記錄所有正規化和匹配過程
  • 可擴展:映射表可透過 Memory 或 DB 動態更新

缺點

  • 額外延遲:動態驗證需調用 K8s API (~50ms)
  • 維護成本:映射表需定期更新

風險

風險 緩解措施
K8s API 不可用 Fallback 到靜態映射表
模糊匹配錯誤 低信心度時標記需人工確認
映射表過時 定期審查 + 動態驗證為主

相關文件

  • feedback_api_path_naming.md - API 路徑命名規範
  • reference_four_hosts.md - 五主機架構
  • Skill 03 - OpenClaw 認知專家 (更新提醒)