# K3s 優化深度討論會議記錄

> **日期**: 2026-03-28 (台北時間)
> **與會者**: 統帥 (CEO) + Claude Code (首席架構師)
> **主題**: K3s 生產級環境優化盤點與工作規劃
> **狀態**: 📋 詳細規劃完成

---

## 一、會議目標

1. 深度盤點 AWOOOI K3s 環境現況
2. 對照業界最佳實踐進行差距分析
3. 產出細化的工作清單（可直接執行）
4. 建立優先級與執行時程

---

## 二、環境現況深度盤點

### 2.1 叢集基礎資訊

| 項目 | 現況 | 評估 |
|------|------|------|
| **K3s 版本** | v1.34.5+k3s1 (2026-03) | ✅ 最新穩定版 |
| **Go 版本** | go1.24.13 | ✅ |
| **運行時間** | 2 週+ (since 2026-03-13) | ✅ 穩定 |
| **K3s 記憶體占用** | 24.4GB | ⚠️ 偏高，需觀察 |

### 2.2 節點配置詳情

| 節點 | IP | 角色 | CPU (cores) | CPU% | Memory | Memory% | Disk | Disk% |
|------|-----|------|-------------|------|--------|---------|------|-------|
| **mon (Master)** | 192.168.0.120 | control-plane | 626m | 5% | 6.7GB/32GB | 21% | 490GB LVM | 26% |
| **mon1 (Worker)** | 192.168.0.121 | worker | 368m | 3% | 5.8GB/32GB | 17% | 490GB LVM | 37% |

### 2.3 作業系統層配置

| 項目 | Master (mon) | Worker (mon1) | 建議值 | 狀態 |
|------|--------------|---------------|--------|------|
| **OS** | Ubuntu 22.04.5 | Ubuntu 22.04.5 | ✅ | ✅ |
| **Kernel** | 5.15.0-171 | 5.15.0-171 | LTS | ✅ |
| **Swap** | 8GB (38MB used) | 8GB (16MB used) | 關閉 | ⚠️ 需關閉 |
| **somaxconn** | 4096 | - | ≥4096 | ✅ |
| **file-max** | 9223372036854775807 | - | ≥1000000 | ✅ |
| **磁碟類型** | SSD (LVM) | SSD (LVM) | SSD | ✅ |

### 2.4 K3s 配置分析

| 配置項 | 現況 | 建議 | 狀態 |
|--------|------|------|------|
| **config.yaml** | ❌ 不存在 | 需建立 | 🔴 缺失 |
| **registries.yaml** | ❌ 不存在 | 需建立 (Harbor mirror) | 🔴 缺失 |
| **kube-reserved** | ❌ 未設定 | cpu=200m,memory=512Mi | 🔴 缺失 |
| **system-reserved** | ❌ 未設定 | cpu=200m,memory=512Mi | 🔴 缺失 |
| **eviction-hard** | 預設值 | 需明確設定 | ⚠️ 需確認 |
| **etcd-expose-metrics** | ❌ 未啟用 | true | 🔴 缺失 |
| **etcd 自動備份** | ❌ 無 | 每 6 小時 | 🔴 高風險 |

### 2.5 Namespace 現況

| Namespace | 用途 | 狀態 |
|-----------|------|------|
| **awoooi-prod** | 正式環境 AWOOOI | ✅ Active |
| **awoooi-sandbox** | 測試環境 | ✅ Active |
| **cnpg-system** | CloudNativePG Operator | ✅ Active |
| **monitoring** | Prometheus + Grafana | ✅ Active |
| **wooo-aiops-prod** | Legacy AIOPS (保留) | ⚠️ 待清理 |
| **wooo-aiops-uat** | Legacy AIOPS UAT | ⚠️ 待清理 |

### 2.6 awoooi-prod 詳細狀態

#### Deployments

| 名稱 | Replicas | Ready | Strategy | Anti-Affinity |
|------|----------|-------|----------|---------------|
| awoooi-api | 2/2 | ✅ | RollingUpdate | ✅ preferred |
| awoooi-web | 2/2 | ✅ | RollingUpdate | ✅ preferred |
| awoooi-worker | 1/1 | ✅ | RollingUpdate | ✅ preferred |

#### 資源配額使用

| 資源 | 使用量 | 上限 | 使用率 |
|------|--------|------|--------|
| limits.cpu | 4 | 8 | 50% |
| limits.memory | 4Gi | 16Gi | 25% |
| requests.cpu | 800m | 4 | 20% |
| requests.memory | 2Gi | 8Gi | 25% |
| pods | 6 | 20 | 30% |
| PVC | 0 | 10 | 0% |

#### 健康檢查配置

| 服務 | Liveness | Readiness | Startup | 評估 |
|------|----------|-----------|---------|------|
| awoooi-api | ✅ HTTP /health | ✅ HTTP /health | ❌ 無 | ⚠️ 需加 Startup |
| awoooi-web | ✅ HTTP / | ✅ HTTP / | ❌ 無 | ⚠️ 需加 Startup |
| awoooi-worker | ✅ exec cat | ✅ exec cat | ❌ 無 | ⚠️ 需加 Startup |

#### 已知問題

| 問題 | 影響 | 原因 |
|------|------|------|
| awoooi-web-99cf84f9c-mxd7l ImagePullBackOff | 1 Pod 異常 | IMAGE_TAG_PLACEHOLDER 未替換 |
| Readiness probe timeout | 間歇性 | API 啟動緩慢 + 無 Startup Probe |

### 2.7 監控基礎設施

