主線
KAI K8s之路 02|Deployment 是什麼?為什麼 Pod 不該手動照顧
有了 Pod 還不夠。Deployment 把「我想要幾個 Pod、用哪個版本、怎麼更新」寫成 desired state,讓 Kubernetes 持續把 workload 拉回正軌。
Pod 是 workload 的一次落地;Deployment 是讓它持續回到期望狀態的規則。
不要手動照顧 Pod;先看 Deployment 的 replicas、selector、rollout 和 events,判斷它怎麼把狀態拉回來。
上一篇先把 Pod 想清楚:Pod 是 Kubernetes 照顧 workload 的第一個邊界。
但這裡馬上會出現下一個問題。
如果 Pod 掛了、被 node 趕走、版本要換,難道我們要每天手動盯著每一個 Pod 嗎?
我不會這樣想。
我會先記這句:
Pod 是 workload 的一次落地;Deployment 是讓它持續回到期望狀態的規則。
先不要手動照顧 Pod
Pod 很重要,但 Pod 本身不是一個你應該長期手動照顧的東西。
Pod 可以被刪掉、重建、換名字、換 node。它更像「這一次 workload 被放到現場的結果」。
真正該被你寫進系統裡的,不是某個 Pod 的名字,而是:
- 我希望這個 workload 有幾份 replica
- 它們應該長成什麼樣子
- 哪些 Pod 算是這個 workload 的一部分
- 更新版本時,要用什麼速度替換
- 新版本不穩時,要不要能 rollback
這就是 Deployment 出現的位置。
用排班表想 Deployment
我會把 Pod 想成現場正在上班的人。
那 Deployment 比較像排班表加主管。
排班表不會說:「請保護小明這個人永遠站在櫃台。」
它會說:
今天櫃台要有 3 個人,穿同一套制服,做同一個版本的工作;有人離開,就補一個人;換新流程時,不要一次把所有人都換掉。
這個比喻很接近 Deployment 的思路。
你不是在珍惜某個 Pod。你是在描述一個 workload 應該維持的狀態。
Deployment 實際上管了什麼
Deployment 是 Kubernetes 裡最常見的 workload controller 之一,通常用來跑 stateless、可替換的 application workload。
它的核心不是命令式地說「現在幫我做這件事」,而是宣告:
我希望最後看起來是這個狀態。
一個 Deployment 裡,最值得先看的通常是三個欄位:
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: example/web:v2
我會這樣讀:
replicas:我希望有幾個 Pod 在跑selector:哪些 Pod 算是這個 Deployment 管的template:如果需要建立新 Pod,Pod 應該長什麼樣子
這三個東西合起來,就是 Deployment 的期望狀態。
Deployment、ReplicaSet、Pod 的關係
這裡新手很容易看錯。
Deployment 通常不是自己直接照顧每一個 Pod。它會管理 ReplicaSet,再由 ReplicaSet 維持一組 Pod replica。
可以先這樣記:
Deployment -> ReplicaSet -> Pods
Deployment 負責比較高層的事情:rollout、rollback、版本切換、scale。
ReplicaSet 負責比較直接的事情:維持指定數量的 Pod。
Pod 則是最後實際跑 workload 的結果。
這也是為什麼 Kubernetes 官方文件會提醒:不要直接管理由 Deployment 擁有的 ReplicaSet。
你可以看它、查它、排查它,但通常不要把它當成主要操作入口。
真正有用的是收斂
Deployment 最重要的能力,我會用兩個字記:收斂。
實際世界會一直偏離你想要的樣子:
- Pod 掛了
- node 出問題
- image 換了
- replica 不夠
- rollout 卡住
- readiness 沒過
Deployment controller 會不斷比較:
期望狀態 vs 實際狀態
然後透過建立、刪除、替換 Pod,讓狀態慢慢回到你宣告的樣子。
這件事很 Kubernetes。
它不是你下了一個一次性的指令,而是你把「正確狀態」寫下來,讓 controller 一直追。
更新版本時,它不是一次全部換掉
Deployment 另一個重要價值,是 rollout。
你改了 Deployment 的 Pod template,例如把 image 從 v1 換成 v2,Deployment 會建立新的 ReplicaSet,逐步把新 Pod 拉上來,再把舊 Pod 降下去。
注意一個細節:通常是 Pod template 改了才會觸發 rollout。單純改 replica 數量,不是同一件事。
這也是為什麼 production 發布時,你不能只看 kubectl get pods。
你要看 rollout 有沒有完成,新版本有沒有真的 available,舊 ReplicaSet 是不是已經被降下來。
新手最容易誤會的幾件事
1. 把 Deployment 當成 Pod 的大一點版本
Deployment 不是「比較大的 Pod」。
Deployment 是一個 controller-facing object。你用它描述期望狀態,controller 透過 ReplicaSet 和 Pod 把狀態拉回來。
2. 看到 Pod 壞了就急著手動刪
有些情況刪 Pod 是合理的排查手段,但如果你每次都靠手動刪 Pod 解決問題,你其實是在繞過 controller 的語言。
更好的問題是:
為什麼 Deployment 產生的 Pod 會一直回到壞狀態?
要查 template、image、config、probe、resource、event,而不是只把眼前那個 Pod 當成唯一問題。
3. 以為 replicas 等於服務一定健康
replicas: 3 只是期望數量。
你還要看 Ready、Available、Updated 這些狀態。三個 Pod 都存在,不代表三個都能服務流量。
4. selector 寫錯也很危險
Deployment 靠 selector 找自己要管的 Pod。selector 和 template label 如果設計不好,controller 可能管不到該管的 Pod,或者和其他 controller 重疊。
這種錯不一定一眼爆炸,但會讓系統行為很怪。
我會怎麼 inspect 一個 Deployment
如果接手一個 workload,我會先用這個順序:
kubectl get deploy -n <ns>
kubectl describe deploy <deploy-name> -n <ns>
kubectl rollout status deployment/<deploy-name> -n <ns>
kubectl get rs -n <ns>
kubectl get pods -n <ns> --show-labels
如果是版本發布相關:
kubectl rollout history deployment/<deploy-name> -n <ns>
kubectl rollout undo deployment/<deploy-name> -n <ns>
我會特別看:
READY是不是接近期望 replicasUP-TO-DATE是不是新 template 的數量AVAILABLE是不是有真的可用- Events 裡有沒有 failed scheduling、image pull、probe failure
- ReplicaSet 的新舊版本是不是符合 rollout 預期
這比只看一個 Pod 的 log 更接近 Kubernetes 的運作方式。
Deployment 不是所有 workload 的答案
這篇講 Deployment,是因為它是跑 stateless app 最常見的入口。
但不是所有 workload 都適合 Deployment。
如果 Pod 需要穩定身份或綁定自己的儲存,後面可能要看 StatefulSet。
如果你要每台 node 都跑一份 agent,可能是 DaemonSet。
所以我會把 Deployment 放在這個位置:
當 Pod 是可替換的,Deployment 就是讓它們維持數量、版本和 rollout 節奏的主控制器。
這篇先記住三件事
- Pod 是執行現場,Deployment 是期望狀態和收斂規則
- Deployment 透過 ReplicaSet 維持 Pod 數量,並處理 rollout / rollback
- Debug app workload 時,不要只盯 Pod;先看 Deployment 的 selector、template、replicas 和 rollout 狀態
下一篇會接著問:Pod 一直會被替換,Service 怎麼給它們一個穩定入口?