12 详解DaemonSet控制器

unlisted · suofeiya's blog

#kubernetes

Table of Contents

写在前面 #

上章节中介绍了Deployment,ReplicaSet,ReplicationController等副本控制器的使用和场景,接下来介绍kubernetes系列教程控制器DaemonSet使用。

1. DaemonSet控制器 #

1.1 DaemonSet简介 #

介绍DaemonSet时我们先来思考一个问题:相信大家都接触过监控系统比如zabbix,监控系统需要在被监控机安装一个agent,安装agent通常会涉及到以下几个场景:

kubernetes中经常涉及到在node上安装部署应用,它是如何解决上述的问题的呢?答案是DaemonSet。DaemonSet守护进程简称DS,适用于在所有节点或部分节点运行一个daemon守护进程,如监控我们安装部署时网络插件kube-flannel和kube-proxy,DaemonSet具有如下特点:

DaemnonSet控制器

DaemonSet适用于每个node节点均需要部署一个守护进程的场景,常见的场景例如:

安装k8s时默认在kube-system命名空间已经安装了有两个DaemonSet,分别为kube-flannel-ds-amd64和kube-proxy,分别负责flannel overlay网络的互通和service代理的实现,可以通过如下命令查看:

\1. 查看kube-system命令空间的DaemonSet列表,当前集群有三个node节点,所以每个DS会运行三个Pod副本

1[root@node-1 ~]# kubectl get ds -n kube-system 
2NAME                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                   AGE
3kube-flannel-ds-amd64   3         3         3       3            3           beta.kubernetes.io/arch=amd64   46d
4kube-proxy              3         3         3       3            3           beta.kubernetes.io/os=linux     46d

\2. 查看Pod的副本情况,可以看到DaemonSet在每个节点都运行一个Pod

img

1.2 DaemonSet定义 #

DaemonSet的定义和Deployment定义使用相类似,需要定义apiVersion,Kind,metadata和spec属性信息,spec中不需要定义replicas个数,spec.template即定义DS生成容器的模版信息,如下是运行一个fluentd-elasticsearch镜像容器的daemon守护进程,运行在每个node上通过fluentd采集日志上报到ElasticSearch。

\1. 通过yaml文件定义DaemonSet

 1[root@node-1 happylau]# cat fluentd-es-daemonset.yaml 
 2apiVersion: apps/v1              #api版本信息
 3kind: DaemonSet                  #类型为DaemonSet
 4metadata:                        #元数据信息
 5  name: fluentd-elasticsearch
 6  namespace: kube-system        #运行的命名空间
 7  labels:
 8    k8s-app: fluentd-logging
 9spec:                          #DS模版
10  selector:
11    matchLabels:
12      name: fluentd-elasticsearch
13  template:
14    metadata:
15      labels:
16        name: fluentd-elasticsearch
17    spec:
18      tolerations:
19      - key: node-role.kubernetes.io/master
20        effect: NoSchedule
21      containers:            #容器信息
22      - name: fluentd-elasticsearch
23        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
24        resources:          #resource资源
25          limits:
26            memory: 200Mi
27          requests:
28            cpu: 100m
29            memory: 200Mi
30        volumeMounts:      #挂载存储agent需要到这些目录采集日志
31        - name: varlog
32          mountPath: /var/log
33        - name: varlibdockercontainers
34          mountPath: /var/lib/docker/containers
35          readOnly: true
36      terminationGracePeriodSeconds: 30
37      volumes:            #将主机的目录以hostPath的形式挂载到容器Pod中
38      - name: varlog
39        hostPath:
40          path: /var/log
41      - name: varlibdockercontainers
42        hostPath:
43          path: /var/lib/docker/containers

DaemonSet定义注意事项:

\2. 生成DaemonSet

1[root@node-1 happylau]# kubectl apply -f fluentd-es-daemonset.yaml 
2daemonset.apps/fluentd-elasticsearch created

\3. 查看DaemonSet列表

1[root@node-1 happylau]# kubectl get daemonsets -n kube-system  fluentd-elasticsearch 
2NAME                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
3fluentd-elasticsearch   3         3         3       3            3           <none>          16s

\4. 查看node上运行Pod的情况,在NODE列可以看到每个node都运行了一个Pod

