不像 Deployment 一個Pod 會散佈在不同 Pod ,DaemonSet 在每個 Node上都只有一個 Container在運作 ,常用來部署一些記錄Log、監控或者其他系統管理應用。典型的應用包括:
其實Kubernetes 自己就在用DaemonSet 運行系統組件。執行如下命令:
$ kubectl get daemonset --namespace=kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
minikube 5 5 5 5 5 <none> 4d
以上是一個 DaemonSet 作為單一用途的 Daemon 時的範例,當然也有可能會有需要同時多個 DaemonSet 來達成某種複雜用途時的場景,這時候就可以還會包含到使用不同的 flag,或是針對不同的硬體型態有不同的 cpu & memory 的資源需求。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
# .spec.selector 一旦定義後就無法再變更了
# 必須與 .spec.template.metadata.labels 的定義相同
# 這裡可以使用 matchLabels 或是 matchExpressions(用來處理較為複雜的 label 組合)
selector:
matchLabels:
name: fluentd-elasticsearch
# 此為必要欄位,與 pod template 相同
# 用來定義 DaemonSet 的內容應該要長什麼樣子
template:
metadata:
labels:
name: fluentd-elasticsearch
# 由於是 DaemonSet 的關係,因此 .spec.template.spec.restartPolicy 永遠是 "Always"
# 預設值為 "Always"
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: k8s.gcr.io/fluentd-elasticsearch:1.20
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
有幾個地方在定義 DaemonSet 的時候需要比較注意的:
.spec.selector 一旦定義後就不建議再修改,若是修改可能會造成某些 pod 變成孤兒(因為 DaemonSet controller 無法管理到正確的 pod)
.spec.selector 的定義必須與 .spec.template.metadata.labels 相同,否則會被 API server 拒絕套用
不可以再建立(或是透過其他 controller 建立,例如:Deployment)帶有與 DaemonSet 相同 label 組合的 pod,否則會被 DaemonSet 認為是自己所產生的