什么是 DaemonSet? 编写 DaemonSet 规约 必需字段 Pod 模板 Pod Selector 仅在某些节点上运行 Pod 如何调度 Daemon Pod 与 Daemon Pod 通讯 更新 DaemonSet DaemonSet 的可替代选择 init 脚本 裸 Pod 静态 Pod Replication Controller
什么是 DaemonSet?前端
DaemonSet 确保所有(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时,也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它建立的全部 Pod。node
使用 DaemonSet 的一些典型用法:数据库
运行集群存储 daemon,例如在每一个节点上运行 glusterd、ceph。 在每一个节点上运行日志收集 daemon,例如fluentd、logstash。 在每一个节点上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。
一个简单的用法是在全部的节点上都启动一个 DaemonSet,将被做为每种类型的 daemon 使用。 一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,但具备不一样的标志,和/或对不一样硬件类型具备不一样的内存、CPU要求。
编写 DaemonSet 规约
必需字段api
和其它全部 Kubernetes 配置同样,DaemonSet 须要 apiVersion、kind 和 metadata 字段。 有关配置文件的基本信息,详见文档 deploying applications、配置容器 和 资源管理 。服务器
DaemonSet 也须要一个 .spec 配置段。
Pod 模板网络
.spec 惟一必需的字段是 .spec.template。app
.spec.template 是一个 Pod 模板。 它与 Pod 具备相同的 schema,除了它是嵌套的,并且不具备 apiVersion 或 kind 字段。less
除了 Pod 必需字段外,在 DaemonSet 中的 Pod 模板必须指定合理的标签(查看 Pod Selector)。ide
在 DaemonSet 中的 Pod 模板必须具备一个值为 Always 的 RestartPolicy,或者未指定它的值,默认是 Always。
Pod Selector工具
.spec.selector 字段表示 Pod Selector,它与 Job 或其它资源的 .spec.selector 的做用是相同的。
spec.selector 表示一个对象,它由以下两个字段组成:
matchLabels - 与 ReplicationController 的 .spec.selector 的做用相同。 matchExpressions - 容许构建更加复杂的 Selector,能够经过指定 key、value 列表,以及与 key 和 value 列表相关的操做符。
当上述两个字段都指定时,结果表示的是 AND 关系。
若是指定了 .spec.selector,必须与 .spec.template.metadata.labels 相匹配。若是没有指定,它们默认是等价的。若是与它们配置的不匹配,则会被 API 拒绝。
若是 Pod 的 label 与 selector 匹配,或者直接基于其它的 DaemonSet、或者 Controller(例如 ReplicationController),也不能够建立任何 Pod。 不然 DaemonSet Controller 将认为那些 Pod 是它建立的。Kubernetes 不会阻止这样作。一个场景是,可能但愿在一个具备不一样值的、用来测试用的节点上手动建立 Pod。
仅在某些节点上运行 Pod
若是指定了 .spec.template.spec.nodeSelector,DaemonSet Controller 将在可以与 Node Selector 匹配的节点上建立 Pod。 相似这种状况,能够指定 .spec.template.spec.affinity,而后 DaemonSet Controller 将在可以与 Node Affinity 匹配的节点上建立 Pod。 若是根本就没有指定,则 DaemonSet Controller 将在全部节点上建立 Pod。
如何调度 Daemon Pod
正常状况下,Pod 运行在哪一个机器上是由 Kubernetes 调度器来选择的。然而,由 Daemon Controller 建立的 Pod 已经肯定了在哪一个机器上(Pod 建立时指定了 .spec.nodeName),所以:
DaemonSet Controller 并不关心一个节点的 unschedulable 字段。 DaemonSet Controller 能够建立 Pod,即便调度器尚未启动,这对集群启动是很是有帮助的。
Daemon Pod 关心 Taint 和 Toleration,它们会为没有指定 tolerationSeconds 的 node.kubernetes.io/not-ready 和 node.alpha.kubernetes.io/unreachable 的 Taint,建立具备 NoExecute 的 Toleration。这确保了当 alpha 特性的 TaintBasedEvictions 被启用时,发生节点故障,好比网络分区,这时它们将不会被清除掉(当 TaintBasedEvictions 特性没有启用,在这些场景下也不会被清除,但会由于 NodeController 的硬编码行为而被清除,而不会由于 Toleration 致使被清除)。
与 Daemon Pod 通讯
与 DaemonSet 中的 Pod 进行通讯,几种可能的模式以下:
Push:配置 DaemonSet 中的 Pod 向其它 Service 发送更新,例如统计数据库。它们没有客户端。 NodeIP 和已知端口:DaemonSet 中的 Pod 可使用 hostPort,从而能够经过节点 IP 访问到 Pod。客户端能经过某种方法知道节点 IP 列表,而且基于此也能够知道端口。 DNS:建立具备相同 Pod Selector 的 Headless Service,而后经过使用 endpoints 资源或从 DNS 检索到多个 A 记录来发现 DaemonSet。 Service:建立具备相同 Pod Selector 的 Service,并使用该 Service 随机访问到某个节点上的 daemon(没有办法访问到特定节点)。
更新 DaemonSet
若是修改了节点标签(Label),DaemonSet 将马上向新匹配上的节点添加 Pod,同时删除新近不可以匹配的节点上的 Pod。
咱们能够修改 DaemonSet 建立的 Pod。然而,不容许对 Pod 的全部字段进行更新。当下次节点(即便具备相同的名称)被建立时,DaemonSet Controller 还会使用最初的模板。
能够删除一个 DaemonSet。若是使用 kubectl 并指定 --cascade=false 选项,则 Pod 将被保留在节点上。而后能够建立具备不一样模板的新 DaemonSet。具备不一样模板的新 DaemonSet 将可以经过标签匹配并识别全部已经存在的 Pod。它不会修改或删除它们,即便是错误匹配了 Pod 模板。经过删除 Pod 或者删除节点,能够强制建立新的 Pod。
在 Kubernetes 1.6 或之后版本,能够在 DaemonSet 上 执行滚动升级。
将来的 Kubernetes 版本将支持节点的可控更新。
DaemonSet 的可替代选择
init 脚本
咱们极可能但愿直接在一个节点上启动 daemon 进程(例如,使用 init、upstartd、或 systemd)。这很是好,但基于 DaemonSet 来运行这些进程有以下一些好处:
像对待应用程序同样,具有为 daemon 提供监控和管理日志的能力。 为 daemon 和应用程序使用相同的配置语言和工具(如 Pod 模板、kubectl)。 Kubernetes 将来版本可能会支持对 DaemonSet 建立 Pod 与节点升级工做流进行集成。 在资源受限的容器中运行 daemon,可以增长 daemon 和应用容器的隔离性。然而,这也实现了在容器中运行 daemon,但却不能在 Pod 中运行(例如,直接基于 Docker 启动)。
裸 Pod
可能要直接建立 Pod,同时指定其运行在特定的节点上。 然而,DaemonSet 替换了因为任何缘由被删除或终止的 Pod,例如节点失败、例行节点维护、内核升级。因为这个缘由,咱们应该使用 DaemonSet 而不是单首创建 Pod。
静态 Pod
可能须要经过在一个指定目录下编写文件来建立 Pod,该目录受 Kubelet 所监视。这些 Pod 被称为 静态 Pod。 不像 DaemonSet,静态 Pod 不受 kubectl 和其它 Kubernetes API 客户端管理。静态 Pod 不依赖于 apiserver,这使得它们在集群启动的状况下很是有用。 并且,将来静态 Pod 可能会被废弃掉。
Replication Controller
DaemonSet 与 Replication Controller 很是相似,它们都能建立 Pod,这些 Pod 对应的进程都不但愿被终止掉(例如,Web 服务器、存储服务器)。 为无状态的 Service 使用 Replication Controller,好比前端(Frontend)服务,实现对副本的数量进行扩缩容、平滑升级,比之于精确控制 Pod 运行在某个主机上要重要得多。 须要 Pod 副本老是运行在所有或特定主机上,并须要先于其余 Pod 启动,当这被认为很是重要时,应该使用 Daemon Controller