K8S 實戰(九)| 控制器 DaemonSet - 將守護程序容器化
前言
Deployment 管理的 Pod 允許在一個節點上執行多個副本。
當需要在節點上執行收集日誌或者執行監控任務的容器時,顯然不適合啟動多個 Pod 副本。
這種場景下,我們可以啟用 DaemonSet 控制器來管理 Pod。
Daemon Pod 的特點
- Pod 執行在叢集中的全部或者部分節點上
- 每個節點上只能有一個這樣的 Pod
- 當叢集中加入了新節點,Pod 會自動在新節點上建立
- 當節點被從叢集中移除後,節點上 Pod 會自動被回收掉
Daemon Pod 適用的場景
- 網路外掛的 Agent
- 儲存外掛的 Agent
- 監控任務的 Agent
- 收集日誌的 Agent
DaemonSet
建立一個 DS
cat daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# this toleration is to have the daemonset runnable on master nodes
# remove it if your masters can't run pods
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
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
# kubectl apply -f daemonset.yaml
daemonset.apps/fluentd-elasticsearch created
檢視
[[email protected] ~]# kubectl get ds --namespace kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd-elasticsearch 6 6 6 6 6 <none> 11m
目前叢集中有 3 個 master,3 個 worker,一共 6 個節點,可以看到 6 個節點上都運行了該 node
工作流程
DaemonSet Controller,從 Etcd 裡獲取所有的 Node 列表,然後遍歷所有的 Node。
然後檢查當前這個 Node 上是不是有一個攜帶了 name=fluentd-elasticsearch 標籤的 Pod 在執行。
而檢查的結果,大概有這麼三種情況:
- Node 上沒有這種 Pod,那麼就意味著要在這個 Node 上建立這個 Pod;
- Node 上有這種 Pod,但是數量大於 1,那就說明要把多餘的 Pod 從這個 Node 上刪除掉;
- 只有一個這種 Pod,說明這個節點是正常的。
重要引數
spec.affinity.nodeAffinity
通過命令
# kubectl edit pod fluentd-elasticsearch-22g5r --namespace=kube-system
可以看到 DaemonSet 自動給 Pod 增加了引數
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchFields:
- key: metadata.name
operator: In
values:
- master03
限制了該 Pod 只能執行在 master03 這個 Node 上
tolerations
同樣通過上面的命令,可以看到有引數
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
- effect: NoSchedule
key: node.kubernetes.io/disk-pressure
意味著可以容忍所有標記有如下“汙點”的 Node,可以在這些 Node 上執行 master/not-ready/unreachable/disk-pressure
正常情況下,如果 Node 上被標記了這些“汙點”,Pod 被禁止排程到這樣的 Node 上執行
但 DaemonSet 給 Pod 加上了 tolerations,使 Pod 可以忽略這些汙點,從而成功將 Pod 排程到“汙點”節點上
如果節點有故障導致 Pod 啟動失敗,DaemonSet 會一直嘗試,直到 Pod 成功啟動
僅在部分節點執行 Pod
可以在 YAML 中手工指定 .spec.template.spec.affinity,這樣 Pod 會執行在指定的 Node 上
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchFields:
- key: metadata.name
operator: In
values:
- target-host-name
如果沒有指定該引數,那麼 Pod 會執行在所有 Node 上
DaemonSet 優點
我們也可以自己寫一個守護程序來執行類似的工作,使用 DaemonSet Pod 有哪些優點呢。
- DaemonSet Pod 自帶自身監控功能,省去了我們自己再寫一個針對守護程序的監控程式的工作
- DaemonSet Pod 不管執行什麼任務,都是統一的語言和管理方式
- DaemonSet Pod 自帶了資源限制功能,避免了守護程序長時間執行佔用過多資源對宿主機造成影響
結束語
DaemonSet 傾向於精確控制 Pod 執行在哪些機器上,確保這些機器上都有這個 Pod 在執行。
而 Deployment 更適合於管理離使用者更近的無狀態類 Pod,比如 Web 服務。
它們的共同點是,都不希望自己管理的 Pod 終止,Pod 出現問題後可以自愈。
聯絡我
微信公眾號:IT奮鬥的青年