1[root@node-1 happylau]# kubectl get pods -n kube-system -o wide |grep fluentd 
2fluentd-elasticsearch-blpqb      1/1     Running   0          3m7s   10.244.2.79      node-3   <none>           <none>
3fluentd-elasticsearch-ksdlt      1/1     Running   0          3m7s   10.244.0.11      node-1   <none>           <none>
4fluentd-elasticsearch-shtkh      1/1     Running   0          3m7s   10.244.1.64      node-2   <none>           <none>

\5. 查看DaemonSet详情,可以看到DaemonSet支持RollingUpdate滚动更新策略

 1[root@node-1 happylau]# kubectl get daemonsets -n kube-system fluentd-elasticsearch -o yaml
 2apiVersion: extensions/v1beta1
 3kind: DaemonSet
 4metadata:
 5  annotations:
 6    kubectl.kubernetes.io/last-applied-configuration: |
 7      {"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"}]}}}}
 8  creationTimestamp: "2019-10-30T15:19:20Z"
 9  generation: 1
10  labels:
11    k8s-app: fluentd-logging
12  name: fluentd-elasticsearch
13  namespace: kube-system
14  resourceVersion: "6046222"
15  selfLink: /apis/extensions/v1beta1/namespaces/kube-system/daemonsets/fluentd-elasticsearch
16  uid: c2c02c48-9f93-48f3-9d6c-32bfa671db0e
17spec:
18  revisionHistoryLimit: 10
19  selector:
20    matchLabels:
21      name: fluentd-elasticsearch
22  template:
23    metadata:
24      creationTimestamp: null
25      labels:
26        name: fluentd-elasticsearch
27    spec:
28      containers:
29      - image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
30        imagePullPolicy: IfNotPresent
31        name: fluentd-elasticsearch
32        resources:
33          limits:
34            memory: 200Mi
35          requests:
36            cpu: 100m
37            memory: 200Mi
38        terminationMessagePath: /dev/termination-log
39        terminationMessagePolicy: File
40        volumeMounts:
41        - mountPath: /var/log
42          name: varlog
43        - mountPath: /var/lib/docker/containers
44          name: varlibdockercontainers
45          readOnly: true
46      dnsPolicy: ClusterFirst
47      restartPolicy: Always             #重启策略必须为Always保障异常时能自动恢复
48      schedulerName: default-scheduler  #默认调度策略
49      securityContext: {}
50      terminationGracePeriodSeconds: 30
51      tolerations:
52      - effect: NoSchedule
53        key: node-role.kubernetes.io/master
54      volumes:
55      - hostPath:
56          path: /var/log
57          type: ""
58        name: varlog
59      - hostPath:
60          path: /var/lib/docker/containers
61          type: ""
62        name: varlibdockercontainers
63  templateGeneration: 1
64  updateStrategy:  #滚动更新策略
65    rollingUpdate:
66      maxUnavailable: 1
67    type: RollingUpdate
68status:
69  currentNumberScheduled: 3
70  desiredNumberScheduled: 3
71  numberAvailable: 3
72  numberMisscheduled: 0
73  numberReady: 3
74  observedGeneration: 1
75  updatedNumberScheduled: 3

1.3 滚动更新与回滚 #

\1. 更新镜像至最新版本

1[root@node-1 ~]# kubectl set image daemonsets fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:latest -n kube-system
2daemonset.extensions/fluentd-elasticsearch image updated

\2. 查看滚动更新状态

1[root@node-1 ~]# kubectl rollout status daemonset -n kube-system fluentd-elasticsearch 
2Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 1 out of 3 new pods have been updated...
3Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 1 out of 3 new pods have been updated...
4Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 1 out of 3 new pods have been updated...
5Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 out of 3 new pods have been updated...
6Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 out of 3 new pods have been updated...
7Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 out of 3 new pods have been updated...
8Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 of 3 updated pods are available...
9daemon set "fluentd-elasticsearch" successfully rolled out

\3. 查看DaemonSet详情,可以看到DS滚动更新的过程:DaemonSet先将node上的pod删除然后再创建

DaemonSet滚动更新过程

\4. 查看DaemonSet滚动更新版本,REVSION 1为初始的版本

1[root@node-1 ~]# kubectl rollout history daemonset -n kube-system fluentd-elasticsearch 
2daemonset.extensions/fluentd-elasticsearch 
3REVISION  CHANGE-CAUSE
41         <none>
52         <none>

\5. 更新回退,如果配置没有符合到预期可以回滚到原始的版本

