
第二週開始談資源。這是我覺得 AI 工程師學 K8s 時,最容易被一般教學帶偏的地方:大部分教學用的範例是 web app,但 web app 的資源特性跟 agent 系統差很多。
一般 web app 的負載大致是「請求進來、處理、回應」,資源用量跟流量成正比,很好預測。agent 系統不是這樣。回頭盤點我那台開發機上的東西,至少有三種性格完全不同的資源型態。
OpenAB 的那幾隻 bot 就是這種。它們的特徵是:
這類負載最怕的不是資源不夠,而是被鄰居拖累。它自己用量很低,但只要主機資源被別的行程吃光,它就跟著卡死(Day 04 那次事件就是這樣)。
對應到 K8s 的講法:它需要「小的 request、小的 limit、重啟機制開著」,也就是 Deployment、replicas 設 1;QoS 最好做到 Guaranteed(request = limit),讓它在節點缺資源時最晚被 evict;要排程/搶佔優先權得另外設 PriorityClass。
Day 04 提到的 ARM64 QEMU build 就是代表。特徵是:
除了 build,我的機器上還有一類「批次 render」:用 headless Chrome 跑網頁自動化,或讓 agent 一口氣跑一批東西。性格一模一樣:短、重、可等、可重試。
這類負載最怕的是沒人排隊。兩個 build 同時跑,或 build 跟推論撞在一起,主機資源一下就見底。它需要的不是「保證資源」,而是「有秩序地排隊,資源不夠就先等」。
對應到 K8s:用 Job,request 照實填(讓 scheduler 知道它要多少),必要時用 priority class 排在 bot 後面。這是我覺得 K8s 明顯贏過 compose 的一點:compose 沒有排隊的概念,K8s 至少放不下時會讓 Job Pending,不會硬塞;真正的排隊要另外控 concurrency。
我的 Whisper 語音轉字幕引擎就是這一類。特徵是:
這一型最難搞,因為它既要「常駐在線」,又「吃很多資源」。你不能像 Job 那樣跑完就把 GPU 放掉(下次啟動又要等一陣子),但一直占著 GPU 不放,成本又很難看。
對應到 K8s:這是 GPU scheduling、node selector,以及「要不要 scale-to-zero」的主戰場。Day 08 會講我自架 Whisper 的經驗,Day 25 會談 GCP 上 Cloud Run GPU 與 GKE GPU node pool 的取捨。
因為一種部署法打不了天下。
在 compose 時代,我把這三種東西混在同一台主機、同一份 compose 檔裡,結果就是 Day 04 那樣:bot 被 build 拖垮、build 跟推論搶 CPU。
分清楚之後,每一類的痛點就很清楚:
| 型態 | 主要問題 | 需要的機制 |
|---|---|---|
| long-running bot | 被鄰居害死 | 資源保證、優先權 |
| burst build | 沒人排隊 | scheduler、Job、可等待 |
| GPU 推論 | 貴、啟動慢、記憶體是硬的 | GPU scheduling、預熱、scale 策略 |
接下來四天用實例一個一個拆:Day 07 講 RAG 引擎的 memory cap(型態一與三的混合)、Day 08 講 Whisper GPU(型態三)、Day 09 把記憶體壓力事件翻成 K8s 語言(三種型態互搶),Day 10 講 training 跟 inference 為什麼要分開(型態三的兩種變體)。
先搞清楚你的 agent 是「常駐的小東西」、「跑完就走的大東西」,還是「常駐的大東西」,這個判斷直接決定它該怎麼部署。