| 組件 | Namespace | 類型 | Port | 狀態 |
|------|-----------|------|------|------|
| **Prometheus** | monitoring | NodePort | 30090 | ✅ |
| **Grafana** | monitoring | NodePort | 30030 | ✅ |
| **Alertmanager** | monitoring | NodePort | 30093 | ✅ |
| **kube-state-metrics** | monitoring | NodePort | 30180 | ✅ |
| **node-exporter** | monitoring | DaemonSet | 9100 | ✅ |
| **metrics-server** | kube-system | ClusterIP | 443 | ✅ |

### 2.8 網路配置

| 項目 | 現況 | 評估 |
|------|------|------|
| **CNI** | Flannel (K3s 預設) | ✅ 適用 |
| **NetworkPolicy** | Zero Trust (Default Deny) | ✅ 完善 |
| **Service 類型** | NodePort (32334, 32335) | ✅ |
| **Ingress** | 僅 wooo-aiops-uat 有 | ⚠️ awoooi 無 |
| **CoreDNS** | 預設配置 + custom | ✅ |

### 2.9 儲存配置

| 項目 | 現況 | 評估 |
|------|------|------|
| **StorageClass** | local-path (預設) | ⚠️ 無分散式 |
| **Longhorn** | ❌ 未部署 | 🔴 缺失 |
| **PVC** | 0 個 (awoooi 無狀態) | ✅ 無需求 |
| **備份工具** | ❌ Velero 未部署 | 🔴 缺失 |

### 2.10 GitOps 與自動化

| 項目 | 現況 | 評估 |
|------|------|------|
| **ArgoCD** | ❌ 未部署 | 🔴 缺失 |
| **Flux** | ❌ 未部署 | - |
| **HelmChart CRD** | ❌ 無使用 | - |
| **CI/CD 部署方式** | kubectl apply (GitHub Actions) | ⚠️ 非 GitOps |
| **Secrets 管理** | 明文 YAML (.gitignore) | ⚠️ 需加密 |

### 2.11 高可用與韌性

| 項目 | 現況 | 評估 |
|------|------|------|
| **Master 節點數** | 1 | 🔴 單點故障 |
| **etcd 模式** | Embedded | ✅ |
| **etcd 備份** | ❌ 無 | 🔴 高風險 |
| **HPA** | ❌ awoooi 無 | ⚠️ 需評估 |
| **PDB** | ❌ awoooi 無 | 🔴 缺失 |
| **VPA** | ❌ 未部署 | ⚠️ 需部署 |
| **Node Problem Detector** | ❌ 未部署 | ⚠️ 缺失 |
| **Kured** | ❌ 未部署 | ⚠️ 缺失 |
| **Descheduler** | ❌ 未部署 | ⚠️ 缺失 |

---

## 三、差距分析 (討論方案 vs 專案現況)

### 3.1 討論提及的優化項目對照

| # | 討論建議 | 專案現況 | 差距等級 | 說明 |
|---|---------|---------|---------|------|
| 1 | 3-Master HA (embedded etcd) | 1 Master | 🔴 高 | 單點故障風險 |
| 2 | 外接資料庫 (PostgreSQL/MySQL) | 可用 (188 PostgreSQL) | ⚠️ 可選 | 已有基礎設施 |
| 3 | 負載平衡器 (HAProxy) | 無 | ⚠️ 中 | 單 Master 不需要 |
| 4 | 關閉 Swap | 開啟 (兩節點各 8GB) | 🔴 高 | 需關閉 |
| 5 | kube-reserved | 未設定 | 🔴 高 | 需設定 |
| 6 | system-reserved | 未設定 | 🔴 高 | 需設定 |
| 7 | sysctl 優化 | somaxconn=4096 ✅ | ✅ 已達標 | - |
| 8 | Longhorn 分散式儲存 | local-path | ⚠️ 中 | 目前無狀態 |
| 9 | ArgoCD GitOps | kubectl apply | 🔴 高 | 需部署 |
| 10 | Sealed Secrets | 明文 YAML | ⚠️ 中 | 需加密 |
| 11 | VPA 自動資源調整 | 未部署 | ⚠️ 中 | 需部署 |
| 12 | Node Problem Detector | 未部署 | ⚠️ 中 | 需部署 |
| 13 | Kured 自動重啟 | 未部署 | ⚠️ 低 | 可延後 |
| 14 | Descheduler 負載均衡 | 未部署 | ⚠️ 低 | 可延後 |
| 15 | Velero 備份 | 未部署 | 🔴 高 | 需部署 |
| 16 | etcd 定期備份 | 無 | 🔴 高 | 需設定 |
| 17 | Startup Probe | 無 | ⚠️ 中 | 需新增 |
| 18 | PodDisruptionBudget | awoooi 無 | 🔴 高 | 需新增 |
| 19 | HPA 水平擴展 | awoooi 無 | ⚠️ 中 | 需評估 |
| 20 | 漸進式交付 (Argo Rollouts) | 無 | ⚠️ 低 | 進階功能 |
| 21 | Service Mesh (Linkerd) | 無 | ⚠️ 低 | NetworkPolicy 已補位 |
| 22 | CloudNativePG | ✅ 已部署 | ✅ 完成 | - |
| 23 | Prometheus + Grafana | ✅ 已部署 | ✅ 完成 | - |
| 24 | kube-state-metrics | ✅ 已部署 | ✅ 完成 | - |
| 25 | node-exporter | ✅ DaemonSet | ✅ 完成 | - |
| 26 | metrics-server | ✅ 已部署 | ✅ 完成 | - |
| 27 | NetworkPolicy Zero Trust | ✅ Default Deny | ✅ 完成 | - |
| 28 | RBAC 最小權限 | ✅ awoooi-executor | ✅ 完成 | - |
| 29 | 反親和性 | ✅ preferred | ✅ 完成 | - |
| 30 | 滾動更新策略 | ✅ maxSurge=1 | ✅ 完成 | - |
| 31 | Harbor 私有倉庫 | ✅ 192.168.0.110:5000 | ✅ 完成 | - |
| 32 | 映像標籤版本化 | ✅ {sha}-{run_id} | ✅ 完成 | - |

