zoukankan      html  css  js  c++  java
  • Kuebernetes之DaemonSet

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

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

    • 运行集群存储守护进程,如glusterd、ceph。
    • 运行集群日志收集守护进程,如fluentd、logstash。
    • 运行节点监控守护进程,如Prometheus Node Exporter, collectd, Datadog agent, New Relic agent, or Ganglia gmond。

    创建DaemonSet

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

    1.  
      apiVersion: apps/v1
    2.  
      kind: DaemonSet
    3.  
      metadata:
    4.  
      name: fluentd-elasticsearch
    5.  
      namespace: kube-system
    6.  
      labels:
    7.  
      k8s-app: fluentd-logging
    8.  
      spec:
    9.  
      selector:
    10.  
      matchLabels:
    11.  
      name: fluentd-elasticsearch
    12.  
      template:
    13.  
      metadata:
    14.  
      labels:
    15.  
      name: fluentd-elasticsearch
    16.  
      spec:
    17.  
      tolerations:
    18.  
      - key: node-role.kubernetes.io/master
    19.  
      effect: NoSchedule
    20.  
      containers:
    21.  
      - name: fluentd-elasticsearch
    22.  
      image: k8s.gcr.io/fluentd-elasticsearch:1.20
    23.  
      resources:
    24.  
      limits:
    25.  
      memory: 200Mi
    26.  
      requests:
    27.  
      cpu: 100m
    28.  
      memory: 200Mi
    29.  
      volumeMounts:
    30.  
      - name: varlog
    31.  
      mountPath: /var/log
    32.  
      - name: varlibdockercontainers
    33.  
      mountPath: /var/lib/docker/containers
    34.  
      readOnly: true
    35.  
      terminationGracePeriodSeconds: 30
    36.  
      volumes:
    37.  
      - name: varlog
    38.  
      hostPath:
    39.  
      path: /var/log
    40.  
      - name: varlibdockercontainers
    41.  
      hostPath:
    42.  
      path: /var/lib/docker/containers

    以上DaemonSet中没有restart policy字段,默认为Always。如果有的话,必需将值设置成Always,否则在创建时出出现不可用错误。

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

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

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

    如果预期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的调度特性,它带来两个问题:

    1. pod行为不一致。普通pod被创建以后等待调度的阶段称为pending,因为DaemonSet中的pod无需调度,因而无此状态,用户会因此产生迷惑。
    2. pod优先级特性由kubernetes scheduler实现,DaemonSet无此特性。当系统打开pod优先级功能时,pod优先级特性会被DaemonSet中的pod忽略。

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

    1.  
      nodeAffinity:
    2.  
      requiredDuringSchedulingIgnoredDuringExecution:
    3.  
      nodeSelectorTerms:
    4.  
      - matchFields:
    5.  
      - key: metadata.name
    6.  
      operator: In
    7.  
      values:
    8.  
      - 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 KeyEffectAlpha FeaturesVersionDescription
    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 ScheduleDaemonSetPodsTaintNodesByCondition 1.11+ When ScheduleDaemonSetPodsis enabled, TaintNodesByConditionis necessary to make sure DaemonSet pods tolerate unschedulable attributes by default scheduler.
    node.kubernetes.io/network-unavailable NoSchedule ScheduleDaemonSetPodsTaintNodesByCondition, 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提供统一入口与负载均衡。
  • 相关阅读:
    广度遍历有向图
    坚持的力量 第二十一篇
    坚持的力量 第二十二篇
    搜索引擎首页
    安装ubuntu
    最小生成树之Kruskal算法
    最小生成树之PRIM算法
    文件同步软件
    [恢]hdu 2151
    [恢]hdu 1396
  • 原文地址:https://www.cnblogs.com/ExMan/p/13721042.html
Copyright © 2011-2022 走看看