docs: 新增稽核報告 + 靈感實驗室 + Runbook 更新

- AWOOOI_COMPREHENSIVE_AUDIT_2026Q1.md 全維度稽核
- INSPIRATION_LAB.md 靈感收集
- K3S-OPTIMIZATION-RUNBOOK.md 優化指南
- ADR-006 AI Fallback 策略更新

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-29 16:03:41 +08:00
parent 01d76df383
commit 95b46af986
6 changed files with 1713 additions and 51 deletions

View File

@@ -1,11 +1,11 @@
# K3s 優化實施 Runbook
> **版本**: 1.2
> **版本**: 2.0
> **建立日期**: 2026-03-28 (台北時間)
> **建立者**: Claude Code (首席架構師)
> **最後修改**: 2026-03-28 21:00 (台北時間)
> **最後修改**: 2026-03-28 20:45 (台北時間)
> **修改者**: Claude Code
> **狀態**: ✅ Phase K0 + K-NET + K-CLEAN 完成
> **狀態**: ✅ K0/K-NET/K-HA/K-CLEAN 完成 | 📋 K1-K4 待執行 (~36h)
---
@@ -16,6 +16,8 @@
| 1.0 | 2026-03-28 | Claude Code | 初始建立 |
| 1.1 | 2026-03-28 | Claude Code | 新增安全執行順序、Alertmanager 靜音、穩定性驗證 |
| 1.2 | 2026-03-28 | Claude Code | **標記完成狀態**: K0 ✅ + K-NET ✅ + K-CLEAN ✅ |
| 1.3 | 2026-03-28 | Claude Code | **K-HA 完成**: 雙 Control-Plane + PostgreSQL Datastore |
| 2.0 | 2026-03-28 | Claude Code | **新增 K1-K4 完整實作步驟** + 15 項異常修復記錄 |
---
@@ -25,10 +27,14 @@
1. [環境基線](#1-環境基線)
2. [Phase K0: 緊急修復](#2-phase-k0-緊急修復) ✅ **已完成**
3. [Phase K-NET: 網路架構 (keepalived)](#3-phase-k-net-網路架構) ✅ **已完成**
4. [Phase K-HA: HA 升級](#4-phase-k-ha-ha-升級) 📋 **待規劃**
4. [Phase K-HA: HA 升級](#4-phase-k-ha-ha-升級) **已完成**
5. [Phase K-CLEAN: 清理腳本](#5-phase-k-clean-清理腳本) ✅ **已完成**
6. [驗證檢查清單](#6-驗證檢查清單)
7. [回滾程序](#7-回滾程序)
6. [Phase K1: 災難恢復 (Velero)](#6-phase-k1-災難恢復) ❌ **待執行**
7. [Phase K2: 自動化維運 (ArgoCD/VPA/NPD)](#7-phase-k2-自動化維運) ❌ **待執行**
8. [Phase K3: 儲存與 HPA](#8-phase-k3-儲存與-hpa) ❌ **待執行**
9. [Phase K4: 進階優化 (Kured/Descheduler)](#9-phase-k4-進階優化) ❌ **待執行**
10. [驗證檢查清單](#10-驗證檢查清單)
11. [回滾程序](#11-回滾程序)
---
@@ -991,9 +997,49 @@ curl -sk https://192.168.0.125:6443/healthz
---
## 4. Phase K-HA: HA 升級 📋 待規劃
## 4. Phase K-HA: HA 升級 ✅ 已完成
> **狀態**: ✅ 2026-03-28 19:35 完成
> **執行者**: Claude Code + 統帥
> **停機時間**: ~20 分鐘
### K-HA 執行結果摘要
| 步驟 | 說明 | 狀態 |
|------|------|------|
| K-HA.1 | PostgreSQL 建立 (188:5432) | ✅ k3s_datastore + k3s_admin |
| K-HA.2 | SQLite 備份 | ✅ state.db.pre-ha-* |
| K-HA.3 | 120 datastore-endpoint 配置 | ✅ 重啟成功 |
| K-HA.4 | 121 Agent→Server 升級 | ✅ 雙 Control-Plane |
| K-HA.5 | 服務重部署 | ✅ CD force_deploy |
| K-HA.6 | 健康驗證 | ✅ 所有組件 up |
### 架構變更
```
遷移前:
120 (Server/Control-Plane) ─── SQLite (Kine)
121 (Agent/Worker)
遷移後:
120 (Server/Control-Plane) ─┬─ PostgreSQL (188:5432/k3s_datastore)
121 (Server/Control-Plane) ─┘
VIP: 192.168.0.125 (keepalived)
```
### 修復過程中的問題
| 問題 | 解決方案 |
|------|----------|
| SENTRY_DSN "CHANGE_ME" | 改為空字串 |
| DATABASE_URL 缺 +asyncpg | 修正為 `postgresql+asyncpg://` |
| awoooi DB 密碼不符 | 更新 PostgreSQL 使用者密碼 |
| kubeconfig 權限 | K3s 重啟後需重新設定 |
---
### K-HA 原規劃內容 (已執行)
> **狀態**: 另案規劃 (需維護窗口 30+ 分鐘)
> **前置條件**: PostgreSQL 準備、完整備份、通知用戶
> **風險等級**: 🔴 高風險
@@ -1191,9 +1237,384 @@ echo "=== 清理完成 ==="
---
## 6. 驗證檢查清單
## 6. Phase K1: 災難恢復 (P1) - 8h ❌ 未開始
### 6.1 Phase K0 驗證
> **狀態**: 📋 待執行
> **前置條件**: K0 完成 ✅
> **預估時間**: 8 小時
### 6.1 K1.1 - 部署 Velero 備份系統
#### 6.1.1 建立 MinIO 儲存 (188) - 30m
```bash
# SSH 到 188
ssh ollama@192.168.0.188
# 建立 MinIO 目錄
sudo mkdir -p /data/minio
sudo chown -R 1000:1000 /data/minio
# Docker Compose 方式部署
cat > ~/minio/docker-compose.yml << 'EOF'
version: '3.8'
services:
minio:
image: minio/minio:RELEASE.2024-03-26T22-10-45Z
container_name: minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minio_admin
MINIO_ROOT_PASSWORD: Minio_Secure_2026!
volumes:
- /data/minio:/data
ports:
- "9000:9000"
- "9001:9001"
restart: unless-stopped
EOF
cd ~/minio && docker-compose up -d
# 驗證
curl http://192.168.0.188:9000/minio/health/live
```
#### 6.1.2 安裝 Velero CLI - 10m
```bash
# 在 120 (Master) 上執行
wget https://github.com/vmware-tanzu/velero/releases/download/v1.13.0/velero-v1.13.0-linux-amd64.tar.gz
tar -xvf velero-v1.13.0-linux-amd64.tar.gz
sudo mv velero-v1.13.0-linux-amd64/velero /usr/local/bin/
velero version
```
#### 6.1.3 部署 Velero 到 K3s - 20m
```bash
# 建立 credentials 檔案
cat > /tmp/credentials-velero << 'EOF'
[default]
aws_access_key_id=minio_admin
aws_secret_access_key=Minio_Secure_2026!
EOF
# 安裝 Velero
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.9.0 \
--bucket velero-backups \
--secret-file /tmp/credentials-velero \
--backup-location-config region=minio,s3ForcePathStyle=true,s3Url=http://192.168.0.188:9000 \
--use-volume-snapshots=false
# 驗證
kubectl get pods -n velero
velero backup-location get
```
#### 6.1.4 配置備份 Schedule - 15m
```bash
# 每日凌晨 3 點備份 awoooi-prod
velero schedule create awoooi-daily \
--schedule="0 3 * * *" \
--include-namespaces awoooi-prod \
--ttl 168h
# 驗證
velero schedule get
```
#### 6.1.5 測試備份/還原 - 30m
```bash
# 手動觸發備份
velero backup create awoooi-test-$(date +%Y%m%d) --include-namespaces awoooi-prod
# 查看備份狀態
velero backup describe awoooi-test-$(date +%Y%m%d)
# 模擬災難:刪除一個 ConfigMap (僅測試用)
kubectl get cm -n awoooi-prod
# 還原
velero restore create --from-backup awoooi-test-$(date +%Y%m%d)
# 驗證還原
velero restore describe <restore-name>
```
---
## 7. Phase K2: 自動化維運 (P2) - 12h ❌ 未開始
> **狀態**: 📋 待執行
> **前置條件**: K0 完成 ✅
> **預估時間**: 12 小時
### 7.1 K2.1 - 部署 ArgoCD (GitOps)
#### 7.1.1 安裝 ArgoCD - 15m
```bash
# 建立 namespace
kubectl create namespace argocd
# 安裝 ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# 暴露為 NodePort
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort", "ports": [{"port": 443, "nodePort": 30443}]}}'
# 取得初始密碼
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# 存取 UI: https://192.168.0.125:30443
```
#### 7.1.2 連接 Git Repo - 30m
```bash
# 下載 ArgoCD CLI
curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x /usr/local/bin/argocd
# 登入
argocd login 192.168.0.125:30443
# 新增 AWOOOI repo
argocd repo add https://github.com/your-org/awoooi.git \
--username <github-user> \
--password <github-token>
```
#### 7.1.3 建立 Application - 30m
```yaml
# argocd-awoooi-prod.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: awoooi-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/awoooi.git
targetRevision: main
path: k8s/awoooi-prod
destination:
server: https://kubernetes.default.svc
namespace: awoooi-prod
syncPolicy:
automated:
prune: true
selfHeal: true
```
### 7.2 K2.2 - 部署 Sealed Secrets
```bash
# 安裝 kubeseal CLI
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.26.0/kubeseal-0.26.0-linux-amd64.tar.gz
tar -xvf kubeseal-0.26.0-linux-amd64.tar.gz
sudo mv kubeseal /usr/local/bin/
# 部署 Controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.26.0/controller.yaml
# 加密現有 Secret
kubeseal --format yaml < k8s/awoooi-prod/03-secrets.yaml > k8s/awoooi-prod/03-sealed-secrets.yaml
```
### 7.3 K2.3 - 部署 VPA
```bash
# 安裝 VPA
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-up.sh
# 建立 VPA 資源 (Off 模式 - 僅建議)
cat > k8s/awoooi-prod/11-vpa.yaml << 'EOF'
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: awoooi-api-vpa
namespace: awoooi-prod
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: awoooi-api
updatePolicy:
updateMode: "Off"
EOF
kubectl apply -f k8s/awoooi-prod/11-vpa.yaml
```
### 7.4 K2.4 - 部署 Node Problem Detector
```bash
# 安裝 NPD
kubectl apply -f https://raw.githubusercontent.com/kubernetes/node-problem-detector/master/deployment/node-problem-detector.yaml
# 驗證
kubectl get pods -n kube-system -l app=node-problem-detector
```
---
## 8. Phase K3: 儲存與 HPA (P3) - 10h ❌ 未開始
> **狀態**: 📋 待執行
> **前置條件**: K0 完成 ✅
> **預估時間**: 10 小時
### 8.1 K3.1 - Longhorn 評估
| 評估項 | 現況 | 決策 |
|--------|------|------|
| 有狀態需求 | AWOOOI 全無狀態 | 延後 |
| OpenClaw 遷入 | 保持容器層部署 | 暫不需要 |
**結論**: Longhorn 暫不部署,待有狀態需求時再評估
### 8.2 K3.2 - 配置 HPA
```yaml
# k8s/awoooi-prod/10-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: awoooi-api-hpa
namespace: awoooi-prod
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: awoooi-api
minReplicas: 2
maxReplicas: 4
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: awoooi-web-hpa
namespace: awoooi-prod
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: awoooi-web
minReplicas: 2
maxReplicas: 4
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
```
```bash
kubectl apply -f k8s/awoooi-prod/10-hpa.yaml
kubectl get hpa -n awoooi-prod
```
---
## 9. Phase K4: 進階優化 (P4) - 6h ❌ 未開始
> **狀態**: 📋 待執行
> **前置條件**: K2 完成
> **預估時間**: 6 小時
### 9.1 K4.1 - 部署 Kured
```bash
# 安裝 Kured
kubectl apply -f https://github.com/weaveworks/kured/releases/latest/download/kured-1.14.1-dockerhub.yaml
# 配置維護窗口 (凌晨 3-5 點)
kubectl patch daemonset kured -n kube-system --type=json -p='[
{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--start-time=03:00"},
{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--end-time=05:00"},
{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--time-zone=Asia/Taipei"}
]'
```
### 9.2 K4.2 - 部署 Descheduler
```yaml
# descheduler-policy.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: descheduler-policy
namespace: kube-system
data:
policy.yaml: |
apiVersion: "descheduler/v1alpha2"
kind: "DeschedulerPolicy"
profiles:
- name: default
pluginConfig:
- name: "RemoveDuplicates"
args:
excludeOwnerKinds:
- "DaemonSet"
- name: "LowNodeUtilization"
args:
thresholds:
cpu: 20
memory: 20
targetThresholds:
cpu: 50
memory: 50
```
### 9.3 K4.3 - 清理 Legacy Namespace
```bash
# 步驟 1: 先用 Velero 備份
velero backup create legacy-wooo-aiops-$(date +%Y%m%d) \
--include-namespaces wooo-aiops-uat,wooo-aiops-prod
# 步驟 2: 確認備份成功
velero backup describe legacy-wooo-aiops-$(date +%Y%m%d)
# 步驟 3: 停用服務 (觀察 1 週)
kubectl scale deploy --all -n wooo-aiops-uat --replicas=0
kubectl scale deploy --all -n wooo-aiops-prod --replicas=0
# 步驟 4: 確認無依賴後刪除
kubectl delete ns wooo-aiops-uat
kubectl delete ns wooo-aiops-prod
```
---
## 10. 驗證檢查清單
### 10.1 Phase K0 驗證
| # | 檢查項目 | 命令 | 預期結果 |
|---|---------|------|---------|
@@ -1206,7 +1627,7 @@ echo "=== 清理完成 ==="
| 7 | 無異常 Pod | `kubectl get pods -n awoooi-prod` | 全部 Running |
| 8 | 孤立 RS 清理 | `kubectl get rs -n awoooi-prod \| wc -l` | ≤ 9 |
### 6.2 Phase K-HA 驗證
### 10.2 Phase K-HA 驗證
| # | 檢查項目 | 命令 | 預期結果 |
|---|---------|------|---------|
@@ -1217,9 +1638,9 @@ echo "=== 清理完成 ==="
---
## 7. 回滾程序
## 11. 回滾程序
### 7.1 K0 回滾 (低風險)
### 11.1 K0 回滾 (低風險)
```bash
# 還原 fstab (重新啟用 Swap)
@@ -1231,7 +1652,7 @@ sudo mv /etc/rancher/k3s/config.yaml.backup /etc/rancher/k3s/config.yaml
sudo systemctl restart k3s
```
### 7.2 K-HA 回滾 (高風險)
### 11.2 K-HA 回滾 (高風險)
```bash
# 步驟 1: 停止 K3s (兩節點)
@@ -1261,7 +1682,7 @@ curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="agent" sh -s - \
### ✅ 實際執行紀錄 (2026-03-28)
```
Day 0 (2026-03-28) - Phase K0 + K-NET + K-CLEAN ✅ 全部完成
Day 0 (2026-03-28) - Phase K0 + K-NET + K-CLEAN + K-HA ✅ 全部完成
├── 09:00 - 統帥批准 Phase K0 ✅
├── 09:30 - K0.1 關閉 Swap (120 + 121) ✅
├── 10:00 - K0.2 config.yaml + registries.yaml ✅
@@ -1274,32 +1695,96 @@ Day 0 (2026-03-28) - Phase K0 + K-NET + K-CLEAN ✅ 全部完成
├── 15:00 - K-NET.3 VIP 192.168.0.125 啟用 ✅
├── 16:00 - K-VIP CI/CD 整合 (GitHub Secret) ✅
├── 18:00 - K-CLEAN 清理 (9 RS + 1 Job) ✅
├── 19:00 - Phase 20 CSRF 防護完成
├── 20:30 - SignOz OTEL 配置修正
── 21:00 - Runbook 狀態更新
├── 19:00 - K-HA.1 PostgreSQL k3s_datastore 建立
├── 19:15 - K-HA.2 SQLite 完整備份
── 19:25 - K-HA.3 120 遷移至 PostgreSQL
├── 19:35 - K-HA.4 121 升級為 Control-Plane ✅
├── 19:45 - K-HA 驗證 (雙節點 + Kine 552 records) ✅
├── 20:00 - 服務重部署 (CD force_deploy) ✅
├── 20:30 - 15 項異常長期修復完成 ✅
└── 21:00 - Runbook + Memory 狀態更新 ✅
```
### 📋 待規劃 (K-HA 需維護窗口)
### ✅ K-HA 已完成 (2026-03-28 19:35)
```
未定日期 - Phase K-HA (外接 PostgreSQL)
├── ?? - 維護窗口開始 (建議週末凌晨)
├── +15m - K-HA.1 PostgreSQL 準備 (188)
├── +30m - K-HA.2 完整備份
├── +60m - K-HA.3 120 遷移至 PostgreSQL
├── +90m - K-HA.4 121 升級為 Server
── +120m - 驗證 + 故障轉移測試
└── +150m - 維護窗口結束
2026-03-28 19:00-20:00 - Phase K-HA (外接 PostgreSQL) ✅ 完成
├── 19:00 - K-HA.1 PostgreSQL 準備 (188) ✅
├── 19:15 - K-HA.2 完整備份 ✅
├── 19:25 - K-HA.3 120 遷移至 PostgreSQL ✅
├── 19:35 - K-HA.4 121 升級為 Server ✅
├── 19:45 - 驗證 (Kine 552 records) ✅
── 20:00 - 服務重部署成功 ✅
```
Day 3+ (2026-03-31 ~ 04-03)
├── Phase K1: Velero
├── Phase K2: ArgoCD, VPA
└── Phase K-NET.3-4: Ingress
### 📋 待規劃 (會議目標尚未完成)
```
Week 2 (2026-03-31 ~ 04-04)
├── Phase K1: Velero 備份系統 (P1 - 6h)
│ ├── K1.1 部署 MinIO (188)
│ ├── K1.2 安裝 Velero
│ ├── K1.3 配置備份 Schedule
│ └── K1.4 測試備份/還原
├── Phase K2: 自動化維運 (P2 - 12h)
│ ├── K2.1 部署 ArgoCD (GitOps)
│ ├── K2.2 部署 Sealed Secrets
│ ├── K2.3 部署 VPA (Off 模式)
│ └── K2.4 部署 NPD
└── Phase K3: 儲存與 HPA (P3 - 10h)
├── K3.1 評估 Longhorn (可延後)
└── K3.2 配置 HPA (API/Web 2-4)
Week 3 (2026-04-07 ~ 04-11)
└── Phase K4: 進階優化 (P4 - 6h)
├── K4.1 部署 Kured
├── K4.2 部署 Descheduler
└── K4.3 清理 Legacy NS
```
---
**Runbook 完成**: 2026-03-28 04:00 (台北時間)
---
## 附錄 B: K-HA 完成後異常修復 (15 項永久方案)
> **執行日期**: 2026-03-28 20:30 (台北時間)
> **範圍**: K-HA 遷移後全面日誌清查
| # | 異常 | 永久方案 | 狀態 |
|---|------|---------|------|
| 1 | ContainerHighMemory +Inf | 修復 alerts.yml 公式 (除零防護) | ✅ |
| 2 | WebsiteDown 誤報 | 移除錯誤 probe target | ✅ |
| 3 | Blackbox TCP 指向舊 IP | 更新為 VIP 192.168.0.125 | ✅ |
| 4 | ClawBot 8088 舊端口 | 改為 OpenClaw 8089 | ✅ |
| 5 | lewooogo-core exports 順序 | types 放最前 | ✅ |
| 6 | ConfigMap OTEL gRPC | 改為 HTTP 24318 | ✅ |
| 7 | Web Deployment 無 secretRef | 新增 Sentry DSN 存取 | ✅ |
| 8 | stats.py Router 層違規 | 完整 Service 層重構 | ✅ |
| 9 | Mock 測試殘留 | 刪除不合規測試 | ✅ |
| 10 | StatsService 無 Interface | 新增 IStatsService Protocol | ✅ |
| 11 | Worker 心跳機制 | 每 30 秒 touch 檔案 | ✅ |
| 12 | Worker liveness 探針 | 改為 mtime 檢查 | ✅ |
| 13 | AI_FALLBACK_ORDER 錯誤 | 改回 Ollama 優先 | ✅ |
| 14 | 架構文檔過時 | K-HA 章節全面更新 | ✅ |
| 15 | 服務端點分散 | 建立 SERVICE-ENDPOINTS.md | ✅ |
---
## 附錄 C: 已知限制
| 限制 | 說明 | 解決方案 |
|------|------|---------|
| VIP:32334 無回應 | keepalived 只做 L3 VIP 漂移 | 需 MetalLB 或 HAProxy |
| 120:32334 間歇性 | Pod 可能只在 121 運行 | AntiAffinity 已確保分散 |
| K3s API 401 | /healthz 需要認證是正常行為 | 使用 kubeconfig |
**結論**: 現有架構符合設計目標VIP 主要保障 K3s API (6443) 高可用
---
**Runbook 完成**: 2026-03-28 21:00 (台北時間)
**建立者**: Claude Code (首席架構師)
**狀態**: 待統帥批准執行
**狀態**: ✅ Phase K0 + K-NET + K-HA + K-CLEAN 執行完成