DaemonSet控制器

官方文档:https://v1-16.docs.kubernetes.io/zh/docs/concepts/workloads/controllers/daemonset/

DaemonSet是Pod控制器的一种实现,用于在集群中的全部节点上同事运行一份指定的Pod资源副本,后续新加入集群的工作节点也会自动创建一个相关的Pod对象,当从集群移除节点时,此类Pod对象也将被自动回收而无须创建。管理员也可以使用节点选择器及节点标签指定仅在部分具有特定特征的节点运行指定的Pod对象

DaemonSet是一种特殊的控制器,它有特定的应用场景,通常运行那些执行系统级操作任务的应用,其应用场景具体如下:

  • 运行集群存储的守护进程,如在各个节点上运行glusterd或ceph
  • 在各个节点上运行日志收集守护进程,如fluentd和logstash
  • 在各个节点上运行监控系统的代理守护程序,如Promethues Node exporter、collectd、datadog agent、new relic agent或ganglia gmond等
    当然,既然是需要运行于集群内的每个节点或部分节点,于是很多场景中也可以把应用直接运维工作节点上的系统级守护进程,不过,这样一来就失去了运用K9S管理所带来的便捷性。另外,也只有必须将Pod对象运行于固定的几个节点并且需要先于其他Pod启动时,才有必要使用DaemonSet控制器,否则就应该使用Deployment控制器

创建DaemonSet资源对象

DaemoSet控制器的spec字段中嵌套使用字段同样主要包含了前面讲到的Pod控制器资源支持的selector、template和minReadySeconds,并且功能和用法基本相同,但它不支持使用replicas,毕竟daemonSet并不是基于期望的副本数来控制Pod资源数量,而实基于节点数量。但template是必须字段 下面的资源清单文件(filebeat-ds.yaml)示例中定义了一个名为filebeat-ds的DaemonSet控制器,它将在每个节点上运行一个filebeat进程以收集容器相关数据

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: filebeat-ds
  5. labels:
  6. app: filebeat
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: filebeat
  11. template:
  12. metadata:
  13. labels:
  14. app: filebeat
  15. name: filebeat
  16. spec:
  17. containers:
  18. - name: filebeat
  19. image: docker.io/ikubernetes/filebeat:5.6.5-alpine
  20. env:
  21. - name: REDIS_HOST
  22. value: db.linux.io:6379
  23. - name: LOG_LEVEL
  24. value: info

通过清单文件创建DaemonSet资源的命令与其他资源的创建并没有什么不同

  1. [root@k8s-master01 nginx]# kubectl apply -f filebeat-ds.yaml --record
  2. daemonset.apps/filebeat-ds created
  3. [root@k8s-master01 nginx]#

注意:从K8S 1.8版本起,DaemonSet也必须使用selector来匹配模板中指定的标签,而且它也支持matchLabels和matchExoressions两种标签选择器

