三只貓
Rich Mindset Zone
richmindsetzone.com
← All posts

你嘅 K8s 會自動修復自己?

你以為你嘅 K8s 識自癒?事實係佢淨係識 reboot

大部分人行入 Kubernetes 嘅世界,第一個俾人 sell 嘅賣點就係「self-healing」。ReplicaSet 幫你 maintain desired replica count、Node 死咗會自動 reschedule Pod、Health check 失效會 restart——聽落好完美,好似請咗個唔使瞓嘅 DevOps engineer 咁。

但現實好快就打面。

你朝早起身,見到成個 production namespace 嘅 Pod 全部 CrashLoopBackOff。點解?因為你個 cert 尋晚 expired,service mesh 嘅 mTLS handshake 全部斷纜。K8s 嘅反應係咩?繼續 restart 啲 Pod,逼佢哋繼續撞同一幅牆,然後撞到 BackOff 越等越耐。呢個唔叫 self-healing,呢個叫 fucking stubborn retry。

另一個常見場景:你個 cluster 嘅 etcd 因為 disk latency 暴增而 degraded,control plane 開始半癱瘓。Deployment controller 收唔到 watch event,ReplicaSet 全部停擺。你成個 cluster 嘅「自癒能力」瞬間消失,因為自癒系統本身就係靠 control plane 運行。Recursive 死局。

呢個就係我哋要面對嘅核心問題:Kubernetes 只係識得喺佢認知範圍內做機械式修復。超出佢嘅抽象層——例如 certificate rotation、DNS resolution 失效、etcd 健康、storage class 爆 quota——佢就企咗喺度,等你 human 入嚟救。

K8s Mechanic:將故障排查變成 code

呢個 gap 正正係我同團隊 build K8s Mechanic 嘅原因。我哋嘅想法好簡單:Operator pattern 已經證明咗 control loop + reconciliation 係處理 infrastructure 問題嘅正確抽象。點解唔將同樣嘅 pattern 套落故障排查同修復度?

K8s Mechanic 嘅核心係一組 Custom Resource Definition:MechanicCheckMechanicRepairMechanicPolicy。你定義嘅唔係 alert rule,而係 diagnostic procedure。

例如當 cert 就嚟 expired,你會寫一個 MechanicCheck 去 check cert expiry、一個 MechanicRepair 去 call cert-manager renew、一個 MechanicPolicy 去決定係咪自動執行定係淨係 send notification:

apiVersion: mechanic.sh/v1alpha1
kind: MechanicCheck
metadata:
  name: tls-cert-expiry
spec:
  interval: 6h
  script: |
    kubectl get certificate -A -o json | jq '
      .items[] | select(.status.notAfter | fromdate < now + 86400 * 7)
      | {name: .metadata.name, namespace: .metadata.namespace, expires: .status.notAfter}'
  onFailure:
    - trigger: renew-tls-cert
---
apiVersion: mechanic.sh/v1alpha1
kind: MechanicRepair
metadata:
  name: renew-tls-cert
spec:
  action: |
    kubectl annotate certificate $NAME -n $NAMESPACE cert-manager.io/renew-before=24h
  maxRetries: 3
  cooldown: 1h

呢個 pattern 嘅威力在於:你唔需要寫一次性的 hotfix script,而係建立一個持續運行嘅自癒 control loop。Check → Detect → Diagnose → Repair → Verify,成個 cycle 行 Autonomous。

而真正令佢 powerful 嘅係事件關聯——一個 Pod 起唔到可以有 20 個 root cause,單點觀察根本無用。MechanicCheck 可以嵌套執行:先 check DNS、再 check cert、再 check storage,逐層排除,最後 pinpoint 真正嘅 culprit。呢個先係人腦做 incident response 嘅方式,只係而家用 code 自動化咗。

OpenCode RCA:唔使再凌晨三點開 war room

好,你而家有 K8s Mechanic 幫你做 automated repair,但更深層嘅問題係:好多故障唔係簡單嘅 check-pass-fail。你嘅 API latency 突然飆升、P95 latency 由 200ms 跳到 2s,但無任何 error,所有 Pod 都 healthy。呢種「grey failure」先係最難搞嘅。

呢個位就係 OpenCode RCA 嘅主戰場。

