在前面的章節中,學習如何使用 Deployment 或 StatefulSet 在叢集的節點之間散佈工作負載的多個副本。 但是,如果您想在每個節點上只運行一個副本怎麼辦?例如,您可能希望每個節點運行一個agent或daemon,來幫此節點提供系統服務(像是metric收集或log聚合)。 要在k8s中部署這些類型的工作負載,您可以使用DaemonSet。
在開始之前,建立kiada命名空間,切換到Chapter16/目錄,並執行以下指令apply SETUP/目錄中的所有yaml:
$ kubectl create ns kiada
$ kubectl config set-context --current --namespace kiada
$ kubectl apply -f SETUP -R
DaemonSet是一個API物件,可確保在每個叢集節點上運行一個Pod副本。預設情況下,DaemonSet Pod部署在每個節點上,但可以使用節點選擇器將部署限制在某些節點上。
DaemonSet包含一個Pod模板並使用它來建立多個Pod副本,就像Deployment、ReplicaSet、StatefulSets一樣。 但是,使用DaemonSet,您不需要指定期望副本數。相反,DaemonSet controller會建立與叢集中的節點一樣多的Pod。 它確保每個Pod被調度到不同的節點上,不像ReplicaSet部署的Pod,多個Pod可以被調度到同一個節點上,如下圖。
圖 16.1 DaemonSet在每個節點上運行一個Pod副本,而ReplicaSet將它們分散在叢集各處。
DaemonSet通常用來部署幫每個叢集節點提供某種系統層級服務的基礎設施Pod。 這包括收集節點系統程序和Pod的log、監控這些程序的daemon、提供叢集網路和儲存、管理套件安裝和更新的工具,以及連結到節點上各種設備提供介面的服務。
Kube Proxy元件負責在叢集中建立的Service物件路由流量,通常利用kube-system命名空間中的DaemonSet部署。 提供Pod網路通訊的Container Network Interface (CNI) plugin通常也利用DaemonSet部署。
儘管您可以使用初始化腳本或systemd等標準方法在叢集節點上運行系統軟體,但使用DaemonSet可確保您以相同的方式管理叢集中的所有工作負載。
就像ReplicaSet和StatefulSets一樣,DaemonSet包含一個Pod模板和一個標籤選擇器,用來確定哪些Pod屬於DaemonSet。 在它的協調循環的每一次通過中,DaemonSet controller都會找到與標籤選擇器匹配的Pod,檢查每個節點是否恰好有一個匹配的Pod,並建立或刪除Pod以確保是這種情況。如下圖。
圖 16.2 DaemonSet controller的協調循環
當您將節點加入到叢集時,DaemonSet controller會建立一個新Pod並將pod與該節點關聯。當你移除一個節點時,DaemonSet會刪除與此節點關聯的Pod物件。 如果這些DaemonSet Pod其中一個消失,例如,因為被手動刪除,controller會立即重新建立它。 如果出現了額外的Pod,例如,如果您建立了一個與DaemonSet中的標籤選擇器匹配的Pod,controller會立即將它刪除。
DaemonSet物件 yaml看起來非常類似於Deployment、ReplicaSet、StatefulSets。讓我們看一個名稱demo的DaemonSet範例,如下:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: demo
spec:
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo
image: busybox
command:
- sleep
- infinity
DaemonSet物件類型是apps/v1 API group/version的一部分。
在DaemonSet物件的spec區段中,您指定標籤選擇器selector
和Pod模板template
,就像ReplicaSet一樣。
在template區段中的metadata區段必須包含labels字段,並且必須與selector中的標籤匹配。
<aside>
💡 選擇器是不可變的,但您可以更改標籤,只要它們仍然與選擇器匹配。
如果需要更改選擇器,則必須刪除DaemonSet並重新建立。
您可以在替換DaemonSet時使用--cascade=orphan
選項保留Pod。
</aside>
正如您在yaml中看到的那樣,demo DaemonSet部署了除了執行sleep
指令之外什麼都不做的Pod。這是因為本練習的目標是觀察DaemonSet本身的行為,而不是觀察它的Pod。
在本章後面,您將建立一個DaemonSet,它的Pod將實際做某些事。
使用kubectl apply
指令apply ds.demo.yaml來建立DaemonSet,然後列出當下命名空間中的所有DaemonSet,如下:
$ kubectl get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
demo 2 2 2 2 2 <none> 7s