1[root@node-1 ~]# kubectl rollout undo daemonset -n kube-system fluentd-elasticsearch --to-revision=1
2daemonset.extensions/fluentd-elasticsearch rolled back

\6. 确认版本回退情况

DaemonSet版本回退

\7. 观察版本回退的过程,回退的过程和和滚动更新过程类似,先删除Pod再创建

DaemonSet回退过程

\8. 删除DaemonSet

1[root@node-1 ~]# kubectl delete daemonsets -n kube-system fluentd-elasticsearch 
2daemonset.extensions "fluentd-elasticsearch" deleted
3[root@node-1 ~]# kubectl get pods -n kube-system |grep fluentd
4fluentd-elasticsearch-d6f6f      0/1     Terminating   0          110m

1.4 DaemonSet调度 #

前面kubernetes系列教程(七)深入玩转pod调度文章介绍了Pod的调度机制,DaemonSet通过kubernetes默认的调度器scheduler会在所有的node节点上运行一个Pod副本,可以通过如下三种方式将Pod运行在部分节点上:

DaemonSet调度算法用于实现将Pod运行在特定的node节点上,如下以通过node affinity亲和力将Pod调度到部分的节点上node-2上为例。

\1. 为node添加一个app=web的labels

1[root@node-1 happylau]# kubectl get nodes --show-labels 
2NAME     STATUS   ROLES    AGE   VERSION   LABELS
3node-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=
4node-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
5node-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

\2. 添加node affinity亲和力调度算法,requiredDuringSchedulingIgnoredDuringExecution设置基本需要满足条件,preferredDuringSchedulingIgnoredDuringExecution设置优选满足条件

 1[root@node-1 happylau]# cat fluentd-es-daemonset.yaml 
 2apiVersion: apps/v1
 3kind: DaemonSet
 4metadata:
 5  name: fluentd-elasticsearch
 6  namespace: kube-system
 7  labels:
 8    k8s-app: fluentd-logging
 9spec:
10  selector:
11    matchLabels:
12      name: fluentd-elasticsearch
13  template:
14    metadata:
15      labels:
16        name: fluentd-elasticsearch
17    spec:
18      tolerations:
19      - key: node-role.kubernetes.io/master
20        effect: NoSchedule
21      containers:
22      - name: fluentd-elasticsearch
23        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
24        resources:
25          limits:
26            memory: 200Mi
27          requests:
28            cpu: 100m
29            memory: 200Mi
30        volumeMounts:
31        - name: varlog
32          mountPath: /var/log
33        - name: varlibdockercontainers
34          mountPath: /var/lib/docker/containers
35          readOnly: true
36      affinity:
37        nodeAffinity:
38          preferredDuringSchedulingIgnoredDuringExecution:  #优先满足条件
39          - weight: 1
40            preference:
41              matchExpressions:
42              - key: app 
43                operator: In
44                values:
45                - web 
46          requiredDuringSchedulingIgnoredDuringExecution:  #要求满足条件
47            nodeSelectorTerms:
48            - matchExpressions:
49              - key: kubernetes.io/hostname
50                operator: In
51                values:
52                - node-2
53                - node-3
54      terminationGracePeriodSeconds: 30
55      volumes:
56      - name: varlog
57        hostPath:
58          path: /var/log
59      - name: varlibdockercontainers
60        hostPath:
61          path: /var/lib/docker/containers

\3. 生成DS,并查看列表

1[root@node-1 happylau]# kubectl delete ds -n kube-system fluentd-elasticsearch 
2daemonset.extensions "fluentd-elasticsearch" deleted
3
4[root@node-1 happylau]# kubectl get daemonsets -n kube-system fluentd-elasticsearch 
5NAME                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
6fluentd-elasticsearch   1         1         1       1            1           <none>          112s

\4. 校验Pod运行的情况,DaemonSet的Pod调度到node-2节点上

1[root@node-1 happylau]# kubectl get pods -n kube-system -o wide 
2NAME                             READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES          <none>
3fluentd-elasticsearch-9kngs      1/1     Running   0          2m39s   10.244.1.82      node-2   <none>           <none>

写在最后 #

本文介绍了kubernetes中DaemonSet控制器,DS控制器能确保所有的节点运行一个特定的daemon守护进程,此外通过nodeSelector或node Affinity能够实现将Pod调度到特定的node节点。

参考文档 #

DaemonSet**:**https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/

『 转载 』该文章来源于网络,侵删。