[Kubernetes] Kubernetes 基礎(五) Pod Controller - Daemonset, StatefulSet
前言
上篇討論 Deployment
做滾動式部署,本篇則會接著探討另外兩種 Controller - Daemonset
, StatefulSet
。
Daemonset 是什麼
Daemonset
用來確保所有符合資格的節點(e.g. 節點被標示為有污點就不具資格)都有一份運行的 Pod,故每個節點上的 Pod 數量就只有一份。
案例
- Cluster storage daemon
- CNI daemon
- Logs collection daemon
- Monitoring daemon
概念圖
從上圖來理解 Daemonset
的概念,圖中有三個 符合資格 的節點,Daemonset
便會在這三個節點上各產生一個 Pod,以此類推,若有第四個節點產生時,Daemonset
也會在這個節點上產生一個新的 Pod。故即便節點數量無法事先估計,但 Daemonset
能根據當前的節點數量動態產生所需的 Pod。
相較於前面提及的 Deployment,Deployment 須先設定要幾個副本,無法事先估計好節點上數量,Deployment 部署的 Pod 同時也無法保證能均勻地散落在不同節點上(Deployment 是透過 scheduler filtering and scoring 來選擇合適節點做部署),故有可能出現多個 Pods 部署於相同節點上面
範例
daemonset.yml
1 |
|
注意:
- yaml 檔裡不需描述 replica 數量: K8s 本身有一套算法偵測目前有幾個節點可部署 Pod
- 如果部署的是 master server 且沒有拔掉 Taints 的話,
Daemonset
不會起作用(因為 Daemonset ㄧ樣是去部署 Pod,所以 Taints 的 Noschedule 會阻擋部署)。當然也可以藉由設定拿掉 Taints,或是設定Daemonset
可容忍(tolerate) Taints,忽略 Noschedule
部署 Daemonset
將上述範例的 yaml 檔進行 apply
1 |
|
output:
1 |
|
接著觀察一下啟動的 Pods 資訊,可知 Pod 分別部署在不同節點上
1 |
|
透過 kubectl tree 來查看 DaemonSet
結構關係
1 |
|
注意:
ControllerRevision 控管相關的版本資訊(因為不能使用ReplicaSet
來管理,ReplicaSet
是確保任何時間點維持著特定的 Pod 數量)
StatefulSet
Stateful 表有狀態的意思,故 StatefulSet
是用來存放 有狀態的 Pods 的集合。
相較於先前用 Daemonset
或是 Deployment
所部署的 Pod 本身都是無狀態的,意味著每次 Pod 被砍掉時,重新產生的 Pod 都是全新的,無任何狀態資訊在裡面,每次可能都要透過項 DB 的服務額外存取。
有些情況下會希望 Pod 本身是有狀態的,Stateful 的 Pod 本身可以不停地重啟,每次重啟都不影響功能運作,確保 Pod 都擁有自己的獨立狀態
- Stable, unique network identifiers: 如獨立的 DNS Name 做網路存取
- Stable, persistent storage
- Order, graceful deployment and scaling
- Ordered, automated rolling updates
StatefulSet
在使用上有個特性:
- 每個 Pod 的名稱後面都會帶一組有續性的流水號(並非如 deployment 一樣,採 hash 方式產生亂碼): 帶有流水號的 Pod 名稱可用來辨識 Pod 身份(or 狀態),管理員能根據這些 Pod 有先後處理的順序。
- 部署方式採 one-by-one,依序進行部署
- 更新方式也是採 one-by-one,以倒過來的順序對 Pod 做更新 (對比 deployment 的 rolling update,事先建新的 Pod 再砍掉舊的)
常見案例:
當 StatefulSet
結合網路、儲存功能時,即使原本的 Pod 被砍掉,被重新部署在不同節點上,仍然可藉由相同的 DNS 名以及相關 Storage 資料去存取相同名稱的 Pod 。
以網路為例:
每個 Pod 都有各自的 DNS,可根據需求藉由 DNS 存取不同的 Pod 上的應用程式,採一對一的方式,一個 DNS name 對到固定的 Pod。即使 Pod 重啟跑到別的節點上,固定的 DNS 仍會指向重啟後的 Pod。
儲存功能也是相同的道理,每個儲存空間對應到固定的 Pod,確保 Pod 能拿到相同的儲存空間
範例
statefulset.yml
注意: StatefulSet
需要表明多少個副本(Replica)
1 |
|
將上述範例的 yaml 檔進行 apply
1 |
|
接著觀察一下啟動的 Pods 時資訊
1 |
|
output
1 |
|
根據結果可知藉由 statefulset
建立出來的 Pod 名稱後面都有帶有流水號,範例中定義 replicas 為 2,創造兩個帶有編號,且號碼為 0 開始的 Pod 名稱
也可以藉由 tree
指令列出 statefulset
結構,了解 statefulset
是如何管理的
1 |
|
output:
1 |
|
總結
Daemonset
的使用時機:
希望在每個節點上都只跑一支應用程式,且是自動隨著節點數量動態調整(產生新節點時 Pod 自動部署 or 節點減少時,主動移除 Pod),確保每個節點上都有部署一支應用程式
statefulset
的使用時機:StatefulSet
因為是用來存放 有狀態的 Pods 的集合,故搭配網路、儲存功能時會更有意義,具體案例可參考 K8s 官方部落格曾發布 MongoDB 的案例,文章內容大概是描述如何透過 K8s 的 StatefulSet
產生多個副本的 MongoDB,舉例來說有三個 Pods,三個 Pods 存放相同資料,彼此相互同步,使用者可以隨時存取任何一個,確保拿到的資料都是一致的,更多細節可看官網文章。
下一篇將探討 K8s 一次性的運算單元 - Job/CronJob