DaemonSet确保全部(或部分,取决于你对DaemonSet限制要求)节点上运行一个Pod的副本。当有节点加入集群时,也会自动为此节点新增一个Pod 。 当有节点从集群移除时,这些Pod也会被回收。删除DaemonSet将会删除它创建的所有Pod。

常用场景:

  • 运行集群存储daemon服务,例如在每个节点上运行glusterd、ceph、nfs
  • 运行日志收集daemon服务,例如fluentd、logstash
  • 运行监控客户端daemon服务,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond

编写DaemonSet

创建DaemonSet

daemonset.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
apiVersion: apps/v1
kind: DaemonSet # 创建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: gcr.io/fluentd-elasticsearch/fluentd:v2.5.1
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: # volume卷配置,用以收集运行节点的容器日志
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers

创建

1
kubectl apply -f daemonset.yaml

必填字段

与所有其他Kubernetes配置一样,DaemonSet需要:

  • apiVersion
  • kind
  • metadata
  • .spec

与其它Controller不同的时,DaemonSet不需要配置metadata.replicas字段,因为它默认会在每个可分配的节点运行一个Pod。

Pod模板

  • .spec唯一必需的字段是.spec.template。
  • .spec.template是一个Pod模板。 它与Pod具有相同的schema表单,除了它是嵌套的,且不具有apiVersion和kind字段。
  • 除了Pod必需字段外,在DaemonSet中的Pod模板必须指定合理的标签。
  • 在DaemonSet中的Pod模板必须具有一个值为AlwaysRestartPolicy,或者未指定它的值,默认是 Always

Pod选择器

.spec.selector字段表示Pod选择器,它由如下两个字段组成:

  • matchLabels - 与ReplicationController的 .spec.selector的作用相同。
  • matchExpressions - 允许构建更加复杂的选择器,可以通过指定key-value列表,以及与key-value列表相关的操作符。

当上述两个字段都指定时,结果表示的是AND逻辑关系。

如果指定了.spec.selector,必须与.spec.template.metadata.labels相匹配。没有指定则默认它们是相同的。如果它们配置的不匹配,则会被API拒绝。尽量保证不要直接创建任何与DaemonSet选择器匹配的Pod标签,否则,DaemonSet控制器会认为这些Pod是由它创建的而造成管理混乱。

节点选择器(即在部分节点运行)

如果指定.spec.template.spec.nodeSelector,则DaemonSet控制器将在与该节点选择器匹配的节点上创建Pod。 同样,如果指定.spec.template.spec.affinity,则DaemonSet控制器将在与该节点关联相匹配的节点上创建Pod。 如果您未指定任何一个,则DaemonSet控制器将在所有节点上创建Pod。

与DaemonSet的Pod通信

与DaemonSet中的Pod进行通信,有如下几种模式:

  • Push:DaemonSet中的Pod配置将更新发送到另一个没有客户端的服务,例如统计数据库。
  • NodeIP和已知端口:DaemonSet中的Pod可以使用hostPort,以便可以通过节点IP访问pod。
  • DNS:使用相同的pod选择器创建Headless无头服务,然后使用Endpoint资源发现DaemonSets或从DNS检索记录。
  • Service:使用相同的Pod选择器创建服务,并使用该服务在随机节点上访问Daemon服务。

DaemonSet更新

  • 如果更改了节点标签,DaemonSet会立即将Pod添加到新匹配的节点,并从新匹配的节点中删除不匹配的Pod。
  • DaemonSet创建的Pod不允许更新所有字段。 此外,DaemonSet控制器将在下次创建节点(包括相同名称节点)时使用原始模板。
  • 使用kubectl删除DaemonSet时如果指定–cascade=false,则Pod将保留在节点上。 然后,你可以使用不同的模板创建新的DaemonSet。 具有不同模板的新DaemonSet将所有现有Pod识别为具有匹配标签。 尽管Pod模板不匹配,现有的Pod也不会被修改或删除。 你需要通过手动删除Pod或删除节点来强制创建新的Pod。
  • 在Kubernetes 1.6及以上版本才支持DaemonSet滚动更新。