与其他资源对象相同,用户也可以使用kubectl describe命令查看DaemonSet对象的详细信息。下面命令的结果信息中,Node-Selector字段的值为空,表示它需要运行于集群中的每个节点之上,而当集群的节点数量为2,因此,其期望的Pod副本数(Descired Number of Nodes Scheduled)为2,而当前也已经成功创建了2个相关的Pod对象

  1. [root@k8s-master01 nginx]# kubectl describe daemonset filebeat-ds
  2. Name: filebeat-ds
  3. Selector: app=filebeat
  4. Node-Selector: <none>
  5. Labels: app=filebeat
  6. Annotations: deprecated.daemonset.template.generation: 1
  7. kubectl.kubernetes.io/last-applied-configuration:
  8. {"apiVersion":"apps/v1","kind":"DaemonSet","metadata":{"annotations":{"kubernetes.io/change-cause":"kubectl apply --filename=filebeat-ds.y...
  9. kubernetes.io/change-cause: kubectl apply --filename=filebeat-ds.yaml --record=true
  10. Desired Number of Nodes Scheduled: 2
  11. Current Number of Nodes Scheduled: 2
  12. Number of Nodes Scheduled with Up-to-date Pods: 2
  13. Number of Nodes Scheduled with Available Pods: 2
  14. Number of Nodes Misscheduled: 0
  15. Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
  16. Pod Template:
  17. Labels: app=filebeat
  18. name=filebeat
  19. Containers:
  20. filebeat:
  21. Image: docker.io/ikubernetes/filebeat:5.6.5-alpine
  22. Port: <none>
  23. Host Port: <none>
  24. Environment:
  25. REDIS_HOST: db.linux.io:6379
  26. LOG_LEVEL: info
  27. Mounts: <none>
  28. Volumes: <none>
  29. Events:
  30. Type Reason Age From Message
  31. ---- ------ ---- ---- -------
  32. Normal SuccessfulCreate 16s daemonset-controller Created pod: filebeat-ds-56b76
  33. Normal SuccessfulCreate 16s daemonset-controller Created pod: filebeat-ds-4tfj6
  34. [root@k8s-master01 nginx]#

根据DaemonSet资源本身的意义,filebeat-ds控制器成功创建的2个Pod对象应该分别运行于集群中的每个节点之上,这一点可以通过如下命令进行验证

  1. [root@k8s-master01 nginx]# kubectl get pods -l app=filebeat -o custom-columns=NAME:metadata.name,Node:spec.nodeName
  2. NAME Node
  3. filebeat-ds-4tfj6 172.18.15.113
  4. filebeat-ds-56b76 172.18.15.114
  5. [root@k8s-master01 nginx]#

集群的部分工作节点偶尔也存在需要将Pod对象以单一实列形式运行的情况,例如,对于拥有特殊硬件的节点来说,可能会需要为其运行特定的监控代理(agent)程序,等等。其实实现方面与前面讲到的Pod资源的节点绑定机制类似,只需要在Pod模板的spec字段中嵌套使用nodeselector字段,并确保其值定义的标签选择器与部分特定工作节点的标签匹配即可

更新DaemonSet对象

DaemonSet自K8S 1.6版本开始支持更新机制,相关配置定义在spec.update-Strategy嵌套字段中。目前,它支持RollingUpdate(滚动更新)和OnDelete(删除时更新)两种更新策略,滚动更新为默认的更新策略,工作逻辑类似于Deployment控制器,不过仅支持shiyongmaxUnavilabel属性定义最大不可用Pod资源副本数(默认值为1),而删除时更新的方式则是在删除相应节点的Pod资源后重建并更新为新版本 例如,将此前创建的filebeat-ds种Pod模板种的容器镜像升级为docker.io/ikubernetes/filebeat:5.6.6-alpine

  1. [root@k8s-master01 nginx]# kubectl set image daemonsets filebeat-ds filebeat=docker.io/ikubernetes/filebeat:5.6.6-alpine --record
  2. daemonset.apps/filebeat-ds image updated
  3. [root@k8s-master01 nginx]#

由下面的命令的返回结果可以看出,filebeat-ds控制器Pod模板中的容器镜像文件已经完成更新,对滚动更新策略来说,它会自动触发更新操作。用户也可以通过filebeat-ds控制器的详细信息中的events字段等来了解滚动更新的操作过程。由下面的命令结果可以看出,默认的滚动更新策略一次删除一个工作节点上的Pod资源,待其新版本Pod资源重建完成后再开始操作另外一个工作节点上的Pod资源

  1. [root@k8s-master01 nginx]# kubectl describe daemonset filebeat-ds
  2. Name: filebeat-ds
  3. Selector: app=filebeat
  4. Node-Selector: <none>
  5. Labels: app=filebeat
  6. Annotations: deprecated.daemonset.template.generation: 2
  7. kubectl.kubernetes.io/last-applied-configuration:
  8. {"apiVersion":"apps/v1","kind":"DaemonSet","metadata":{"annotations":{"kubernetes.io/change-cause":"kubectl apply --filename=filebeat-ds.y...
  9. kubernetes.io/change-cause: kubectl set image daemonsets filebeat-ds filebeat=docker.io/ikubernetes/filebeat:5.6.6-alpine --record=true
  10. Desired Number of Nodes Scheduled: 2
  11. Current Number of Nodes Scheduled: 2
  12. Number of Nodes Scheduled with Up-to-date Pods: 2
  13. Number of Nodes Scheduled with Available Pods: 2
  14. Number of Nodes Misscheduled: 0
  15. Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
  16. Pod Template:
  17. Labels: app=filebeat
  18. name=filebeat
  19. Containers:
  20. filebeat:
  21. Image: docker.io/ikubernetes/filebeat:5.6.6-alpine
  22. Port: <none>
  23. Host Port: <none>
  24. Environment:
  25. REDIS_HOST: db.linux.io:6379
  26. LOG_LEVEL: info
  27. Mounts: <none>
  28. Volumes: <none>
  29. Events:
  30. Type Reason Age From Message
  31. ---- ------ ---- ---- -------
  32. Normal SuccessfulCreate 3m36s daemonset-controller Created pod: filebeat-ds-56b76
  33. Normal SuccessfulCreate 3m36s daemonset-controller Created pod: filebeat-ds-4tfj6
  34. Normal SuccessfulDelete 2m8s daemonset-controller Deleted pod: filebeat-ds-56b76
  35. Normal SuccessfulCreate 116s daemonset-controller Created pod: filebeat-ds-rjqrf
  36. Normal SuccessfulDelete 115s daemonset-controller Deleted pod: filebeat-ds-4tfj6
  37. Normal SuccessfulCreate 113s daemonset-controller Created pod: filebeat-ds-jpk96
  38. [root@k8s-master01 nginx]#

DaemonSet控制器的滚动更新机制也可以借助于minReadySeconds字段控制滚动节奏,必要时可以执行暂停和继续操作,因此它也能够设计为金丝雀发布机制。另外,故障的更新操作也可以进行回滚,包括回滚至revision历史记录中的任何一个指定版本,例如,下面的例子就是回滚到指定revision的版本

  1. [root@k8s-master01 nginx]# kubectl rollout history daemonset filebeat-ds
  2. daemonset.apps/filebeat-ds
  3. REVISION CHANGE-CAUSE
  4. 1 kubectl apply --filename=filebeat-ds.yaml --record=true
  5. 2 kubectl set image daemonsets filebeat-ds filebeat=docker.io/ikubernetes/filebeat:5.6.6-alpine --record=true
  6. 3 kubectl set image daemonsets filebeat-ds filebeat=docker.io/ikubernetes/filebeat:5.6.7-alpine --record=true
  7. [root@k8s-master01 nginx]#
  8. [root@k8s-master01 nginx]# kubectl get daemonset filebeat-ds -o wide
  9. NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
  10. filebeat-ds 2 2 2 2 2 <none> 9m22s filebeat docker.io/ikubernetes/filebeat:5.6.7-alpine app=filebeat
  11. [root@k8s-master01 nginx]#
  12. [root@k8s-master01 nginx]# kubectl rollout undo daemonset filebeat-ds --to-revision=1
  13. daemonset.apps/filebeat-ds rolled back
  14. [root@k8s-master01 nginx]#
  15. [root@k8s-master01 nginx]# kubectl get daemonset filebeat-ds -o wide
  16. NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
  17. filebeat-ds 2 2 2 2 2 <none> 11m filebeat docker.io/ikubernetes/filebeat:5.6.5-alpine app=filebeat
  18. [root@k8s-master01 nginx]#