主線

KAI K8s之路 02|Deployment 是什麼?為什麼 Pod 不該手動照顧

有了 Pod 還不夠。Deployment 把「我想要幾個 Pod、用哪個版本、怎麼更新」寫成 desired state,讓 Kubernetes 持續把 workload 拉回正軌。

中文 主線 第 2 篇
先抓住

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 出現的位置。

KAI notebook style diagram contrasting manual Pod babysitting with Deployment desired state.
Deployment 的重點不是「幫你建立幾個 Pod」而已,而是把你想要的 workload 狀態寫成規則,讓 controller 持續把實際狀態拉回來。

用排班表想 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 的結果。

KAI notebook style diagram showing Deployment owning ReplicaSet and ReplicaSet owning Pods.
順著 ownership 看會比較穩:先看 Deployment 的期望狀態,再看 ReplicaSet 怎麼維持 Pod;不要倒過來把某個 Pod 當成整個系統的主角。

這也是為什麼 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 數量,不是同一件事。

KAI notebook style diagram showing a Deployment rolling update from old version Pods to new version Pods with readiness checks.
rollout 不是把舊 Pod 一次清掉,而是在可用性和更新速度之間做受控替換。真正要看的不是「有沒有 Pod」,而是新版本有沒有安全變成 Available。

這也是為什麼 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 是不是接近期望 replicas
  • UP-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 節奏的主控制器。

這篇先記住三件事

  1. Pod 是執行現場,Deployment 是期望狀態和收斂規則
  2. Deployment 透過 ReplicaSet 維持 Pod 數量,並處理 rollout / rollback
  3. Debug app workload 時,不要只盯 Pod;先看 Deployment 的 selector、template、replicas 和 rollout 狀態

下一篇會接著問:Pod 一直會被替換,Service 怎麼給它們一個穩定入口?