### 3.2 差距統計

| 等級 | 數量 | 佔比 | 說明 |
|------|------|------|------|
| 🔴 高風險 | 8 | 25% | 需立即處理 |
| ⚠️ 中度 | 11 | 34% | 短期規劃 |
| ✅ 已完成 | 13 | 41% | 無需處理 |

---

## 四、細化工作清單

### Phase K0: 緊急修復 (P0) - 預計 4 小時

#### K0.1 關閉 Swap (兩個節點)

| # | 任務 | 節點 | 命令/動作 | 驗證方式 | 估時 |
|---|------|------|-----------|---------|------|
| K0.1.1 | 停止 Swap | mon | `sudo swapoff -a` | `swapon --show` 無輸出 | 1m |
| K0.1.2 | 永久禁用 Swap | mon | `sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab` | `cat /etc/fstab` 確認註解 | 1m |
| K0.1.3 | 停止 Swap | mon1 | `sudo swapoff -a` | `swapon --show` 無輸出 | 1m |
| K0.1.4 | 永久禁用 Swap | mon1 | `sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab` | `cat /etc/fstab` 確認註解 | 1m |
| K0.1.5 | 重啟驗證 (可選) | 兩節點 | 計畫性重啟確認 Swap 不自動啟用 | `free -h` Swap 為 0 | 10m |

#### K0.2 建立 K3s 配置 (Master)

| # | 任務 | 檔案 | 內容 | 估時 |
|---|------|------|------|------|
| K0.2.1 | 建立 config.yaml | `/etc/rancher/k3s/config.yaml` | 見下方 | 5m |
| K0.2.2 | 建立 registries.yaml | `/etc/rancher/k3s/registries.yaml` | Harbor mirror 配置 | 5m |
| K0.2.3 | 重啟 K3s 服務 | - | `sudo systemctl restart k3s` | 2m |
| K0.2.4 | 驗證配置生效 | - | `kubectl describe node mon` 檢查 Allocatable | 3m |

**config.yaml 內容:**
```yaml
# /etc/rancher/k3s/config.yaml
# AWOOOI K3s Master 配置
# 建立者: Claude Code (首席架構師)
# 日期: 2026-03-28

# Kubelet 資源預留
kubelet-arg:
  - "kube-reserved=cpu=200m,memory=512Mi"
  - "system-reserved=cpu=200m,memory=512Mi"
  - "eviction-hard=memory.available<256Mi,nodefs.available<10%,imagefs.available<15%"

# etcd 監控
etcd-expose-metrics: true

# 叢集 CIDR (確認現有)
cluster-cidr: "10.42.0.0/16"
service-cidr: "10.43.0.0/16"

# 節點標籤
node-label:
  - "environment=production"
  - "system=awoooi"
```

**registries.yaml 內容:**
```yaml
# /etc/rancher/k3s/registries.yaml
# Harbor 私有倉庫配置

mirrors:
  "192.168.0.110:5000":
    endpoint:
      - "http://192.168.0.110:5000"

configs:
  "192.168.0.110:5000":
    tls:
      insecure_skip_verify: true
```

#### K0.3 設定 etcd 自動備份

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K0.3.1 | 建立備份目錄 | `sudo mkdir -p /var/lib/rancher/k3s/server/db/snapshots-backup` | 1m |
| K0.3.2 | 建立備份腳本 | `/usr/local/bin/k3s-etcd-backup.sh` | 5m |
| K0.3.3 | 設定 crontab | `0 */6 * * *` 每 6 小時 | 2m |
| K0.3.4 | 手動測試備份 | 執行腳本確認成功 | 3m |
| K0.3.5 | 設定備份清理 | 保留最近 7 天 | 2m |

**備份腳本:**
```bash
#!/bin/bash
# /usr/local/bin/k3s-etcd-backup.sh
# K3s etcd 自動備份腳本

BACKUP_DIR="/var/lib/rancher/k3s/server/db/snapshots-backup"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_NAME="awoooi-etcd-${TIMESTAMP}"

# 執行備份
/usr/local/bin/k3s etcd-snapshot save --name "${BACKUP_NAME}"

# 複製到備份目錄
cp /var/lib/rancher/k3s/server/db/snapshots/${BACKUP_NAME}* ${BACKUP_DIR}/

# 清理 7 天前的備份
find ${BACKUP_DIR} -name "awoooi-etcd-*" -mtime +7 -delete

echo "[$(date)] etcd backup completed: ${BACKUP_NAME}"
```

#### K0.4 新增 PodDisruptionBudget

| # | 任務 | 檔案 | 估時 |
|---|------|------|------|
| K0.4.1 | 建立 PDB YAML | `k8s/awoooi-prod/09-pdb.yaml` | 10m |
| K0.4.2 | 套用 PDB | `kubectl apply -f` | 2m |
| K0.4.3 | 驗證 PDB 生效 | `kubectl get pdb -n awoooi-prod` | 2m |

**09-pdb.yaml 內容:**
```yaml
# AWOOOI PodDisruptionBudget
# 確保滾動更新和節點維護時服務不中斷

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: awoooi-api-pdb
  namespace: awoooi-prod
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: awoooi-api

---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: awoooi-web-pdb
  namespace: awoooi-prod
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: awoooi-web
```

