在 Kubernetes 中,Deployment 和 StatefulSet 都是用於管理 Pod 的控制器(Controller),但它們適用於不同類型的負載,主要區別在於對 有狀態應用(Stateful Applications) 與 無狀態應用(Stateless Applications) 的支持。
下面是兩者的主要區別:
1. Pod 標識與網絡標識
- Deployment:
- Pod 是無序且無身份標識的。
- Pod 名稱是隨機生成的(如
my-app-7d5b8f9c4-xk2vq)。 - 每次重建 Pod,其名稱、IP 都會變化。
- StatefulSet:
- Pod 具有穩定的、唯一的標識。
- Pod 名稱是有序的(如
my-statefulset-0,my-statefulset-1)。 - Pod 的主機名、DNS 記錄穩定,即使被刪除重建,也會保留相同的身份和網絡標識。
2. 存儲(Volume)
- Deployment:
- 所有 Pod 共享相同的 Volume 配置,但每個 Pod 的 Volume 實例是獨立的(如果使用 PVC 模板,則每個副本會創建自己的 PVC,但通常不推薦用於有狀態場景)。
- 更適合臨時性或可丟棄的數據。
- StatefulSet:
- 每個 Pod 有自己專屬的持久化存儲卷(Persistent Volume Claim)。
- 即使 Pod 被調度到其他節點,其關聯的 PVC 仍然綁定到該 Pod(通過 Pod 名稱匹配)。
- 數據不會因 Pod 重建而丟失。
3. 部署與擴縮容順序
- Deployment:
- Pod 的創建、終止是並行的,沒有固定順序。
- 適合快速擴縮容。
- StatefulSet:
- Pod 的創建、刪除、擴縮容是按序進行的(例如先啓動
my-set-0,再my-set-1)。 - 支持“有序部署”和“有序終止”,這對某些分佈式系統(如 ZooKeeper、Kafka、MySQL 主從)至關重要。
4. 適用場景
- Deployment:適用於無狀態應用,例如 Web 服務器、API 服務、緩存等。這些應用不需要記住自身狀態,可以隨時替換。
- StatefulSet:適用於有狀態應用,例如:
- 數據庫(MySQL、PostgreSQL、MongoDB)
- 分佈式協調服務(ZooKeeper、etcd)
- 消息隊列(Kafka、RabbitMQ 集羣模式)
- 需要穩定網絡標識或持久存儲的應用
5. 更新策略
- Deployment:
- 支持滾動更新(RollingUpdate)、重新創建(Recreate)等策略。
- StatefulSet:
- 也支持滾動更新,但默認是按序更新(從高序號到低序號,或反之,取決於配置)。
- 可以設置
.spec.updateStrategy.type為RollingUpdate或OnDelete。
總結對比表:
|
特性
|
Deployment
|
StatefulSet
|
|
Pod 身份
|
無身份、隨機名
|
有序、穩定唯一標識
|
|
網絡標識(DNS)
|
不穩定
|
穩定(如 |
|
存儲
|
通常共享或臨時
|
每個 Pod 專屬持久卷
|
|
啓動/終止順序
|
並行
|
有序
|
|
適用應用類型
|
無狀態
|
有狀態
|
|
更新策略
|
滾動更新等
|
按序滾動更新
|
如果你正在部署一個 Web 應用,用 Deployment;
如果你要部署數據庫集羣或需要穩定身份和存儲的服務,用 StatefulSet。