All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 33s
CD Pipeline / build-and-deploy (push) Successful in 4m38s
CD Pipeline / post-deploy-checks (push) Successful in 51s
146 lines
4.8 KiB
YAML
146 lines
4.8 KiB
YAML
# AWOOOI Signal Worker Deployment
|
||
# 負責人: CTO
|
||
# 版本: v1.3
|
||
# 日期: 2026-03-22
|
||
# 更新: 2026-03-28 v1.1 - 新增 startupProbe + revisionHistoryLimit:3 (Phase K0.5/K0.7)
|
||
# 更新: 2026-03-28 v1.2 - liveness 改為 mtime 檢查 (心跳機制長期方案)
|
||
# 更新: 2026-03-29 v1.3 - ADR-038/039 terminationGracePeriodSeconds:90 (Graceful Shutdown)
|
||
#
|
||
# Phase 6.5: Redis Streams 消費者
|
||
# 職責: 消費 awoooi:signals 串流,觸發 Incident Engine
|
||
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: awoooi-worker
|
||
namespace: awoooi-prod
|
||
labels:
|
||
app: awoooi-worker
|
||
system: awoooi
|
||
environment: prod
|
||
component: signal-processor
|
||
spec:
|
||
# Phase 8: Worker 啟用 - 處理 Redis Streams 訊號
|
||
replicas: 1
|
||
revisionHistoryLimit: 3
|
||
selector:
|
||
matchLabels:
|
||
app: awoooi-worker
|
||
environment: prod
|
||
system: awoooi
|
||
strategy:
|
||
type: RollingUpdate
|
||
rollingUpdate:
|
||
# 2026-07-01 Codex: DB role `awoooi` is capped at two connections and
|
||
# worker imports the same API DB stack. Do not run old+new worker pods
|
||
# during rollout until the DB role/pool budget is raised and verified.
|
||
maxSurge: 0
|
||
maxUnavailable: 1
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: awoooi-worker
|
||
system: awoooi
|
||
environment: prod
|
||
component: signal-processor
|
||
spec:
|
||
# 2026-07-01 Codex: keep hostname spread as a preference, not a hard
|
||
# scheduler blocker, so reboot recovery and GitOps rollouts do not deadlock.
|
||
topologySpreadConstraints:
|
||
- maxSkew: 1
|
||
topologyKey: kubernetes.io/hostname
|
||
whenUnsatisfiable: ScheduleAnyway
|
||
labelSelector:
|
||
matchLabels:
|
||
app: awoooi-worker
|
||
environment: prod
|
||
system: awoooi
|
||
# ADR-038/039: Graceful Shutdown (Worker 需要 75 秒完成清理)
|
||
serviceAccountName: awoooi-executor
|
||
automountServiceAccountToken: true
|
||
terminationGracePeriodSeconds: 90
|
||
containers:
|
||
- name: worker
|
||
# 映像標籤由 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
|
||
lifecycle:
|
||
preStop:
|
||
exec:
|
||
command: ["/bin/sh", "-c", "sleep 5"]
|
||
# Worker 模式啟動 (非 HTTP 服務)
|
||
command: ["python", "-m", "src.workers.signal_worker"]
|
||
envFrom:
|
||
- configMapRef:
|
||
name: awoooi-config
|
||
- secretRef:
|
||
name: awoooi-secrets
|
||
env:
|
||
- name: WORKER_MODE
|
||
value: "true"
|
||
- name: CONSUMER_GROUP
|
||
value: "awoooi-workers"
|
||
- name: CONSUMER_NAME
|
||
valueFrom:
|
||
fieldRef:
|
||
fieldPath: metadata.name
|
||
- name: DATABASE_POOL_SIZE
|
||
# 2026-07-01 Codex: keep worker DB usage inside the current
|
||
# production role connection budget during reboot rollouts.
|
||
value: "1"
|
||
- name: DATABASE_MAX_OVERFLOW
|
||
value: "0"
|
||
resources:
|
||
requests:
|
||
cpu: "100m"
|
||
memory: "256Mi"
|
||
limits:
|
||
cpu: "500m"
|
||
memory: "512Mi"
|
||
# Worker 健康檢查 (mtime 時間戳檢查 - 長期解決方案)
|
||
# 心跳機制:Worker 每 30 秒 touch 健康文件
|
||
# 探針檢查:文件 mtime 必須在 60 秒內
|
||
livenessProbe:
|
||
exec:
|
||
command:
|
||
- /bin/sh
|
||
- -c
|
||
- |
|
||
[ -f /tmp/worker-healthy ] && \
|
||
[ "$(find /tmp/worker-healthy -mmin -1 2>/dev/null)" ] && exit 0
|
||
exit 1
|
||
initialDelaySeconds: 30
|
||
periodSeconds: 15
|
||
timeoutSeconds: 5
|
||
failureThreshold: 3
|
||
readinessProbe:
|
||
exec:
|
||
command:
|
||
- cat
|
||
- /tmp/worker-ready
|
||
initialDelaySeconds: 10
|
||
periodSeconds: 10
|
||
timeoutSeconds: 5
|
||
failureThreshold: 3
|
||
# Phase K0.5: Startup Probe (允許最多 60 秒啟動時間)
|
||
startupProbe:
|
||
exec:
|
||
command:
|
||
- cat
|
||
- /tmp/worker-ready
|
||
initialDelaySeconds: 5
|
||
periodSeconds: 5
|
||
timeoutSeconds: 5
|
||
failureThreshold: 12
|
||
# 反親和性 - 分散到不同節點
|
||
affinity:
|
||
podAntiAffinity:
|
||
preferredDuringSchedulingIgnoredDuringExecution:
|
||
- weight: 100
|
||
podAffinityTerm:
|
||
labelSelector:
|
||
matchLabels:
|
||
app: awoooi-worker
|
||
topologyKey: kubernetes.io/hostname
|