Files
awoooi/k8s/awoooi-prod/06-deployment-api.yaml
Your Name 40badc42cf
All checks were successful
Code Review / ai-code-review (push) Successful in 54s
E2E Health Check / e2e-health (push) Successful in 2m59s
fix(ollama): 恢復 GCP 優先路由(ADR-110 正式路由)
nginx proxy 架設完成後恢復原設計:
  GCP-A (110:11435 → 34.143.170.20:11434) → primary
  GCP-B (110:11436 → 34.21.145.224:11434) → secondary
  111 (192.168.0.111:11434)               → 兜底

OLLAMA_URL=http://192.168.0.110:11435
OLLAMA_SECONDARY_URL=http://192.168.0.110:11436
OLLAMA_FALLBACK_URL=http://192.168.0.111:11434

已用 kubectl set env 熱更新,不動 image tag。
兩台 GCP Ollama 均 200 OK(10 個模型各)。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 23:37:42 +08:00

200 lines
7.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AWOOOI Backend (FastAPI) Deployment
# 負責人: CIO
# 版本: v1.1
# 日期: 2026-03-20
# 更新: 2026-03-28 - 新增 startupProbe + revisionHistoryLimit:3 (Phase K0.5/K0.7)
apiVersion: apps/v1
kind: Deployment
metadata:
name: awoooi-api
namespace: awoooi-prod
labels:
app: awoooi-api
system: awoooi
environment: prod
spec:
replicas: 2
revisionHistoryLimit: 3
selector:
matchLabels:
app: awoooi-api
environment: prod
system: awoooi
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: awoooi-api
system: awoooi
environment: prod
spec:
# Phase 7: 使用 RBAC ServiceAccount (最小權限)
serviceAccountName: awoooi-executor
automountServiceAccountToken: true
# 2026-04-09 Claude Sonnet 4.6 Asia/Taipei: Bug #12 修正
# fsGroup=1000 讓 appuser(1000) 可讀取 defaultMode=0400 的 repair-ssh-key Secret
# SSH 要求 key 必須是 owner-only (0400/0600)0444 會被拒絕
securityContext:
fsGroup: 1000
containers:
- name: api
# 映像標籤由 CI/CD 動態注入 (格式: {sha}-{run_id})
# Harbor 金庫: 110 主機 (192.168.0.110:5000)
image: 192.168.0.110:5000/library/api:IMAGE_TAG_PLACEHOLDER
imagePullPolicy: Always
ports:
- containerPort: 8000
name: http
envFrom:
- configMapRef:
name: awoooi-config
- secretRef:
name: awoooi-secrets
# 2026-04-12 ogt: env 優先於 envFrom — 覆蓋 configmap 特定值
# 說明: Kubernetes env: 優先於 envFrom:,用於 live-patch 後需同步回 Git
env:
- name: USE_AI_ROUTER
value: "true"
- name: ENABLE_NEMOTRON_COLLABORATION
# 2026-04-15 ogt: 重新啟用 — asyncio.wait_for=120sOllama 已等待回應
value: "true"
- name: NEMOTRON_TIMEOUT_SECONDS
value: "55"
- name: TELEGRAM_ENABLE_POLLING
value: "true"
- name: OLLAMA_URL
value: "http://192.168.0.110:11435" # 2026-05-04 ogt: GCP-A primary via 110 nginx proxy11435 → 34.143.170.20:11434
- name: OLLAMA_SECONDARY_URL
value: "http://192.168.0.110:11436" # 2026-05-04 ogt: GCP-B secondary via 110 nginx proxy11436 → 34.21.145.224:11434
- name: OLLAMA_FALLBACK_URL
value: "http://192.168.0.111:11434" # 2026-05-04 ogt: 111 兜底K8s 內網直連GPU RTX
- name: OPENCLAW_DEFAULT_MODEL
value: "qwen2.5:7b-instruct"
- name: OPENCLAW_TIMEOUT
value: "120"
- name: AGENT_DIAGNOSTICIAN_TIMEOUT_SEC
value: "100"
- name: AGENT_SOLVER_TIMEOUT_SEC
value: "80"
- name: PROMETHEUS_MULTIPROC_DIR
value: "/tmp/awoooi-prometheus-multiproc"
# 2026-04-05 Claude Code: Sprint 3 — 掛載 SSH key 供 HostRepairAgent 使用
volumeMounts:
- name: repair-ssh-key
mountPath: /etc/repair-ssh
readOnly: true
# 2026-04-06 Claude Code: Sprint 3 Security Fix A1 — known_hosts
# 掛到獨立目錄,避免與 repair-ssh-key 的 mountPath 衝突
- name: repair-known-hosts
mountPath: /etc/repair-known-hosts
readOnly: true
# 2026-04-08 Claude Sonnet 4.6: Sprint 5.1 Guardrail — service registry YAML
# 掛載到 /app/ops/config/ 讓 _find_registry_path() 可找到
- name: service-registry
mountPath: /app/ops/config/service-registry.yaml
subPath: service-registry.yaml
readOnly: true
# MCP Phase 2a (2026-04-11 Claude Sonnet 4.6): SSH MCP key
# ssh_mcp_key → /run/secrets/ssh_mcp_key (SSH_KEY_PATH in ssh_provider.py)
# known_hosts → /etc/ssh-mcp/known_hosts (SSH_MCP_KNOWN_HOSTS_FILE)
- name: ssh-mcp-key
mountPath: /run/secrets/ssh_mcp_key
subPath: ssh_mcp_key
readOnly: true
- name: ssh-mcp-key
mountPath: /etc/ssh-mcp/known_hosts
subPath: known_hosts
readOnly: true
- name: prometheus-multiproc
mountPath: /tmp/awoooi-prometheus-multiproc
resources:
requests:
cpu: "200m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
livenessProbe:
httpGet:
path: /api/v1/health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /api/v1/health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
# Phase K0.5: Startup Probe (允許最多 60 秒啟動時間)
startupProbe:
httpGet:
path: /api/v1/health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 12
# 反親和性 - 分散到不同節點
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: awoooi-api
topologyKey: kubernetes.io/hostname
# 2026-04-05 Claude Code: Sprint 3 — repair SSH key (defaultMode 0400)
volumes:
- name: repair-ssh-key
secret:
secretName: awoooi-repair-ssh-key
defaultMode: 0400 # 八進位 0400 = 十進位 256 = r-------- (owner read-only)
# 2026-04-06 Claude Code: Sprint 3 Security Fix A1
# optional: true — CD 首次跑時建立 secretPod 不阻塞等待
- name: repair-known-hosts
secret:
secretName: awoooi-repair-known-hosts
optional: true
# 2026-04-08 Claude Sonnet 4.6: Sprint 5.1 Guardrail — service registry
- name: service-registry
configMap:
name: service-registry
# MCP Phase 2a (2026-04-11 Claude Sonnet 4.6): SSH MCP key
# optional: true — SSH MCP 預設關閉Secret 不存在時 Pod 不阻塞
- name: ssh-mcp-key
secret:
secretName: ssh-mcp-key
defaultMode: 0400
optional: true
- name: prometheus-multiproc
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: awoooi-api-svc
namespace: awoooi-prod
labels:
app: awoooi-api
spec:
type: NodePort
selector:
app: awoooi-api
ports:
- port: 8000
targetPort: 8000
nodePort: 32334
name: http