OpenCode RCA 嘅架構 base on Claude Code CLI 做 agentic root cause analysis。佢唔係傳統嘅 monitoring dashboard 等你去 drill down,而係一個主動嘅 AI investigator。當 alert trigger 之後,OpenCode RCA 會做以下嘢:

  1. Context gathering — 自動 pull 受影響 service 嘅 deployment history、最近的 git commits、更改咗嘅 ConfigMap、rollout status
  2. Hypothesis generation — 由 LLM(我哋用 Claude)根據 context 生成 3-5 個最可能嘅 root cause hypothesis,每個 hypothesis 帶一個驗證計劃
  3. Parallel verification — 一句話 spawn 5 個 background agent 同時驗證唔同 hypothesis:一個 check Prometheus metric correlation、一個 grep 最近 merged PR、一個 analyse istio 嘅 access log pattern、一個 inspect database connection pool metrics、一個 check upstream dependency health
  4. Root cause synthesis — 將所有結果合成一份 concise 嘅 incident report,連同 suggested remediation

我講個真實 case。上個月 production 有個 intermittent timeout,我哋 team 排查咗兩個鐘都搵唔到原因。OpenCode RCA 喺 47 秒內 pinpoint 到問題:一個 upstream Redis cluster 嘅 maxmemory-policy 被意外 set 咗做 allkeys-lru,導致近期 active 嘅 cache key 反而被 evict,令到 downstream 不斷去 DB 做 full query,connection pool 爆煲。修復方法就係改返做 volatile-lru 再 flush 一次。

47 秒 vs 120 分鐘。 呢個唔係 marginal improvement,呢個係 paradigm shift。

將 K8s Mechanic 同 OpenCode RCA 串聯成真正嘅自癒 loop

但最精彩嘅部分係當你將兩個系統串埋一齊。

K8s Mechanic 做第一層:已知故障模式嘅 automated detection + repair。OpenCode RCA 做第二層:未知故障模式嘅 deep investigation + 動態生成修復方案。而呢兩個 layer 之間有一條 feedback loop。

當 OpenCode RCA 成功診斷一個新嘅 root cause,佢會自動生成一個對應嘅 MechanicCheck + MechanicRepair template,apply 落 cluster。下一次同一 pattern 出現時,K8s Mechanic 就會直接 handle 到,唔使再行完整 RCA。隨住時間推移,你個 cluster 嘅「known failure repertoire」會不斷增長,system 會越嚟越 autonomous。

用 code 嘅概念去理解:OpenCode RCA 係你嘅 JIT compiler,處理 cold path 嘅新 pattern;K8s Mechanic 係你嘅 AOT compiled code,處理 hot path 嘅已知 pattern。Cold path 愈處理愈少,hot path 愈積愈多,system 整體 latency 同 human intervention 次數會 log-scale 下跌。

呢個亦係為何我堅持用「k8s-mechanic + versus-incident」呢個 stack 嘅原因。Versus-incident 提供咗一個 unified event bus,俾 MechanicCheck 嘅 failure event 同 OpenCode RCA 嘅 diagnosis result 可以互相 trigger,而唔係各自為政。

具體建議:你聽日可以做嘅三件事

如果你嘅 cluster 仲係嗰種「Alert → Slack Notification → 搵人睇」嘅 pattern,你都唔使一次過搞全套。以下係 gradual adoption path:

第一,唔使急住寫 MechanicCheck。 先做 audit:統計過去三個月嘅 on-call incident,分類邊啲係重複 pattern、邊啲係新 pattern。通常你會發現 70-80% 嘅 incident 係重複問題。呢啲就係你第一個 MechanicCheck 嘅 target。

第二,引入 RCA agent 做 post-mortem 自動化。 即使你未做好 automated repair,OpenCode RCA 嘅 post-incident analysis 已經有即時價值。每次 incident 完之後行一次,累積一個 structured root cause database。呢個 database 直接 feed 返俾 step 1 嘅 prioritization。

第三,建立一個「no-touch Monday」作為 KPI。 每個星期一,睇下有冇任何 incident 需要 human intervention。如果有,分析點解 automation 冇 handle 到,補返個 MechanicCheck 或者 refine RCA agent 嘅 prompt。呢個 rhythm 逼使你團隊持續投資自癒能力,而唔係做一次就放低。

到最後,你嘅目標唔係「zero incident」——啲嘢永遠都會壞。你嘅目標係「zero toil」:每個故障都變成 automation 嘅 training data,而唔係你凌晨三點起身嘅理由。

呢個先係真正嘅 self-healing infrastructure。