視頻教程連接:kubernetes快速入門
寫在前面
上章節(jié)中介紹了Deployment,ReplicaSet,ReplicationController等副本控制器的使用和場景,接下來介紹kubernetes系列教程控制器DaemonSet使用。
1. DaemonSet控制器
1.1 DaemonSet簡介
介紹DaemonSet時(shí)我們先來思考一個(gè)問題:相信大家都接觸過監(jiān)控系統(tǒng)比如zabbix,監(jiān)控系統(tǒng)需要在被監(jiān)控機(jī)安裝一個(gè)agent,安裝agent通常會(huì)涉及到以下幾個(gè)場景:
- 所有節(jié)點(diǎn)都必須安裝agent以便采集監(jiān)控?cái)?shù)據(jù)
- 新加入的節(jié)點(diǎn)需要配置agent,手動(dòng)或者運(yùn)行腳本
- 節(jié)點(diǎn)下線后需要手動(dòng)在監(jiān)控系統(tǒng)中刪除
kubernetes中經(jīng)常涉及到在node上安裝部署應(yīng)用,它是如何解決上述的問題的呢?答案是DaemonSet。DaemonSet守護(hù)進(jìn)程簡稱DS,適用于在所有節(jié)點(diǎn)或部分節(jié)點(diǎn)運(yùn)行一個(gè)daemon守護(hù)進(jìn)程,如監(jiān)控我們安裝部署時(shí)網(wǎng)絡(luò)插件kube-flannel和kube-proxy,DaemonSet具有如下特點(diǎn):
- DaemonSet確保所有節(jié)點(diǎn)運(yùn)行一個(gè)Pod副本
- 指定節(jié)點(diǎn)運(yùn)行一個(gè)Pod副本,通過標(biāo)簽選擇器或者節(jié)點(diǎn)親和性
- 新增節(jié)點(diǎn)會(huì)自動(dòng)在節(jié)點(diǎn)增加一個(gè)Pod
- 移除節(jié)點(diǎn)時(shí)垃圾回收機(jī)制會(huì)自動(dòng)清理Pod

DaemonSet適用于每個(gè)node節(jié)點(diǎn)均需要部署一個(gè)守護(hù)進(jìn)程的場景,常見的場景例如:
- 日志采集agent,如fluentd或logstash
- 監(jiān)控采集agent,如Prometheus Node Exporter,Sysdig Agent,Ganglia gmond
- 分布式集群組件,如Ceph MON,Ceph OSD,glusterd,Hadoop Yarn NodeManager等
- k8s必要運(yùn)行組件,如網(wǎng)絡(luò)flannel,weave,calico,kube-proxy等
安裝k8s時(shí)默認(rèn)在kube-system命名空間已經(jīng)安裝了有兩個(gè)DaemonSet,分別為kube-flannel-ds-amd64和kube-proxy,分別負(fù)責(zé)flannel overlay網(wǎng)絡(luò)的互通和service代理的實(shí)現(xiàn),可以通過如下命令查看:
- 查看kube-system命令空間的DaemonSet列表,當(dāng)前集群有三個(gè)node節(jié)點(diǎn),所以每個(gè)DS會(huì)運(yùn)行三個(gè)Pod副本
[root@node-1 ~]# kubectl get ds -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-flannel-ds-amd64 3 3 3 3 3 beta.kubernetes.io/arch=amd64 46d
kube-proxy 3 3 3 3 3 beta.kubernetes.io/os=linux 46d
- 查看Pod的副本情況,可以看到DaemonSet在每個(gè)節(jié)點(diǎn)都運(yùn)行一個(gè)Pod

