守护进程集 (DS, DaemonSet) 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

使用 DaemonSet 一些典型使用场景:

  • 运行集群存储 daemon,例如在每个 Node 上运行 glusterdceph
  • 在每个 Node 上运行日志收集 daemon,例如fluentdlogstash
  • 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exportercollectd、Datadog 代理、New Relic 代理,或 Ganglia gmond

一个简单的用法是,在所有的 Node 上都存在一个 DaemonSet,将被作为每种类型的 daemon 使用。 一个稍微复杂的用法可能是,对单独的每种类型的 daemon 使用多个 DaemonSet,但具有不同的标志,和/或对不同硬件类型具有不同的内存、CPU 要求。

yaml 示例

下面的描述文件创建了一个运行着 fluentd-elasticsearch 镜像的 DaemonSet 对象:

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: fluentd-elasticsearch
  5. namespace: kube-system
  6. labels:
  7. k8s-app: fluentd-logging
  8. spec:
  9. selector:
  10. matchLabels: # 与spec.template.metadata.labels一致
  11. name: fluentd-elasticsearch
  12. template: # pod模板
  13. metadata:
  14. labels:
  15. name: fluentd-elasticsearch
  16. spec:
  17. tolerations:
  18. - key: node-role.kubernetes.io/master
  19. effect: NoSchedule
  20. containers: # 容器模板
  21. - name: fluentd-elasticsearch
  22. image: k8s.gcr.io/fluentd-elasticsearch:1.20
  23. resources:
  24. limits:
  25. memory: 200Mi
  26. requests:
  27. cpu: 100m
  28. memory: 200Mi
  29. volumeMounts:
  30. - name: varlog
  31. mountPath: /var/log
  32. - name: varlibdockercontainers
  33. mountPath: /var/lib/docker/containers
  34. readOnly: true
  35. terminationGracePeriodSeconds: 30
  36. volumes: # 对外暴露的卷
  37. - name: varlog
  38. hostPath:
  39. path: /var/log
  40. - name: varlibdockercontainers
  41. hostPath:
  42. path: /var/lib/docker/containers

在 Kubernetes 1.8 之后,必须指定.spec.selector 来确定这个 DaemonSet 对象管理的 Pod,通常与.spec.template.metadata.labels 中定义的 Pod 的 label 一致。

Pod 模板

.spec 唯一必需的字段是 .spec.template

.spec.template 是一个 Pod 模板。 它与 Pod 具有相同的 schema,除了它是嵌套的,而且不具有 apiVersionkind 字段。

Pod 除了必须字段外,在 DaemonSet 中的 Pod 模板必须指定合理的标签(查看 pod selector)。

在 DaemonSet 中的 Pod 模板必需具有一个值为 AlwaysRestartPolicy,或者未指定它的值,默认是 Always

Daemon Pods 的调度特性

默认情况下,Pod 被分配到具体哪一台 Node 上运行是由 Scheduler(负责分配调度 Pod 到集群内的 Node 上,它通过监听 ApiServer,查询还未分配 Node 的 Pod,然后根据调度策略为这些 Pod 分配 Node)决定的。但是,DaemonSet 对象创建的 Pod 却拥有一些特殊的特性:

  • Node 的 unschedulable属性会被 DaemonSet Controller 忽略。
  • 即使 Scheduler 还未启动,DaemonSet Controller 也能够创建并运行 Pod。