#### K0.5 新增 Startup Probe

| # | 任務 | 檔案 | 估時 |
|---|------|------|------|
| K0.5.1 | 修改 API Deployment | `k8s/awoooi-prod/06-deployment-api.yaml` | 10m |
| K0.5.2 | 修改 Web Deployment | `k8s/awoooi-prod/05-deployment-web.yaml` | 10m |
| K0.5.3 | 修改 Worker Deployment | `k8s/awoooi-prod/08-deployment-worker.yaml` | 10m |
| K0.5.4 | 套用變更 | `kubectl apply -f` | 5m |
| K0.5.5 | 觀察 Pod 啟動 | 確認無 Probe 失敗 | 10m |

**Startup Probe 配置 (API):**
```yaml
startupProbe:
  httpGet:
    path: /api/v1/health
    port: 8000
  initialDelaySeconds: 5
  periodSeconds: 5
  timeoutSeconds: 3
  failureThreshold: 30  # 5s * 30 = 150s 最大啟動時間
```

---

### Phase K1: 災難恢復 (P1) - 預計 8 小時

#### K1.1 部署 Velero 備份系統

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K1.1.1 | 建立 MinIO 儲存 (188) | Docker Compose 或直接安裝 | 30m |
| K1.1.2 | 安裝 Velero CLI | 下載並安裝到 Master | 10m |
| K1.1.3 | 部署 Velero 到 K3s | `velero install --provider aws ...` | 20m |
| K1.1.4 | 配置備份 Schedule | 每日備份 awoooi-prod | 15m |
| K1.1.5 | 測試備份/還原 | 建立測試 Pod，備份，刪除，還原 | 30m |
| K1.1.6 | 文檔化還原步驟 | 建立 DR 手冊 | 30m |

#### K1.2 評估 HA 架構方案

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K1.2.1 | 方案 A 評估 | 新增 2 台 Master (硬體需求) | 1h |
| K1.2.2 | 方案 B 評估 | 使用外接 PostgreSQL (188) | 1h |
| K1.2.3 | 成本/風險分析 | 建立比較表 | 30m |
| K1.2.4 | 統帥決策 | 選擇方案並規劃時程 | - |

**方案比較:**

| 項目 | 方案 A: 3-Master | 方案 B: 外接 PostgreSQL |
|------|-----------------|------------------------|
| 硬體成本 | 需 2 台新主機 | 無 (使用現有 188) |
| 複雜度 | 中 (etcd 叢集) | 低 (單資料庫) |
| 性能 | 最佳 | 良好 |
| 維護成本 | 高 (3 節點) | 低 |
| 建議 | 長期目標 | **短期推薦** |

---

### Phase K2: 自動化維運 (P2) - 預計 12 小時

#### K2.1 部署 ArgoCD (GitOps)

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K2.1.1 | 建立 argocd namespace | `kubectl create ns argocd` | 1m |
| K2.1.2 | 安裝 ArgoCD | `kubectl apply -f` 官方 YAML | 10m |
| K2.1.3 | 配置 Ingress/NodePort | 暴露 UI (建議 NodePort) | 15m |
| K2.1.4 | 取得初始密碼 | `kubectl get secret` | 2m |
| K2.1.5 | 連接 Git Repo | 設定 AWOOOI repo 連線 | 15m |
| K2.1.6 | 建立 Application | awoooi-prod 應用定義 | 30m |
| K2.1.7 | 測試自動同步 | push 變更確認同步 | 30m |
| K2.1.8 | 文檔化流程 | 建立 ArgoCD 使用指南 | 30m |

#### K2.2 部署 Sealed Secrets

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K2.2.1 | 安裝 kubeseal CLI | 本地安裝 | 5m |
| K2.2.2 | 部署 Controller | `kubectl apply -f` | 10m |
| K2.2.3 | 加密現有 Secrets | 重新打包 03-secrets.yaml | 30m |
| K2.2.4 | 移除 .gitignore 排除 | 讓加密 Secrets 進 Git | 5m |
| K2.2.5 | 測試解密 | 確認 Pod 可讀取 | 15m |

#### K2.3 部署 VPA (Vertical Pod Autoscaler)

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K2.3.1 | 安裝 VPA 組件 | `kubectl apply -f` | 10m |
| K2.3.2 | 建立 VPA 資源 | awoooi-api, web, worker | 15m |
| K2.3.3 | 設定為 "Off" 模式 | 僅建議，不自動調整 | 5m |
| K2.3.4 | 觀察建議值 | 收集 1 週數據 | - |
| K2.3.5 | 調整 Deployment 資源 | 根據建議修改 | 30m |

#### K2.4 部署 Node Problem Detector

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K2.4.1 | 安裝 NPD | `kubectl apply -f` DaemonSet | 10m |
| K2.4.2 | 配置問題偵測規則 | 磁碟、記憶體、核心 | 20m |
| K2.4.3 | 整合 Alertmanager | 節點問題觸發告警 | 30m |
| K2.4.4 | 測試告警 | 模擬問題確認通知 | 15m |

---

### Phase K3: 儲存與 HPA (P3) - 預計 10 小時

#### K3.1 評估 Longhorn 需求

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K3.1.1 | 盤點有狀態需求 | 目前 AWOOOI 全無狀態 | 30m |
| K3.1.2 | 未來需求評估 | OpenClaw 遷入 K3s? | 30m |
| K3.1.3 | 決策 | 延後或立即部署 | - |

