前言
在實際的生產環境中,我們幾乎不太可能只跑一個 Pod 來承載線上服務。當流量變大、需要版本更新時,如何做到多副本部署、水平擴縮容、不停機滾動更新?這些需求正好就是 Kubernetes 中 Deployment 這個資源物件存在的意義。
我個人在剛接觸 K8s 的時候,對 Deployment 的認識僅止於「幫我把 Pod 跑起來」,但深入之後才發現它背後的設計遠比想像中精巧。這篇文章就來跟大家聊聊我對 Deployment 的理解,從基本結構到滾動更新、擴縮容、回滾機制,一次講清楚。
Deployment 在 K8s 中的角色
Deployment 是 Kubernetes 裡用來管理無狀態應用的核心資源。你可以把它想像成一個牧場管理員——它底下管理的 Pod 就像一頭頭牲畜,如果哪一頭出了問題,管理員會自動補上新的,維持數量穩定。
不過 Deployment 並不是直接操控 Pod 的,中間其實還有一層叫做 ReplicaSet。Deployment 透過 ReplicaSet 來達成水平擴容與滾動更新等功能,而我們平時不太需要直接碰 ReplicaSet,它比較像是幫 Deployment 跑腿的角色。
以下用表格整理它們的關係:
| 資源 | 角色 | 說明 |
|---|---|---|
| Deployment | 管理者 | 定義應用的期望狀態(副本數、映像檔版本、更新策略等) |
| ReplicaSet | 執行者 | 根據 Deployment 的指示,維持指定數量的 Pod 副本 |
| Pod | 工作單元 | 實際跑容器的最小單位 |
Deployment YAML 範例解析
下面是一份我常用的 Deployment YAML 範本,涵蓋了滾動更新策略、初始化容器、健康探針等常見配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: my-web
template:
metadata:
labels:
app: my-web
spec:
initContainers:
- name: init-setup
image: ********/init-setup:latest
containers:
- name: my-web
image: ********/my-web:latest
ports:
- containerPort: 80
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 3
periodSeconds: 5
readinessProbe:
httpGet:
path: /readiness
port: 80
initialDelaySeconds: 5
periodSeconds: 5
幾個重點欄位說明:
| 欄位 | 用途 |
|---|---|
replicas |
指定要維持多少個 Pod 副本 |
strategy.rollingUpdate.maxSurge |
滾動更新時,最多可以額外多建幾個 Pod |
strategy.rollingUpdate.maxUnavailable |
滾動更新時,最多允許幾個 Pod 不可用 |
imagePullPolicy: Always |
每次啟動都拉最新映像檔(也可設為 IfNotPresent 或 Never) |
livenessProbe |
存活探針,偵測容器是否還在正常運作 |
readinessProbe |
就緒探針,偵測容器是否準備好接收流量 |
寫好 YAML 後,執行以下指令就能部署:
kubectl apply -f my-web-deployment.yaml
滾動更新(Rolling Update)
這是我覺得 Deployment 最優雅的設計之一。當我們更新了 Pod 模板(例如換了映像檔版本),Deployment 不會粗暴地把所有 Pod 一次砍掉重建,而是採用逐步替換的方式。
具體流程大致如下:
- Deployment 偵測到 Pod 模板有變更
- 建立一個新的 ReplicaSet(對應新版映像檔)
- 新 ReplicaSet 啟動一個新 Pod,確認就緒後,舊 ReplicaSet 刪除一個舊 Pod
- 重複步驟 3,直到所有 Pod 都替換成新版本
- 舊的 ReplicaSet 保留(不管理任何 Pod),以便後續回滾

Kubernetes 滾動更新流程示意(圖片來源:spacelift.io)
這種方式確保了在整個更新過程中,始終有足夠數量的 Pod 在服務,使用者幾乎不會感受到中斷——這就是所謂的零停機部署。

Deployment 滾動更新策略總覽(圖片來源:spacelift.io)
水平擴縮容(Horizontal Scaling)
水平擴縮容的概念很直覺:就是增減 Pod 的數量。假設線上流量突然暴增,我們想把副本數從 3 擴到 5,有兩種方式:
方式一:修改 YAML 後重新 apply
# 將 replicas 改為 5 後執行
kubectl apply -f my-web-deployment.yaml
方式二:直接用指令調整
kubectl scale deployment my-web-deployment --replicas=5 -n my-namespace
執行後,Deployment 對應的 ReplicaSet 就會自動補上 2 個新的 Pod,非常方便。反之,要縮容的話就把數字調小即可。
回滾(Rollback)
生產環境最怕的就是更新出包。還好 Deployment 內建了回滾機制,因為每次滾動更新時,舊的 ReplicaSet 都還在,裡面保存了完整的配置資訊。
常用的回滾指令如下:
# 查看部署歷史版本
kubectl rollout history deployment my-web-deployment -n my-namespace
# 查看某個版本的詳細資訊
kubectl rollout history deployment my-web-deployment --revision=2 -n my-namespace
# 回滾到指定版本
kubectl rollout undo deployment my-web-deployment --to-revision=2 -n my-namespace
這讓我們在出問題時能快速回到上一個穩定版本,大幅降低了線上事故的風險。
初始化容器與健康探針
在 Pod 的定義中,除了主要的應用容器,還可以配置初始化容器(initContainers)和健康探針(Probes)。
初始化容器
initContainers 會在主容器啟動之前執行。如果有多個初始化容器,它們會按順序逐一執行,全部成功退出後主容器才會啟動。常見用途包括:等待相依服務就緒、資料庫 migration、下載設定檔等。
Liveness 與 Readiness 探針
這兩個探針是 K8s 確保服務穩定性的關鍵機制:
| 探針類型 | 偵測目的 | 失敗後果 |
|---|---|---|
| Liveness Probe | 容器是否還活著 | K8s 會重啟該容器 |
| Readiness Probe | 容器是否準備好接收流量 | 該 Pod 會被從 Service 的負載均衡中移除,不再接收流量 |
兩者搭配使用,可以有效避免流量打到還沒準備好或已經異常的容器上,是維運穩定性的好幫手。
小結
雖然 Deployment 是 Kubernetes 裡相對基礎的資源,但它涵蓋的功能——多副本管理、滾動更新、水平擴縮容、版本回滾——每一個都是日常維運的必備技能。我自己的經驗是,把 Deployment 搞透了,後面再去理解 StatefulSet、DaemonSet 等進階資源會輕鬆很多。
希望這篇整理對你有幫助,有任何問題歡迎留言交流!
參考資料:
- Kubernetes 官方文件 — Deployments
- Spacelift — Kubernetes Rolling Updates for Reliable Deployments

發佈留言