31-DaemonSet

concepts/workloads/controllers/daemonset/

DaemonSet

A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. As nodes are added to the cluster, Pods are added to them. As nodes are removed from the cluster, those Pods are garbage collected. Deleting a DaemonSet will clean up the Pods it created. 守护程序确保所有(或某些)节点运行pod的副本。当节点被添加到集群中时,pod被添加到它们中。当节点从集群中移除时,这些pod将被垃圾收集。删除守护程序将清除它创建的pod。

Some typical uses of a DaemonSet are:

In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon. A more complex setup might use multiple DaemonSets for a single type of daemon, but with different flags and/or different memory and cpu requests for different hardware types. 在一个简单的例子中,每种类型的守护进程都将使用一个覆盖所有节点的守护进程集。一个更复杂的安装程序可能对一种守护程序类型使用多个守护程序,但对于不同的硬件类型使用不同的标志和/或不同的内存和CPU请求。

Writing a DaemonSet Spec

Create a DaemonSet

You can describe a DaemonSet in a YAML file. For example, the daemonset.yaml file below describes a DaemonSet that runs the fluentd-elasticsearch Docker image: 可以在yaml文件中描述守护进程。例如,下面的daemonset.yaml文件描述了运行fluentd elasticsearch docker映像的守护程序:

controllers/daemonset.yaml Copy controllers/daemonset.yaml to clipboard

apiVersion: apps/v1
kind: 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: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        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:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
  • Create a DaemonSet based on the YAML file:

    kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml

Required Fields

