Files
awoooi/k8s/drift-cronjob.yaml
OG T 2c6ed4e9cf
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 14m36s
fix(k8s): 修復 ArgoCD probe 失敗 + drift-scanner egress 封鎖
問題 1 — ArgoCD "All connection attempts failed":
- ARGOCD_URL 指向 192.168.0.120:30443,但 node 120 kube-proxy 對
  30443 有路由 bug(ArgoCD pod 在 121)
- 修復: ARGOCD_URL → 192.168.0.121:30443
- NetworkPolicy: 補白名單 192.168.0.121/32:30443
- NetworkPolicy: 補白名單 192.168.0.125/32:30443 (keepalived VIP)

問題 2 — drift-scanner Error x5 / 系統沉默 9.4h:
- CronJob pod template 缺少 system=awoooi label
- default-deny-all 封鎖所有 egress,allow-required-egress 僅對
  system=awoooi pods 生效
- 修復: drift-cronjob pod template 新增 system: awoooi

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 15:28:52 +08:00

79 lines
3.3 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.
# Config Drift Detection CronJob - Phase 25 P2
# 每小時掃描 awoooi-prod namespace 的配置漂移
#
# 建立時間: 2026-04-04 (台北時區)
# 建立者: Claude Code (Phase 25 P2)
# 關聯設計: docs/superpowers/specs/2026-04-04-nemotron-active-defense-design.md 方向三
# 關聯 ADR: 待起草 ADR-057
#
# 部署: kubectl apply -f k8s/drift-cronjob.yaml -n awoooi-prod
# 手動觸發: kubectl create job --from=cronjob/drift-scanner drift-scan-manual -n awoooi-prod
# 查看 log: kubectl logs -l job-name=drift-scanner -n awoooi-prod
apiVersion: batch/v1
kind: CronJob
metadata:
name: drift-scanner
namespace: awoooi-prod
labels:
app: awoooi
component: drift-scanner
phase: "25"
annotations:
# 2026-04-04 ogt: Phase 25 P2 — Config Drift Detection
description: "每小時掃描 K8s 配置漂移,由 Nemotron 做意圖分析"
spec:
# 每小時整點執行(台北時間 = UTC+8schedule 用 UTC
schedule: "0 * * * *"
concurrencyPolicy: Forbid # 禁止並發:上次未完成則跳過
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
startingDeadlineSeconds: 60 # 錯過時間窗口超過 60s 則跳過
jobTemplate:
spec:
backoffLimit: 0 # 失敗不重試(漂移掃描冪等,下次 cron 自動補掃)
activeDeadlineSeconds: 300 # 最長 5 分鐘
template:
metadata:
labels:
app: awoooi
component: drift-scanner
# 2026-04-14 Claude Sonnet 4.6: 補 system=awoooi — allow-required-egress 以此篩選
# 缺此 label 導致 default-deny-all 封鎖所有 egress系統沉默 9.4h 根因)
system: awoooi
spec:
restartPolicy: Never
# 2026-04-09 Claude Sonnet 4.6: awoooi-api SA 不存在,改用 default只需呼叫內部 API不需 K8s 權限)
serviceAccountName: default
containers:
- name: drift-scanner
# 使用 awoooi-api 鏡像(含 kubectl + Python 環境)
# 2026-04-09 Claude Sonnet 4.6: 改用內網 registry + 固定 SHA tag (禁止 latest)
image: 192.168.0.110:5000/awoooi/api:21567a7a6dbee7db2c0f59c265f80713ff5e6fe4
imagePullPolicy: Always
command:
- python
- -c
- |
import asyncio, httpx, os
API_URL = os.environ.get("INTERNAL_API_URL", "http://awoooi-api:8000")
async def run():
async with httpx.AsyncClient(timeout=240) as c:
r = await c.post(f"{API_URL}/api/v1/drift/internal/scan")
print(f"status={r.status_code} body={r.text[:200]}")
asyncio.run(run())
env:
# 2026-04-09 Claude Sonnet 4.6: ClusterIP 和 DNS 在 Job Pod 均不可達
# 改用 NodePort 直連 K3s worker node同 K8s_API_SERVER_URL 解法)
- name: INTERNAL_API_URL
value: "http://192.168.0.121:32334"
- name: DRIFT_SCAN_NAMESPACES
value: "awoooi-prod"
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "256Mi"