# ADR-016: K8s 資源名稱規範與動態驗證 > **狀態**: Accepted > **日期**: 2026-03-26 > **決策者**: 統帥 + 首席架構師 ## 背景 在 E2E Tool Call 驗證中發現,AI (OpenClaw) 產生的 kubectl 指令會執行失敗,原因是資源名稱不正確: ```bash # 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 資源名稱: ```json { "target_resource": "awoooi-api", // ✅ 優先 "target_resource": "api.awoooi.wooo.work", // ⚠️ 會被轉換 "namespace": "awoooi-prod" } ``` ### 輸出格式 (ResolveResult) ```python @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 認知專家 (更新提醒)