As with all other Kubernetes config, a DaemonSet needs apiVersion, kind, and metadata fields. For general information about working with config files, see deploying applications, configuring containers, and object management using kubectl documents. 与所有其他kubernetes配置一样,守护进程需要apiversionkindmetadata字段。有关使用配置文件的一般信息,请参阅[部署应用程序](https://kubernetes.io/docs/user guide/deploying applications/)、配置容器使用kubectl进行对象管理文档。

A DaemonSet also needs a .spec section.

Pod Template

The .spec.template is one of the required fields in .spec. 必须字段

The .spec.template is a pod template. It has exactly the same schema as a Pod, except it is nested and does not have an apiVersion or kind.

In addition to required fields for a Pod, a Pod template in a DaemonSet has to specify appropriate labels (see pod selector). 除了pod所需的字段外,守护程序中的pod模板还必须指定适当的标签

A Pod Template in a DaemonSet must have a RestartPolicy equal to Always, or be unspecified, which defaults to Always. 守护程序集中的pod模板必须具有等于always的restartpolicy,或者未指定,默认为always。

Pod Selector

The .spec.selector field is a pod selector. It works the same as the .spec.selector of a Job. .spec.selector字段是一个pod选择器。它的工作原理与作业的.spec.selector相同。

As of Kubernetes 1.8, you must specify a pod selector that matches the labels of the .spec.template. The pod selector will no longer be defaulted when left empty. Selector defaulting was not compatible with kubectl apply. Also, once a DaemonSet is created, its .spec.selector can not be mutated. Mutating the pod selector can lead to the unintentional orphaning of Pods, and it was found to be confusing to users. 从Kubernetes 1.8开始,必须指定与.spec.template的标签匹配的pod选择器。空舱选择器将不再默认。选择器默认值与kubectl apply不兼容。另外,一旦创建了守护程序集,就不能对其.spec.selector进行修改。改变pod选择器可能会导致无意中孤立pod,用户会感到困惑。

The .spec.selector is an object consisting of two fields .spec.selector是由两个字段组成的对象:

  • matchLabels - works the same as the .spec.selector of a ReplicationController. MatchLabels-工作方式与复制控制器的.spec.selector相同。
  • matchExpressions - allows to build more sophisticated selectors by specifying key, list of values and an operator that relates the key and values. 允许通过指定键、值列表和与键和值相关的运算符来生成更复杂的选择器。

When the two are specified the result is ANDed. 当这两个被指定时,结果是anded。

If the .spec.selector is specified, it must match the .spec.template.metadata.labels. Config with these not matching will be rejected by the API. 如果指定了.spec.selector,则它必须与.spec.template.metadata.labels匹配。这些不匹配的配置将被api拒绝。

Also you should not normally create any Pods whose labels match this selector, either directly, via another DaemonSet, or via another workload resource such as ReplicaSet. Otherwise, the DaemonSet Controller will think that those Pods were created by it. Kubernetes will not stop you from doing this. One case where you might want to do this is manually create a Pod with a different value on a node for testing. 另外,您通常不应该直接通过另一个守护进程或通过另一个工作负载资源(如replicaset)创建标签与此选择器匹配的任何pod。否则,守护进程控制器会认为这些pod是由它创建的。库伯内特斯不会阻止你这么做的。您可能希望这样做的一种情况是在节点上手动创建一个具有不同值的pod以进行测试。

Running Pods on Only Some Nodes

If you specify a .spec.template.spec.nodeSelector, then the DaemonSet controller will create Pods on nodes which match that node selector. Likewise if you specify a .spec.template.spec.affinity, then DaemonSet controller will create Pods on nodes which match that node affinity. If you do not specify either, then the DaemonSet controller will create Pods on all nodes. 如果指定.spec.template.spec.node selector,那么守护程序控制器将在与该节点选择器匹配的节点上创建pod。同样,如果指定了.spec.template.spec.affinity,那么守护程序控制器将在与该节点affinity匹配的节点上创建pod。如果未指定任何一个,那么守护程序控制器将在所有节点上创建pod。

How Daemon Pods are Scheduled

Scheduled by DaemonSet controller (disabled by default since 1.12)

Normally, the machine that a Pod runs on is selected by the Kubernetes scheduler. However, Pods created by the DaemonSet controller have the machine already selected (.spec.nodeName is specified when the Pod is created, so it is ignored by the scheduler). Therefore: 通常,pod运行的机器由kubernetes调度程序选择。但是,由守护程序集控制器创建的pod已经选择了计算机(.spec.nodename是在创建pod时指定的,因此调度程序将忽略它)。因此:

  • The unschedulable field of a node is not respected by the DaemonSet controller. 守护程序控制器不尊重节点的不可调度字段。
  • The DaemonSet controller can make Pods even when the scheduler has not been started, which can help cluster bootstrap. 守护程序控制器甚至可以在调度程序尚未启动时生成pod,这有助于集群引导。

Scheduled by default scheduler (enabled by default since 1.12)

FEATURE STATE: Kubernetes v1.16 beta

A DaemonSet ensures that all eligible nodes run a copy of a Pod. Normally, the node that a Pod runs on is selected by the Kubernetes scheduler. However, DaemonSet pods are created and scheduled by the DaemonSet controller instead. That introduces the following issues: 守护程序确保所有符合条件的节点都运行pod的副本。通常,pod运行的节点由kubernetes调度程序选择。但是,守护程序pod是由守护程序控制器创建和调度的。这带来了以下问题:

  • Inconsistent Pod behavior: Normal Pods waiting to be scheduled are created and in Pending state, but DaemonSet pods are not created in Pending state. This is confusing to the user. pod行为不一致:正常的等待调度的pod是在“pending”状态下创建的,但是守护程序pod不是在“pending”状态下创建的。这让用户感到困惑。
  • Pod preemption is handled by default scheduler. When preemption is enabled, the DaemonSet controller will make scheduling decisions without considering pod priority and preemption. POD抢占由默认调度程序处理。当启用抢占时,守护进程控制器将在不考虑pod优先级和抢占的情况下做出调度决策。

ScheduleDaemonSetPods allows you to schedule DaemonSets using the default scheduler instead of the DaemonSet controller, by adding the NodeAffinity term to the DaemonSet pods, instead of the .spec.nodeName term. The default scheduler is then used to bind the pod to the target host. If node affinity of the DaemonSet pod already exists, it is replaced. The DaemonSet controller only performs these operations when creating or modifying DaemonSet pods, and no changes are made to the spec.template of the DaemonSet. schedule daemonset pods允许您使用默认调度程序而不是守护程序控制器调度守护程序,方法是将'nodeaffinity'项添加到守护程序pods,而不是'spec.nodename'项。然后使用默认调度程序将pod绑定到目标主机。如果DAEMAGE POD的节点亲和性已经存在,则替换它。守护程序控制器仅在创建或修改守护程序pod时执行这些操作,并且不会更改守护程序的“spec.template”。

nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchFields:
      - key: metadata.name
        operator: In
        values:
        - target-host-name

In addition, node.kubernetes.io/unschedulable:NoSchedule toleration is added automatically to DaemonSet Pods. The default scheduler ignores unschedulable Nodes when scheduling DaemonSet Pods. 此外,node.kubernetes.io/unschedulable:noschedule容忍被自动添加到守护程序pods。默认调度程序在调度守护程序集播客时忽略不可调度的节点。

Taints and Tolerations

Although Daemon Pods respect taints and tolerations, the following tolerations are added to DaemonSet Pods automatically according to the related features. 尽管守护程序pod尊重污染和容忍,但以下容忍将根据相关功能自动添加到守护程序pod中。

Toleration Key Effect Version Description
node.kubernetes.io/not-ready NoExecute 1.13+ DaemonSet pods will not be evicted when there are node problems such as a network partition.
node.kubernetes.io/unreachable NoExecute 1.13+ DaemonSet pods will not be evicted when there are node problems such as a network partition.
node.kubernetes.io/disk-pressure NoSchedule 1.8+
node.kubernetes.io/memory-pressure NoSchedule 1.8+
node.kubernetes.io/unschedulable NoSchedule 1.12+ DaemonSet pods tolerate unschedulable attributes by default scheduler.
node.kubernetes.io/network-unavailable NoSchedule 1.12+ DaemonSet pods, who uses host network, tolerate network-unavailable attributes by default scheduler.

Communicating with Daemon Pods

Some possible patterns for communicating with Pods in a DaemonSet are: 与守护进程中的pod通信的一些可能模式是:

  • Push: Pods in the DaemonSet are configured to send updates to another service, such as a stats database. They do not have clients. 守护进程中的pod被配置为向另一个服务(如stats数据库)发送更新。他们没有客户。
  • NodeIP and Known Port: Pods in the DaemonSet can use a hostPort, so that the pods are reachable via the node IPs. Clients know the list of node IPs somehow, and know the port by convention. 守护进程中的pod可以使用hostport,以便可以通过节点ip访问pod。客户端以某种方式知道节点IP的列表,并按约定知道端口。
  • DNS: Create a headless service with the same pod selector, and then discover DaemonSets using the endpoints resource or retrieve multiple A records from DNS. 使用相同的pod选择器创建一个headless服务,然后使用endpoints资源发现守护进程或从dns检索多个a记录。
  • Service: Create a service with the same Pod selector, and use the service to reach a daemon on a random node. (No way to reach specific node.) 使用相同的pod选择器创建一个服务,并使用该服务访问随机节点上的守护进程。(无法到达特定节点。)

Updating a DaemonSet

If node labels are changed, the DaemonSet will promptly add Pods to newly matching nodes and delete Pods from newly not-matching nodes. 如果更改了节点标签,守护进程将立即向新匹配的节点添加pod,并从新不匹配的节点删除pod。

You can modify the Pods that a DaemonSet creates. However, Pods do not allow all fields to be updated. Also, the DaemonSet controller will use the original template the next time a node (even with the same name) is created. 您可以修改守护程序创建的pod。但是,pods不允许更新所有字段。此外,守护程序控制器将在下次创建节点(即使名称相同)时使用原始模板。

You can delete a DaemonSet. If you specify --cascade=false with kubectl, then the Pods will be left on the nodes. If you subsequently create a new DaemonSet with the same selector, the new DaemonSet adopts the existing Pods. If any Pods need replacing the DaemonSet replaces them according to its updateStrategy. 您可以删除守护程序集。如果使用kubectl指定--cascade=false,那么pods将留在节点上。如果随后用同一选择器创建新的起始点,则新的起始点采用现有的POD。如果任何pod需要替换守护进程,则根据其updatestrategy替换它们。

You can perform a rolling update on a DaemonSet. 可以对守护进程执行滚动更新。

Alternatives to DaemonSet

Init Scripts

It is certainly possible to run daemon processes by directly starting them on a node (e.g. using init, upstartd, or systemd). This is perfectly fine. However, there are several advantages to running such processes via a DaemonSet: 当然可以通过直接在节点上启动守护进程来运行它们(例如,使用init、upstartd或systemd)。这很好。但是,通过守护程序运行这样的进程有几个优点:

  • Ability to monitor and manage logs for daemons in the same way as applications. 能够以与应用程序相同的方式监视和管理守护进程的日志。
  • Same config language and tools (e.g. Pod templates, kubectl) for daemons and applications. 守护进程和应用程序的相同配置语言和工具(例如pod模板、kubectl)。
  • Running daemons in containers with resource limits increases isolation between daemons from app containers. However, this can also be accomplished by running the daemons in a container but not in a Pod (e.g. start directly via Docker). 在具有资源限制的容器中运行守护程序会增加守护程序与应用程序容器之间的隔离。但是,这也可以通过在容器中而不是在pod中运行守护进程来实现(例如,直接通过docker启动)。

Bare Pods

It is possible to create Pods directly which specify a particular node to run on. However, a DaemonSet replaces Pods that are deleted or terminated for any reason, such as in the case of node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, you should use a DaemonSet rather than creating individual Pods. 可以直接创建指定要在其上运行的特定节点的pod。但是,守护程序会替换因任何原因(如在节点故障或中断性节点维护(如内核升级)而被删除或终止的pod。因此,应该使用守护进程,而不是创建单独的pod。

Static Pods

It is possible to create Pods by writing a file to a certain directory watched by Kubelet. These are called static pods. Unlike DaemonSet, static Pods cannot be managed with kubectl or other Kubernetes API clients. Static Pods do not depend on the apiserver, making them useful in cluster bootstrapping cases. Also, static Pods may be deprecated in the future. 可以通过将文件写入kubelet监视的特定目录来创建pods。这些被称为静态吊舱。与守护进程不同,静态pod不能由kubectl或其他kubernetes api客户端管理。静态pod不依赖于apiserver,这使得它们在集群引导情况下非常有用。另外,静态pod在将来可能会被弃用。

Deployments

DaemonSets are similar to Deployments in that they both create Pods, and those Pods have processes which are not expected to terminate (e.g. web servers, storage servers). 守护程序与部署类似,因为它们都创建pod,并且这些pod具有预期不会终止的进程(例如web服务器、存储服务器)。

Use a Deployment for stateless services, like frontends, where scaling up and down the number of replicas and rolling out updates are more important than controlling exactly which host the Pod runs on. Use a DaemonSet when it is important that a copy of a Pod always run on all or certain hosts, and when it needs to start before other Pods. 对无状态服务(如前端)使用部署,在这种情况下,增加和减少副本数量以及推出更新比准确控制pod运行在哪个主机上更为重要。当pod的副本始终在所有或特定主机上运行,并且需要在其他pod之前启动时,请使用守护程序集。

Feedback

Was this page helpful?

k8s
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!