#### K3.2 配置 HPA (水平擴展)

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K3.2.1 | 建立 HPA YAML | `k8s/awoooi-prod/10-hpa.yaml` | 20m |
| K3.2.2 | 套用 HPA | API: 2-4, Web: 2-4 | 10m |
| K3.2.3 | 壓力測試 | 確認自動擴展 | 1h |
| K3.2.4 | 調整閾值 | 根據測試結果 | 30m |

**10-hpa.yaml 內容:**
```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
```

---

### Phase K4: 進階優化 (P4) - 預計 6 小時

#### K4.1 部署 Kured (自動重啟)

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K4.1.1 | 安裝 Kured | Helm 或 YAML | 15m |
| K4.1.2 | 配置維護窗口 | 凌晨 3-5 點 | 10m |
| K4.1.3 | 整合 Slack/Telegram 通知 | 重啟前通知 | 30m |
| K4.1.4 | 測試 | 建立 /var/run/reboot-required | 20m |

#### K4.2 部署 Descheduler

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K4.2.1 | 安裝 Descheduler | CronJob 模式 | 15m |
| K4.2.2 | 配置策略 | RemoveDuplicates, LowNodeUtilization | 20m |
| K4.2.3 | 測試遷移 | 觀察 Pod 重新調度 | 30m |

#### K4.3 清理 Legacy Namespace

| # | 任務 | 動作 | 估時 |
|---|------|------|------|
| K4.3.1 | 備份 wooo-aiops-uat | Velero backup | 15m |
| K4.3.2 | 停用服務 | scale to 0 | 10m |
| K4.3.3 | 確認無依賴 | 觀察 1 週 | - |
| K4.3.4 | 刪除 namespace | `kubectl delete ns` | 5m |
| K4.3.5 | 同樣處理 wooo-aiops-prod | 同上 | 30m |

---

## 五、工作總覽與時程

### 5.1 Phase 概覽

| Phase | 名稱 | 優先級 | 預估時間 | 前置條件 |
|-------|------|--------|----------|---------|
| **K0** | 緊急修復 | 🔴 P0 | 4h | 無 |
| **K1** | 災難恢復 | 🔴 P1 | 8h | K0 完成 |
| **K2** | 自動化維運 | 🟠 P2 | 12h | K0 完成 |
| **K3** | 儲存與 HPA | 🟡 P3 | 10h | K0 完成 |
| **K4** | 進階優化 | 🟢 P4 | 6h | K2 完成 |

### 5.2 建議執行時程

```
Week 1 (2026-03-28 ~ 04-03)
├── Day 1-2: Phase K0 (緊急修復)
│   ├── K0.1 關閉 Swap ✅
│   ├── K0.2 K3s 配置 ✅
│   ├── K0.3 etcd 備份 ✅
│   ├── K0.4 PDB ✅
│   └── K0.5 Startup Probe ✅
│
└── Day 3-5: Phase K1 (災難恢復)
    ├── K1.1 Velero
    └── K1.2 HA 評估

Week 2 (2026-04-04 ~ 04-10)
├── Day 1-3: Phase K2 (自動化維運)
│   ├── K2.1 ArgoCD
│   ├── K2.2 Sealed Secrets
│   ├── K2.3 VPA
│   └── K2.4 NPD
│
└── Day 4-5: Phase K3 (儲存與 HPA)
    ├── K3.1 Longhorn 評估
    └── K3.2 HPA

Week 3 (2026-04-11 ~ 04-17)
└── Phase K4 (進階優化)
    ├── K4.1 Kured
    ├── K4.2 Descheduler
    └── K4.3 Legacy 清理
```

### 5.3 任務統計

| 類別 | 任務數 | 預估總時數 |
|------|--------|-----------|
| 配置變更 | 15 | 3h |
| 新建檔案 | 8 | 4h |
| 部署工具 | 12 | 15h |
| 測試驗證 | 10 | 6h |
| 文檔 | 5 | 4h |
| **總計** | **50** | **~40h** |

---

## 六、風險與緩解

| 風險 | 影響 | 機率 | 緩解措施 |
|------|------|------|---------|
| K3s 重啟後 Pod 無法啟動 | 服務中斷 | 低 | 先在 mon1 測試配置 |
| Swap 關閉後記憶體不足 | OOMKill | 低 | 當前使用率 <25%，風險低 |
| etcd 備份失敗 | 資料遺失 | 中 | 設定監控告警 |
| ArgoCD 同步錯誤 | 部署異常 | 中 | 先用 Manual Sync |
| Velero 還原失敗 | DR 失效 | 中 | 定期測試還原 |

---

## 七、決策待定事項

| # | 決策點 | 選項 | 建議 | 狀態 |
|---|--------|------|------|------|
| 1 | HA 架構選擇 | A: 3-Master / B: 外接 PostgreSQL / C: 維持現狀 | B | ✅ **方案 B 已執行** (2026-03-28) |
| 2 | Longhorn 部署時機 | 立即 / 等有狀態需求 | 等待 | ⏳ 延後 (無狀態需求) |
| 3 | Legacy Namespace 清理 | 立即 / 觀察 1 個月 | 觀察後清理 | 🟡 待 Velero 部署後執行 |
| 4 | K0 執行時機 | 今天 / 週末維護窗口 | 今天開始 | ✅ **已完成** (2026-03-28) |

---

## 八、會議結論

### 8.1 現況評估

AWOOOI K3s 環境已具備 **41% 的生產級優化項目**，包括：
- ✅ 完整的監控基礎 (Prometheus/Grafana/Alertmanager)
- ✅ 零信任網路策略
- ✅ RBAC 最小權限
- ✅ 滾動更新策略
- ✅ 私有映像倉庫 (Harbor)

### 8.2 主要差距

