- RED_ZONES.md: Tier 3/2 紅區清單 - setup-hooks.sh: Git Hook 安裝腳本 - infrastructure docs: 部署拓撲更新 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
11 KiB
11 KiB
AWOOOI 部署契約 (Deployment Contracts)
版本: v1.0 建立日期: 2026-03-20 負責人: CIO 強制等級: 施工前必須遵守
概述
此文件定義 AWOOOI 部署的「鐵律級」配置規範。 施工前必須確認此契約,否則禁止開始基建工作。
環境架構 (CEO 指示 #3)
⚠️ 重要: AWOOOI 只有兩個環境,不設 UAT
| 環境 | 用途 | 域名 | K8s Namespace | 備註 |
|---|---|---|---|---|
| Dev | 本機開發 | localhost:3000 |
- | 開發者本機 |
| Prod | 生產環境 | awoooi.wooo.work |
awoooi-prod |
唯一線上環境 |
與舊系統完全隔離
| 項目 | AWOOOI (新) | Legacy (舊) |
|---|---|---|
| 域名 | awoooi.wooo.work |
aiops.wooo.work |
| Namespace | awoooi-prod |
wooo-aiops |
| Frontend Port | 32335 | 31235 |
| API Port | 32334 | 31234 |
| OpenClaw Port | 8089 | 8088 |
| Redis DB | 10-15 | 0-9 |
CIO-001: K8s Namespace 資源配額
🎯 顧問深度討論 #3: 防止 Memory Leak 拖垮叢集
ResourceQuota 配置
# k8s/quotas/awoooi-prod-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: awoooi-prod-quota
namespace: awoooi-prod
spec:
hard:
# 計算資源上限 (叢集 40%)
requests.cpu: "4" # 4 cores
requests.memory: "8Gi" # 8GB
limits.cpu: "8" # 8 cores
limits.memory: "16Gi" # 16GB
# Pod 數量限制
pods: "50"
# 儲存限制
persistentvolumeclaims: "10"
requests.storage: "100Gi"
LimitRange 配置
# k8s/quotas/awoooi-prod-limits.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: awoooi-prod-limits
namespace: awoooi-prod
spec:
limits:
# 預設容器限制
- type: Container
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "2"
memory: "4Gi"
min:
cpu: "50m"
memory: "64Mi"
# Pod 總限制
- type: Pod
max:
cpu: "4"
memory: "8Gi"
強制規則
- 新 Deployment 必須指定 resources: 沒有 requests/limits 將被拒絕
- 禁止 BestEffort QoS: 所有 Pod 必須有明確資源定義
- 定期檢查: 每週檢查資源使用率,超過 70% 發出告警
CIO-002: Nginx SSE 長連線配置
🎯 顧問深度討論 #2: 防止 SSE 每 60 秒斷線
Nginx 配置範本
# k8s/nginx/awoooi-prod.conf
# 上游服務定義
upstream awoooi-api {
server awoooi-api-service:8000;
keepalive 32;
}
upstream awoooi-web {
server awoooi-web-service:3000;
keepalive 16;
}
server {
listen 443 ssl http2;
server_name awoooi.wooo.work;
# SSL 配置
ssl_certificate /etc/nginx/ssl/awoooi.crt;
ssl_certificate_key /etc/nginx/ssl/awoooi.key;
# === SSE 專用路由 (AI 思考串流) ===
location ~ ^/api/v1/(agent|dashboard)/stream {
proxy_pass http://awoooi-api;
# ⚠️ 關鍵: SSE 必要配置
proxy_buffering off; # 禁用緩衝 (打字機效果零延遲)
proxy_read_timeout 3600s; # 1 小時長連線
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
# HTTP/1.1 長連線
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Accel-Buffering no;
# 標準 Headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# === 一般 API 路由 ===
location /api/ {
proxy_pass http://awoooi-api;
proxy_http_version 1.1;
proxy_set_header Connection "keep-alive";
proxy_read_timeout 60s;
proxy_send_timeout 60s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# === 前端靜態資源 ===
location / {
proxy_pass http://awoooi-web;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 健康檢查 (不經認證)
location /health {
proxy_pass http://awoooi-api/health;
proxy_read_timeout 5s;
}
}
SSE 測試腳本
#!/bin/bash
# scripts/test-sse.sh
# 測試 SSE 連線是否正常
echo "Testing SSE connection to awoooi.wooo.work..."
timeout 120 curl -N \
-H "Accept: text/event-stream" \
-H "Authorization: Bearer $TOKEN" \
"https://awoooi.wooo.work/api/v1/agent/stream?prompt=test"
if [ $? -eq 124 ]; then
echo "✅ SSE connection held for 2 minutes (test passed)"
else
echo "❌ SSE connection dropped unexpectedly"
exit 1
fi
CIO-003: NetworkPolicy 零信任邊界
🎯 顧問深度討論 #1: Default Deny All 策略
預設拒絕策略
# k8s/network-policies/default-deny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: awoooi-prod
spec:
podSelector: {} # 套用到所有 Pod
policyTypes:
- Ingress
- Egress
允許清單 - Ingress
# k8s/network-policies/allow-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-nginx-to-services
namespace: awoooi-prod
spec:
podSelector:
matchLabels:
app: awoooi-api
policyTypes:
- Ingress
ingress:
# 只允許 Nginx Ingress Controller
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8000
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-nginx-to-web
namespace: awoooi-prod
spec:
podSelector:
matchLabels:
app: awoooi-web
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 3000
允許清單 - Egress
# k8s/network-policies/allow-egress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-services
namespace: awoooi-prod
spec:
podSelector:
matchLabels:
app: awoooi-api
policyTypes:
- Egress
egress:
# 允許訪問 PostgreSQL (192.168.0.188:5432)
- to:
- ipBlock:
cidr: 192.168.0.188/32
ports:
- protocol: TCP
port: 5432
# 允許訪問 Redis DB 10-15 (192.168.0.188:6380)
- to:
- ipBlock:
cidr: 192.168.0.188/32
ports:
- protocol: TCP
port: 6380
# 允許訪問 Ollama (192.168.0.188:11434)
- to:
- ipBlock:
cidr: 192.168.0.188/32
ports:
- protocol: TCP
port: 11434
# 允許訪問 OpenClaw AWOOOI (192.168.0.188:8089)
- to:
- ipBlock:
cidr: 192.168.0.188/32
ports:
- protocol: TCP
port: 8089
# 允許訪問 Kali Scanner (192.168.0.112:8080)
- to:
- ipBlock:
cidr: 192.168.0.112/32
ports:
- protocol: TCP
port: 8080
# 允許 DNS 解析
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
# 允許訪問外部 AI API (雲端備援)
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
ports:
- protocol: TCP
port: 443
禁止訪問 Legacy Namespace
# k8s/network-policies/deny-legacy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-access-to-legacy
namespace: awoooi-prod
spec:
podSelector: {}
policyTypes:
- Egress
egress:
# 明確拒絕 Legacy Namespace
- to:
- namespaceSelector:
matchLabels:
name: wooo-aiops
# 沒有 ports = 全部拒絕
監控與告警配置
Prometheus 告警規則
# k8s/monitoring/prometheus/awoooi-alerts.yaml
groups:
- name: awoooi-resource-alerts
rules:
# CPU 使用率告警
- alert: AWOOOIHighCPUUsage
expr: |
sum(rate(container_cpu_usage_seconds_total{namespace="awoooi-prod"}[5m]))
/ sum(kube_resourcequota{namespace="awoooi-prod", resource="limits.cpu"})
> 0.7
for: 5m
labels:
severity: warning
annotations:
summary: "AWOOOI CPU 使用率超過 70%"
description: "Namespace awoooi-prod 的 CPU 使用率已達 {{ $value | humanizePercentage }}"
# Memory 使用率告警
- alert: AWOOOIHighMemoryUsage
expr: |
sum(container_memory_working_set_bytes{namespace="awoooi-prod"})
/ sum(kube_resourcequota{namespace="awoooi-prod", resource="limits.memory"})
> 0.7
for: 5m
labels:
severity: warning
annotations:
summary: "AWOOOI Memory 使用率超過 70%"
# Pod 重啟告警
- alert: AWOOOIPodRestarting
expr: |
increase(kube_pod_container_status_restarts_total{namespace="awoooi-prod"}[1h]) > 3
for: 5m
labels:
severity: critical
annotations:
summary: "AWOOOI Pod 頻繁重啟"
description: "Pod {{ $labels.pod }} 在過去 1 小時重啟超過 3 次"
驗收清單
施工前確認
- ResourceQuota 已套用
- LimitRange 已套用
- Default Deny NetworkPolicy 已套用
- 允許清單 NetworkPolicy 已套用
- Nginx SSE 配置已驗證
- 告警規則已部署
施工後驗證
# 驗證 ResourceQuota
kubectl describe quota awoooi-prod-quota -n awoooi-prod
# 驗證 LimitRange
kubectl describe limitrange awoooi-prod-limits -n awoooi-prod
# 驗證 NetworkPolicy
kubectl get networkpolicy -n awoooi-prod
# 測試 SSE 連線
./scripts/test-sse.sh
# 測試 Legacy 隔離
kubectl exec -it deploy/awoooi-api -n awoooi-prod -- \
curl -s http://wooo-aiops-api.wooo-aiops:8000/health
# 預期: 連線失敗 (被 NetworkPolicy 阻擋)
變更記錄
| 日期 | 版本 | 變更 | 作者 |
|---|---|---|---|
| 2026-03-20 | v1.0 | 初版建立 | CIO |
此文件由 CIO 維護,基建施工前必須完整遵守。