31.DaemonSet

DaemonSet

本文将为您介绍DaemonSet的基本概念。

什么是DaemonSet

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

使用DaemonSet的一些典型用法:

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

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

编写DaemonSet Spec

必需字段

和其它所有Kubernetes配置一样,DaemonSet需要 apiVersionkindmetadata字段。有关配置文件的通用信息,详见文档 部署应用配置容器 和资源管理。

DaemonSet也需要一个 .spec配置段。

Pod模板

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

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

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

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

Pod Selector

.spec.selector 字段表示Pod Selector,它与 Job 或其它资源的 .spec.selector 的原理是相同的。

spec.selector 表示一个对象,它由如下两个字段组成:

  • matchLabels -ReplicationController.spec.selector 的原理相同。
  • matchExpressions -允许构建更加复杂的Selector,可以通过指定keyvalue列表,以及与keyvalue列表的相关的操作符。

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

如果指定了 .spec.selector,必须与 .spec.template.metadata.labels 相匹配。如果没有指定,它们默认是等价的。如果与它们配置的不匹配,则会被API拒绝。

如果Podlabelselector匹配,或者直接基于其它的DaemonSet、或者Controller(例如ReplicationController,也不可以创建任何Pod。 否则DaemonSet Controller将认为那些Pod是它创建的。Kubernetes不会阻止这样做。一个场景是,可能希望在一个具有不同值的、用来测试用的Node上手动创建Pod

仅在相同的Node上运行Pod

如果指定了 .spec.template.spec.nodeSelectorDaemonSet Controller将在能够匹配上 Node SelectorNode上创建Pod。 类似这种情况,可以指定 .spec.template.spec.affinity,然后DaemonSet Controller将在能够匹配上 Node AffinityNode上创建Pod。 如果根本就没有指定,则DaemonSet Controller将在所有Node上创建Pod

如何调度Daemon Pod

正常情况下,Pod运行在哪个机器上是由Kubernetes调度器进行选择的。然而,由Daemon Controller创建的Pod已经确定了在哪个机器上(Pod创建时指定了 .spec.nodeName,因此:

  • DaemonSet Controller并不关心一个Nodeunschedulable 字段。
  • DaemonSet Controller可以创建Pod,即使调度器还没有被启动,这对集群启动是非常有帮助的。

Daemon Pod关心 TaintToleration,它们会为没有指定 tolerationSecondsnode.alpha.kubernetes.io/notReadynode.alpha.kubernetes.io/unreachableTaint,而创建具有 NoExecuteToleration。这确保了当alpha特性的 TaintBasedEvictions 被启用,当Node出现故障,比如网络分区,这时它们将不会被清除掉(当 TaintBasedEvictions 特性没有启用,在这些场景下也不会被清除,但会因为NodeController的硬编码行为而被清除,Toleration是不会的

Daemon Pod通信

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

  • Push:配置DaemonSet中的Pod向其它Service发送更新,例如统计数据库。它们没有客户端。
  • NodeIP和已知端口DaemonSet中的Pod可以使用 hostPort,从而可以通过Node IP访问到Pod。客户端能通过某种方法知道Node IP列表,并且基于此也可以知道端口。
  • DNS:创建具有相同Pod SelectorHeadless Service,然后通过使用 endpoints 资源或从DNS检索到多个A记录来发现DaemonSet
  • Service:创建具有相同Pod SelectorService,并使用该Service访问到某个随机Node上的daemon(没有办法访问到特定Node

更新DaemonSet

如果修改了Node LabelDaemonSet将立刻向新匹配上的Node添加Pod,同时删除新近无法匹配上的Node上的Pod

可以修改DaemonSet创建的Pod。然而,不允许对Pod的所有字段进行更新。当下次Node(即使具有相同的名称)被创建时,DaemonSet Controller还会使用最初的模板。

可以删除一个DaemonSet。如果使用 kubectl 并指定 --cascade=false 选项,则Pod将被保留在Node上。然后可以创建具有不同模板的新DaemonSet。具有不同模板的新DaemonSet将鞥能够通过Label匹配识别所有已经存在的Pod。它不会修改或删除它们,即使是错误匹配了Pod模板。通过删除Pod或者 删除Node,可以强制创建新的Pod

Kubernetes 1.6或以后版本,可以在DaemonSet执行滚动升级

init脚本

很可能通过直接在一个Node上启动daemon进程(例如,使用 initupstartd、或 systemd。这非常好,然而基于DaemonSet来运行这些进程有如下一些好处:

  • 像对待应用程序一样,具备为daemon提供监控和管理日志的能力。
  • daemon和应用程序使用相同的配置语言和工具(如Pod模板kubectl
  • Kubernetes未来版本可能会支持对DaemonSet创建PodNode升级工作流进行集成。
  • 在资源受限的容器中运行daemon,能够增加daemon和应用容器的隔离性。然而这也实现了在容器中运行daemon,但却不能在Pod中运行(例如,直接基于Docker启动

Pod

可能要直接创建Pod,同时指定其运行在特定的Node上。 然而,DaemonSet替换了由于任何原因被删除或终止的Pod,例如Node失败、例行节点维护,比如内核升级。由于这个原因,我们应该使用DaemonSet而不是单独创建Pod

静态Pod

很可能,通过在一个指定目录下编写文件来创建Pod,该目录受Kubelet所监视。这些Pod被称为 静态Pod。 不像DaemonSet,静态Pod不受kubectl和 其它Kubernetes API客户端管理。静态Pod不依赖于apiserver,这使得它们在集群启动的情况下非常有用。 而且,未来静态Pod可能会被废弃掉。

Replication Controller

DaemonSetReplication Controller 非常类似,它们都能创建Pod,这些Pod都具有不期望被终止的进程(例如,Web服务器、存储服务器。 为无状态的Service使用Replication Controller,像frontend,实现对副本的数量进行扩缩容、平滑升级,比之于精确控制Pod运行在某个主机上要重要得多。需要Pod副本总是运行在全部或特定主机上,并需要先于其他Pod启动,当这被认为非常重要时,应该使用Daemon Controller

上一页
下一页