Kuebernetes之DaemonSet

系列目录html

DaemonSet确保集群中每一个(部分)node运行一份pod副本,当node加入集群时建立pod,当node离开集群时回收pod。若是删除DaemonSet,其建立的全部pod也被删除,DaemonSet中的pod覆盖整个集群。node

当须要在集群内每一个node运行同一个pod,使用DaemonSet是有价值的,如下是典型使用场景:docker

  • 运行集群存储守护进程,如glusterd、ceph。数据库

  • 运行集群日志收集守护进程,如fluentd、logstash。api

  • 运行节点监控守护进程,如Prometheus Node Exporter, collectd, Datadog agent, New Relic agent, or Ganglia gmond。网络

建立DaemonSet

如下是DaemonSet的示例spec文件,运行fluentd-elasticsearch image:app

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: k8s.gcr.io/fluentd-elasticsearch:1.20
        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

以上DaemonSet中没有restart policy字段,默认为Always。若是有的话,必需将值设置成Always,不然在建立时出出现不可用错误。负载均衡

DaemonSet一样会受到Taint的抵制,若是不在配置中加入匹配的Toleration,那么DaemonSet不会在拥有Taint属性的node上部署pod。上例中有以下内容:elasticsearch

tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule

缘由就是系统默认为master节点增长了 “node-role.kubernetes.io/master”的Taint,以抵制普通pod部署,使master成为专用节点。由于咱们预期上例DaemonSet在集群内全局部署,所以须要加入相匹配的Toleration。ui

若是预期DaemonSet只在特定节点上运行,能够在上述配置文件中加入.spec.template.spec.nodeSelector字段。.
spec.template.spec.nodeSelector字段内加入节点选择器(node selector)或者亲和选择器(node affinity),则DaemonSet只会在知足条件的node上部署pod。总之,能够经过Taint、Toleration、Affinity、node label控制DaemonSet部署pod的节点范围。

将以上内容保存在daemonset.yaml文件中,执行以下命令建立DaemonSet:

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

系统如何调度DaemonSet pod?

默认状况下DaemonSet在建立pod时,为其增长spec.nodeName字段,也就是说所建立的pod运行在那个节上在建立阶段就已经肯定,因此DaemonSet中的pod实际上没有接受kubernetes scheduler的调度,它不须要调度,所以产生如下两个特性:

  • DaemonSet中的pod不听从节点的unreachable条件,也就是即便节点被系统断定为不可达,DaemonSet仍然试图在其上部署pod。

  • 在集群引导阶段,即便kubernetes scheduler尚未部署生效,DaemonSet仍然能够将pod部署到集群中的任何节点,此特性主要是在集群引导阶段使用。

由于DaemonSet不一样于常规pod的调度特性,它带来两个问题:

  • pod行为不一致。普通pod被建立之后等待调度的阶段称为pending,由于DaemonSet中的pod无需调度,于是无此状态,用户会所以产生迷惑。

  • pod优先级特性由kubernetes scheduler实现,DaemonSet无此特性。当系统打开pod优先级功能时,pod优先级特性会被DaemonSet中的pod忽略。

为了解决以上两个问题,kubernetes增长了经过设置容许DaemonSet使用kurbernetes scheduler的功能,并在1.11的 alpha版本中成为稳定特性。其实现机制是DaemonSet在建立pod时,再也不自动添加.spec.nodeName,而是以nodeAffinity取而代之,示例以下:

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

其中"target-host-name"就是原来.spec.nodeName的值,这样pod就会被kubernetes scheduler调度。经过以上操做解决了上述两个问题。但DaemonSet的调度有本身因有的特性,在上文中提到的“不受节点unreachable条件限制”,为了使DaemonSet在使用kubernetes scheduler时仍然保持此特性须要打开集群的"TaintNodesByCondition"特性,若是DaemonSet使用主机网络那么必需在DaemonSet中添加以下的Toleration:

node.kubernetes.io/network-unavailable:NoSchedule

DaemonSet自动添加的Toleration

系统在某此条件下会自动为节点添加Taint,好比硬盘不足、网络不可达等,以阻止新pod往不知足条件的节点上调度。但DaemonSet的目的是在所有有资格的node上部署,不但愿被这种Taint打断,因经系统也默认为DaemonSet上的pod添加Toleration。以下表:

Toleration Key Effect Alpha Features Version Description
node.kubernetes.io/not-ready NoExecute TaintBasedEvictions 1.8+ when TaintBasedEvictions is enabled,they will not be evicted when there are node problems such as a network partition.
node.kubernetes.io/unreachable NoExecute TaintBasedEvictions 1.8+ when TaintBasedEvictions is enabled,they will not be evicted when there are node problems such as a network partition.
node.kubernetes.io/disk-pressure NoSchedule TaintNodesByCondition 1.8+
node.kubernetes.io/memory-pressure NoSchedule TaintNodesByCondition 1.8+
node.kubernetes.io/unschedulable NoSchedule ScheduleDaemonSetPods, TaintNodesByCondition 1.11+ When ScheduleDaemonSetPodsis enabled, TaintNodesByConditionis necessary to make sure DaemonSet pods tolerate unschedulable attributes by default scheduler.
node.kubernetes.io/network-unavailable NoSchedule ScheduleDaemonSetPods, TaintNodesByCondition, hostnework 1.11+ When ScheduleDaemonSetPodsis enabled, TaintNodesByConditionis necessary to make sure DaemonSet pods, who uses host network, tolerate network-unavailable attributes by default scheduler.
node.kubernetes.io/out-of-disk NoSchedule ExperimentalCriticalPodAnnotation(critical pod only), TaintNodesByCondition 1.8+

与DaemonSet中pod通讯的几种模式

  • Push:收集数据并向其它服务发送,如将收集到的统计信息发送给统计类型数据库。

  • NodeIP and Known Port:DaemonSet中的pod能够被设置使用主机网络的一个port,而客户端能够很方便的知道节点IP列表,所以能够经过节点IP地址与port访问DaemonSet pod。

  • DNS:建立无头服务而且让它的选择器匹配全部DaemonSet的pod,这样DaemonSet中的pod就会成为无头服务的endpoints。相似于StatefulSet。

  • Service:让Service选中DaemonSet,为访问DaemonSet中的pod提供统一入口与负载均衡。

相关文章
相关标签/搜索