1.2 DaemonSet定義
DaemonSet的定義和Deployment定義使用相類似,需要定義apiVersion,Kind,metadata和spec屬性信息,spec中不需要定義replicas個(gè)數(shù),spec.template即定義DS生成容器的模版信息,如下是運(yùn)行一個(gè)fluentd-elasticsearch鏡像容器的daemon守護(hù)進(jìn)程,運(yùn)行在每個(gè)node上通過fluentd采集日志上報(bào)到ElasticSearch。
- 通過yaml文件定義DaemonSet
[root@node-1 happylau]# cat fluentd-es-daemonset.yaml
apiVersion: apps/v1 #api版本信息
kind: DaemonSet #類型為DaemonSet
metadata: #元數(shù)據(jù)信息
name: fluentd-elasticsearch
namespace: kube-system #運(yùn)行的命名空間
labels:
k8s-app: fluentd-logging
spec: #DS模版
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers: #容器信息
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources: #resource資源
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts: #掛載存儲(chǔ),agent需要到這些目錄采集日志
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes: #將主機(jī)的目錄以hostPath的形式掛載到容器Pod中。
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
DaemonSet定義注意事項(xiàng):
- daemonset.spec.template定義Pod的模板信息,包含的metadata信息需要和selector保持一致
- template必須定義RestartPolicy的策略,切策略值為Always,保障服務(wù)異常時(shí)能自動(dòng)重啟恢復(fù)
- Pod運(yùn)行在特定節(jié)點(diǎn),支持指定調(diào)度策略,如nodeSelector,Node affinity,實(shí)現(xiàn)靈活調(diào)度
- 生成DaemonSet
[root@node-1 happylau]# kubectl apply -f fluentd-es-daemonset.yaml
daemonset.apps/fluentd-elasticsearch created
- 查看DaemonSet列表
[root@node-1 happylau]# kubectl get daemonsets -n kube-system fluentd-elasticsearch
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd-elasticsearch 3 3 3 3 3 <none> 16s
- 查看node上運(yùn)行Pod的情況,在NODE列可以看到每個(gè)node都運(yùn)行了一個(gè)Pod
[root@node-1 happylau]# kubectl get pods -n kube-system -o wide |grep fluentd
fluentd-elasticsearch-blpqb 1/1 Running 0 3m7s 10.244.2.79 node-3 <none> <none>
fluentd-elasticsearch-ksdlt 1/1 Running 0 3m7s 10.244.0.11 node-1 <none> <none>
fluentd-elasticsearch-shtkh 1/1 Running 0 3m7s 10.244.1.64 node-2 <none> <none>
- 查看DaemonSet詳情,可以看到DaemonSet支持RollingUpdate滾動(dòng)更新策略
[root@node-1 happylau]# kubectl get daemonsets -n kube-system fluentd-elasticsearch -o yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"DaemonSet","metadata":{"annotations":{},"labels":{"k8s-app":"fluentd-logging"},"name":"fluentd-elasticsearch","namespace":"kube-system"},"spec":{"selector":{"matchLabels":{"name":"fluentd-elasticsearch"}},"template":{"metadata":{"labels":{"name":"fluentd-elasticsearch"}},"spec":{"containers":[{"image":"quay.io/fluentd_elasticsearch/fluentd:v2.5.2","name":"fluentd-elasticsearch","resources":{"limits":{"memory":"200Mi"},"requests":{"cpu":"100m","memory":"200Mi"}},"volumeMounts":[{"mountPath":"/var/log","name":"varlog"},{"mountPath":"/var/lib/docker/containers","name":"varlibdockercontainers","readOnly":true}]}],"terminationGracePeriodSeconds":30,"tolerations":[{"effect":"NoSchedule","key":"node-role.kubernetes.io/master"}],"volumes":[{"hostPath":{"path":"/var/log"},"name":"varlog"},{"hostPath":{"path":"/var/lib/docker/containers"},"name":"varlibdockercontainers"}]}}}}
creationTimestamp: "2019-10-30T15:19:20Z"
generation: 1
labels:
k8s-app: fluentd-logging
name: fluentd-elasticsearch
namespace: kube-system
resourceVersion: "6046222"
selfLink: /apis/extensions/v1beta1/namespaces/kube-system/daemonsets/fluentd-elasticsearch
uid: c2c02c48-9f93-48f3-9d6c-32bfa671db0e
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
creationTimestamp: null
labels:
name: fluentd-elasticsearch
spec:
containers:
- image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
imagePullPolicy: IfNotPresent
name: fluentd-elasticsearch
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/log
name: varlog
- mountPath: /var/lib/docker/containers
name: varlibdockercontainers
readOnly: true
dnsPolicy: ClusterFirst
restartPolicy: Always #重啟策略必須為Always,保障異常時(shí)能自動(dòng)恢復(fù)
schedulerName: default-scheduler #默認(rèn)調(diào)度策略
securityContext: {}
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
volumes:
- hostPath:
path: /var/log
type: ""
name: varlog
- hostPath:
path: /var/lib/docker/containers
type: ""
name: varlibdockercontainers
templateGeneration: 1
updateStrategy: #滾動(dòng)更新策略
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
status:
currentNumberScheduled: 3
desiredNumberScheduled: 3
numberAvailable: 3
numberMisscheduled: 0
numberReady: 3
observedGeneration: 1
updatedNumberScheduled: 3
1.3 滾動(dòng)更新與回滾
- 更新鏡像至最新版本
[root@node-1 ~]# kubectl set image daemonsets fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:latest -n kube-system
daemonset.extensions/fluentd-elasticsearch image updated
- 查看滾動(dòng)更新狀態(tài)
[root@node-1 ~]# kubectl rollout status daemonset -n kube-system fluentd-elasticsearch
Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 1 out of 3 new pods have been updated...
Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 1 out of 3 new pods have been updated...
Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 1 out of 3 new pods have been updated...
Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 out of 3 new pods have been updated...
Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 out of 3 new pods have been updated...
Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 out of 3 new pods have been updated...
Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 of 3 updated pods are available...
daemon set "fluentd-elasticsearch" successfully rolled out
- 查看DaemonSet詳情,可以看到DS滾動(dòng)更新的過程:DaemonSet先將node上的pod刪除然后再創(chuàng)建