| 差距 | 風險等級 | 處理建議 | 狀態 |
|------|---------|---------|------|
| 單 Master 架構 | 🔴 高 | 短期接受，中期改善 | ✅ **雙 CP 已完成** |
| Swap 開啟 | 🔴 高 | **立即關閉** | ✅ **已關閉** |
| 無資源預留 | 🔴 高 | **立即設定** | ✅ **已設定** |
| 無 etcd 備份 | 🔴 高 | **立即設定** | ✅ **已設定** |
| 無 GitOps | 🔴 高 | 2 週內部署 ArgoCD | ❌ K2 待執行 |
| 無 PDB | 🔴 高 | **立即建立** | ✅ **已建立** |
| 無 Startup Probe | ⚠️ 中 | **立即新增** | ✅ **已新增** |

### 8.3 下一步行動

1. **統帥確認**: 閱讀本會議記錄，決策待定事項
2. **首席架構師**: K0 Phase 準備執行
3. **工作追蹤**: 建立對應的 GitHub Issues / Memory

---

## 九、K3s 環境異常分析 (實測數據)

### 9.1 已識別的異常模式

根據實際 kubectl events 和 logs 分析，以下是 K3s 環境中**常見的異常狀況**：

#### 異常類型 1: Readiness Probe 失敗 (高頻)

| 指標 | 數據 |
|------|------|
| **發生頻率** | 每次部署時 |
| **影響範圍** | awoooi-api, awoooi-web |
| **根因** | 無 Startup Probe，應用啟動時間 > Readiness 等待時間 |

**實際錯誤訊息:**
```
Readiness probe failed: Get "http://10.42.0.51:8000/api/v1/health":
  dial tcp 10.42.0.51:8000: connect: connection refused
```

**解決方案:**
- 新增 Startup Probe (failureThreshold: 30, periodSeconds: 5)
- 調整 Readiness initialDelaySeconds: 10 → 15

---

#### 異常類型 2: ImagePullBackOff (持續中)

| 指標 | 數據 |
|------|------|
| **發生頻率** | 持續 8 小時 |
| **影響 Pod** | awoooi-web-99cf84f9c-mxd7l |
| **根因** | IMAGE_TAG_PLACEHOLDER 未替換 |

**實際錯誤:**
```
Error: ImagePullBackOff
Back-off pulling image "192.168.0.110:5000/library/web:IMAGE_TAG_PLACEHOLDER"
```

**解決方案:**
- 清理孤立 ReplicaSet: `kubectl delete rs awoooi-web-99cf84f9c -n awoooi-prod`
- CI/CD 流程驗證 image tag 替換

---

#### 異常類型 3: CNPG Controller 重啟 (11 次)

| 指標 | 數據 |
|------|------|
| **重啟次數** | 11 次 (最高) |
| **根因** | wooo-postgres-ha Pod 無法連線 |
| **影響** | Legacy namespace 持續產生錯誤日誌 |

**實際錯誤:**
```json
{"msg":"Cannot extract Pod status","error":"dial tcp 10.42.0.26:8000: connect: connection refused"}
```

**解決方案:**
- 清理 wooo-aiops-uat 的 PostgreSQL HA 叢集
- 或修復 NetworkPolicy 允許 CNPG 連線

---

#### 異常類型 4: Legacy Namespace Image Pull Secret 失敗

| 指標 | 數據 |
|------|------|
| **發生頻率** | 持續 |
| **影響 Namespace** | wooo-aiops-prod |
| **根因** | registry-secret 不存在或過期 |

**實際錯誤:**
```
Unable to retrieve some image pull secrets (registry-secret)
```

**解決方案:**
- 更新或刪除 wooo-aiops-prod namespace
- 如需保留，重新建立 registry-secret

---

#### 異常類型 5: Health Check 顯示主機 unreachable

| 指標 | 數據 |
|------|------|
| **發生頻率** | 間歇性 |
| **unreachable 主機** | 192.168.0.110, 192.168.0.120 |
| **根因** | NetworkPolicy 或網路逾時 |

**實際日誌:**
```json
{"overall_status": "unhealthy", "host_statuses": {
  "192.168.0.110": "unreachable",
  "192.168.0.120": "unreachable",
  "192.168.0.188": "degraded"
}}
```

**解決方案:**
- 檢查 NetworkPolicy egress 規則
- 增加 health check timeout
- 加入重試機制

---

### 9.2 異常統計摘要

| 異常類型 | 嚴重度 | 頻率 | 影響 | 需處理 |
|---------|--------|------|------|--------|
| Readiness Probe 失敗 | ⚠️ 中 | 高 | 部署延遲 | ✅ K0.5 |
| ImagePullBackOff | 🔴 高 | 持續 | Pod 無法啟動 | ✅ 立即 |
| CNPG 重啟 | ⚠️ 中 | 中 | 日誌噪音 | ✅ K4.3 |
| Image Pull Secret | ⚠️ 中 | 持續 | Legacy Pod 異常 | ✅ K4.3 |
| Host unreachable | ⚠️ 中 | 間歇 | Dashboard 顯示異常 | ⏳ 調查 |

---

## 十、網路架構深度討論

### 10.1 現況網路拓撲

```
                    ┌─────────────────────────────────────────────────────────────┐
                    │                     Internet                                 │
                    └─────────────────────────────────────────────────────────────┘
                                              │
                                              ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                         192.168.0.0/24 LAN                                       │
│                                                                                  │
│  ┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐            │
│  │ 192.168.0.188   │     │ 192.168.0.110   │     │ 192.168.0.112   │            │
│  │ AI+Web 中心    │     │ DevOps 金庫     │     │ Kali Security   │            │
│  │                 │     │                 │     │                 │            │
│  │ ┌─────────────┐│     │ ┌─────────────┐ │     │ ┌─────────────┐ │            │
│  │ │Nginx:443   ││◄────┼─│Harbor:5000  │ │     │ │Scanner:8080 │ │            │
│  │ │(SSL Term)  ││     │ │GH Runner    │ │     │ └─────────────┘ │            │
│  │ └─────────────┘│     │ │Sentry:9000  │ │     └─────────────────┘            │
│  │ ┌─────────────┐│     │ │Langfuse:3100│ │                                     │
│  │ │PostgreSQL  ││     │ └─────────────┘ │                                     │
│  │ │:5432       ││     └─────────────────┘                                     │
│  │ │Redis:6380  ││                                                              │
│  │ │Ollama:11434││     ┌─────────────────────────────────────────┐             │
│  │ │OpenClaw    ││     │           K3s Cluster                   │             │
│  │ │:8088       ││     │  ┌───────────────┐ ┌───────────────┐   │             │
│  │ └─────────────┘│     │  │192.168.0.120 │ │192.168.0.121  │   │             │
│  └─────────────────┘     │  │K3s Master    │ │K3s Worker     │   │             │
│          │               │  │              │ │               │   │             │
│          │               │  │ ┌──────────┐ │ │ ┌──────────┐  │   │             │
│          │               │  │ │API:32334 │ │ │ │API Pod   │  │   │             │
│          │               │  │ │Web:32335 │ │ │ │Web Pod   │  │   │             │
│          │               │  │ └──────────┘ │ │ └──────────┘  │   │             │
│          │               │  └───────────────┘ └───────────────┘   │             │
│          │               │        Pod CIDR: 10.42.0.0/16          │             │
│          │               │        Svc CIDR: 10.43.0.0/16          │             │
│          │               └─────────────────────────────────────────┘             │
│          │                              │                                        │
│          └──────────────────────────────┘                                        │
│                   流量路徑: 188 Nginx → 120 NodePort → Pod                       │
└─────────────────────────────────────────────────────────────────────────────────┘
```

### 10.2 網路架構問題分析

| # | 問題 | 現況 | 風險 | 建議 |
|---|------|------|------|------|
| 1 | **流量入口單點** | 188 Nginx | 188 故障 = 全站不可用 | 考慮 keepalived VIP |
| 2 | **K3s API 單入口** | 只有 120 | 無法 AA 故障轉移 | 需 VIP 或 LB |
| 3 | **NodePort 暴露** | 32334, 32335 | 安全性較低 | 可改 Ingress Controller |
| 4 | **無 Ingress** | awoooi-prod 無 | 無法 host-based 路由 | 部署 Traefik/Nginx Ingress |
| 5 | **CNI** | Flannel (預設) | 功能有限 | 若需 NetworkPolicy L7，考慮 Cilium |

### 10.3 網路架構方案討論

#### 方案 N1: 維持現狀 + VIP (最小改動)

```
變更:
1. 188 + 備用主機部署 keepalived → VIP (192.168.0.100)
2. K3s API VIP (192.168.0.125) - 120+121 keepalived

優點: 改動小，快速實施
缺點: 沒有自動故障轉移測試
```

#### 方案 N2: Traefik Ingress + 外部 LB

```
變更:
1. 啟用 K3s 內建 Traefik (目前停用)
2. 配置 Ingress 資源替代 NodePort
3. 188 Nginx 代理到 K3s Traefik

優點: 更靈活的路由規則
缺點: 需要調整 DNS 和 SSL 配置
```

#### 方案 N3: MetalLB + Ingress (進階)

```
變更:
1. 部署 MetalLB (L2 模式)
2. 分配 IP Pool: 192.168.0.200-210
3. Service 改為 LoadBalancer 類型
4. 188 Nginx 代理到 LB IP

優點: 雲端級 LB 體驗
缺點: 需要額外 IP 段，配置較複雜
```

### 10.4 建議網路架構方案

根據專案現況，**建議方案 N1 + 部分 N2**:

| 階段 | 動作 | 估時 |
|------|------|------|
| 短期 | 部署 keepalived VIP (K3s API) | 2h |
| 短期 | 清理 ImagePullBackOff Pod | 30m |
| 中期 | 啟用 Traefik + 配置 Ingress | 4h |
| 中期 | 188 Nginx 高可用 (可選) | 4h |

---

## 十一、部署策略討論：主機 vs VM vs K3s

### 11.1 現有服務部署分佈

| 層級 | 服務 | 主機 | 數量 |
|------|------|------|------|
| **主機直裝** | PostgreSQL, Nginx, GitHub Runner | 188, 110 | 4 |
| **Docker Compose** | OpenClaw, Redis, Ollama, SigNoz, Sentry | 188, 110 | 6 |
| **K3s Deployment** | AWOOOI API/Web/Worker | 120, 121 | 3 |
| **K3s StatefulSet** | (Legacy) wooo-postgres-ha | 120, 121 | 3 |

### 11.2 部署策略決策矩陣

| 服務類型 | 主機 | Docker | K3s | 建議 |
|---------|------|--------|-----|------|
| **核心基礎設施** (Harbor, Runner) | ✅ | ⚠️ | ❌ | 主機 |
| **有狀態資料庫** (PostgreSQL) | ✅ | ⚠️ | ⚠️ | 主機 (188) |
| **快取服務** (Redis) | ⚠️ | ✅ | ✅ | Docker 或 K3s |
| **AI 推論** (Ollama) | ⚠️ | ✅ | ❌ | Docker (GPU/大記憶體) |
| **無狀態 API** (AWOOOI) | ❌ | ⚠️ | ✅ | K3s |
| **監控觀測** (Prometheus, Grafana) | ❌ | ⚠️ | ✅ | K3s |
| **AI 大腦** (OpenClaw) | ⚠️ | ✅ | ⚠️ | Docker (獨立管理) |