- 查看DaemonSet滾動(dòng)更新版本,REVSION 1為初始的版本
[root@node-1 ~]# kubectl rollout history daemonset -n kube-system fluentd-elasticsearch
daemonset.extensions/fluentd-elasticsearch
REVISION CHANGE-CAUSE
1 <none>
2 <none>
- 更新回退,如果配置沒有符合到預(yù)期可以回滾到原始的版本
[root@node-1 ~]# kubectl rollout undo daemonset -n kube-system fluentd-elasticsearch --to-revision=1
daemonset.extensions/fluentd-elasticsearch rolled back
- 確認(rèn)版本回退情況

- 觀察版本回退的過程,回退的過程和和滾動(dòng)更新過程類似,先刪除Pod再創(chuàng)建

- 刪除DaemonSet
[root@node-1 ~]# kubectl delete daemonsets -n kube-system fluentd-elasticsearch
daemonset.extensions "fluentd-elasticsearch" deleted
[root@node-1 ~]# kubectl get pods -n kube-system |grep fluentd
fluentd-elasticsearch-d6f6f 0/1 Terminating 0 110m
1.4 DaemonSet調(diào)度
前面kubernetes系列教程(七)深入玩轉(zhuǎn)pod調(diào)度文章介紹了Pod的調(diào)度機(jī)制,DaemonSet通過kubernetes默認(rèn)的調(diào)度器scheduler會(huì)在所有的node節(jié)點(diǎn)上運(yùn)行一個(gè)Pod副本,可以通過如下三種方式將Pod運(yùn)行在部分節(jié)點(diǎn)上:
- 指定nodeName節(jié)點(diǎn)運(yùn)行
- 通過標(biāo)簽運(yùn)行nodeSelector
- 通過親和力調(diào)度node Affinity和node Anti-affinity
DaemonSet調(diào)度算法用于實(shí)現(xiàn)將Pod運(yùn)行在特定的node節(jié)點(diǎn)上,如下以通過node affinity親和力將Pod調(diào)度到部分的節(jié)點(diǎn)上node-2上為例。
- 為node添加一個(gè)app=web的labels
[root@node-1 happylau]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
node-1 Ready master 47d v1.15.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-1,kubernetes.io/os=linux,node-role.kubernetes.io/master=
node-2 Ready <none> 47d v1.15.3 app=web,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-2,kubernetes.io/os=linux
node-3 Ready <none> 47d v1.15.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-3,kubernetes.io/os=linux
- 添加node affinity親和力調(diào)度算法,requiredDuringSchedulingIgnoredDuringExecution設(shè)置基本需要滿足條件,preferredDuringSchedulingIgnoredDuringExecution設(shè)置優(yōu)選滿足條件
[root@node-1 happylau]# cat fluentd-es-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:
- 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
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution: #優(yōu)先滿足條件
- weight: 1
preference:
matchExpressions:
- key: app
operator: In
values:
- web
requiredDuringSchedulingIgnoredDuringExecution: #要求滿足條件
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node-2
- node-3
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- 生成DS,并查看列表
[root@node-1 happylau]# kubectl delete ds -n kube-system fluentd-elasticsearch
daemonset.extensions "fluentd-elasticsearch" deleted
[root@node-1 happylau]# kubectl get daemonsets -n kube-system fluentd-elasticsearch
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd-elasticsearch 1 1 1 1 1 <none> 112s
- 校驗(yàn)Pod運(yùn)行的情況,DaemonSet的Pod調(diào)度到node-2節(jié)點(diǎn)上
[root@node-1 happylau]# kubectl get pods -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES <none>
fluentd-elasticsearch-9kngs 1/1 Running 0 2m39s 10.244.1.82 node-2 <none> <none>
寫在最后
本文介紹了kubernetes中DaemonSet控制器,DS控制器能確保所有的節(jié)點(diǎn)運(yùn)行一個(gè)特定的daemon守護(hù)進(jìn)程,此外通過nodeSelector或node Affinity能夠?qū)崿F(xiàn)將Pod調(diào)度到特定的node節(jié)點(diǎn)。
參考文檔
DaemonSet:https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
當(dāng)你的才華撐不起你的野心時(shí),你就應(yīng)該靜下心來學(xué)習(xí)
?
如果覺得文章對(duì)您有幫助,請訂閱專欄,分享給有需要的朋友吧??
關(guān)于作者 劉海平(HappyLau )云計(jì)算高級(jí)顧問 目前在騰訊云從事公有云相關(guān)工作,曾就職于酷狗,EasyStack,擁有多年公有云+私有云計(jì)算架構(gòu)設(shè)計(jì),運(yùn)維,交付相關(guān)經(jīng)驗(yàn),參與了酷狗,南方電網(wǎng),國泰君安等大型私有云平臺(tái)建設(shè),精通Linux,Kubernetes,OpenStack,Ceph等開源技術(shù),在云計(jì)算領(lǐng)域具有豐富實(shí)戰(zhàn)經(jīng)驗(yàn),擁有RHCA/OpenStack/Linux授課經(jīng)驗(yàn)。