### 11.3 是否需要 VM？

| 考量點 | 現況 | VM 優勢 | VM 劣勢 | 建議 |
|--------|------|---------|---------|------|
| **資源隔離** | 5 台實體主機 | 更細粒度隔離 | Hypervisor 開銷 | ❌ 不需要 |
| **快速複製** | Docker/K3s 已滿足 | 完整 OS 快照 | 啟動慢 | ❌ 不需要 |
| **硬體利用** | 32GB RAM/主機 | 動態分配 | 資源碎片化 | ❌ 不需要 |
| **災難恢復** | etcd 備份 + Velero | VM 快照 | 備份大 | ⚠️ 可選 |

**結論**: 以目前 5 台實體主機的規模，**不建議引入 VM 層**。
- K3s 已提供足夠的資源隔離和調度
- Docker Compose 用於需要獨立管理的服務
- VM 會增加 Hypervisor 開銷和管理複雜度

### 11.4 未來擴展建議

| 場景 | 觸發條件 | 建議行動 |
|------|---------|---------|
| K3s 資源不足 | CPU > 70% 或 Memory > 80% | 新增 K3s Worker 節點 |
| 需要 GPU | AI 推論加速 | 188 加裝 GPU + Docker 或 K3s GPU Operator |
| 高可用 PostgreSQL | 業務要求 0 停機 | CNPG 在 K3s 中部署，或 188 PostgreSQL + Repmgr |
| 多區域部署 | 需要異地備援 | 考慮雲端 K3s + 本地混合 |

---

## 十二、工作清單整合更新

### 12.1 新增立即處理項目

| # | 任務 | 優先級 | 估時 |
|---|------|--------|------|
| **K0.6** | 清理 ImagePullBackOff Pod | 🔴 P0 | 15m |
| **K0.7** | 清理孤立 ReplicaSet | 🔴 P0 | 15m |

**執行命令:**
```bash
# K0.6: 刪除異常 Pod
kubectl delete pod awoooi-web-99cf84f9c-mxd7l -n awoooi-prod

# K0.7: 清理舊 ReplicaSet (保留最新 3 個)
kubectl get rs -n awoooi-prod -o name | while read rs; do
  replicas=$(kubectl get $rs -n awoooi-prod -o jsonpath='{.spec.replicas}')
  if [ "$replicas" == "0" ]; then
    kubectl delete $rs -n awoooi-prod
  fi
done
```

### 12.2 網路架構相關工作

| Phase | 任務 | 優先級 | 估時 |
|-------|------|--------|------|
| **K-NET.1** | 部署 keepalived (120+121) | 🟠 P2 | 2h |
| **K-NET.2** | 配置 K3s API VIP | 🟠 P2 | 1h |
| **K-NET.3** | 啟用 Traefik Ingress | 🟡 P3 | 3h |
| **K-NET.4** | 配置 awoooi Ingress 資源 | 🟡 P3 | 1h |

### 12.3 完整 Phase 排程更新

```
Week 1 (2026-03-28 ~ 04-03)
├── Day 1: Phase K0 (緊急修復) ← 今天
│   ├── K0.1-K0.5 (原有)
│   ├── K0.6 清理 ImagePullBackOff ← 新增
│   └── K0.7 清理孤立 RS ← 新增
│
├── Day 2-3: Phase K-HA (HA 架構)
│   ├── K-HA.1 PostgreSQL 準備
│   ├── K-HA.2 備份
│   ├── K-HA.3 120 遷移
│   ├── K-HA.4 121 升級
│   └── K-HA.5 驗證
│
└── Day 4-5: Phase K-NET (網路)
    ├── K-NET.1 keepalived
    └── K-NET.2 VIP 配置

Week 2 (2026-04-04 ~ 04-10)
├── Phase K1 (Velero)
├── Phase K2 (ArgoCD, VPA)
└── Phase K-NET.3-4 (Ingress)

Week 3 (2026-04-11 ~ 04-17)
├── Phase K3 (HPA)
└── Phase K4 (Legacy 清理)
```

---

## 十三、附錄

### A. 參考文件

| 文件 | 路徑 |
|------|------|
| 部署層級決策 | `memory/feedback_deployment_layer_decision.md` |
| 五主機架構 | `memory/reference_four_hosts.md` |
| 部署拓撲 | `memory/feedback_deployment_topology.md` |
| K8s 資源命名 | `docs/adr/ADR-016-k8s-resource-naming.md` |

### B. 現有 K8s YAML 清單

```
k8s/awoooi-prod/
├── 01-namespace-quota.yaml    # ✅ 已配置
├── 02-network-policy.yaml     # ✅ 已配置
├── 03-secrets.yaml            # ⚠️ 需加密
├── 04-configmap.yaml          # ✅ 已配置
├── 05-deployment-web.yaml     # ⚠️ 需 Startup Probe
├── 06-deployment-api.yaml     # ⚠️ 需 Startup Probe
├── 07-rbac.yaml               # ✅ 已配置
├── 08-deployment-worker.yaml  # ⚠️ 需 Startup Probe
├── 09-pdb.yaml                # 🔴 需新建
├── 10-hpa.yaml                # 🔴 需新建
└── kustomization.yaml         # ✅ 已配置
```

---

**會議記錄完成時間**: 2026-03-28 03:30 (台北時間)
**記錄者**: Claude Code (首席架構師)
**審核者**: 待統帥審核
