zoukankan      html  css  js  c++  java
  • Taint & toleration

    pod调度

    简介:

    Scheduler 是 Kubernetes 的调度器,主要任务是把定义的Pod分配到集群的节点上,听起来非常简单,但要考虑需要方面的问题:

    • 公平:如何保证每个节点都能被分配到资源
    • 资源高效利用:集群所有资源最大化被使用
    • 效率:调度性能要好,能够尽快的对大批量的Pod完成调度工作
    • 灵活:允许用户根据自己的需求控制调度的流程

    Scheduler 是作为单独的服务运行的,启动之后会一直监听API Server,获取 podSpec.NodeName为空的Pod,对每个Pod都会创建一个buiding,表明该Pod应该放在哪个节点上

    调度过程:

    调度流程:首先过滤掉不满足条件的节点,这个过程称为predicate;然后对通过的节点按照优先级的顺序,这个是priority;最后从中选择优先级最高的节点。如果中间有任何一步报错,则直接返回错误信息。

    Predicate调度算法:

    • PodFitsResources:节点上剩余的资源是否大于 Pod 请求的资源
    • PodFitsHost:如果Pod指定了nodeName,检查节点名称是否和nodeName匹配
    • PodFitsHostPort:节点上已经使用的port是否和Pod申请的port冲突
    • PodSelectorMatches:过滤和Pod指定的 label 不匹配的节点
    • NoDiskConflict:已经 mount 的 volume 和 Pod 指定的volume不冲突,除非他们都是只读

    如果在predicate过程中没有适合的节点,Pod会一直处于Pending状态,不断重新调度,直到有节点满足条件,经过这个步骤,如果多个节点满足条件,就会进入priority过程:按照优先级大小对节点排序,优先级由一系列键值对组成,键是该优先级的名称,值是它的权重,这些优先级选项包括:

    • LeastRequestedPriority:通过计算CPU和Memory的使用率来决定权重,使用率越低权重越高,换句话说,这个优先级倾向于资源使用率低的节点
    • BalanceResourceAllocation:节点上CPU和Memory使用率非常及接近,权重就越高,这个要和上边的一起使用,不可单独使用
    • ImageLocalityPriority:倾向于已经要使用镜像的节点,镜像的总大小值越大,权重越高

    通过算法对所有的优先级项目和权重进行计算,得出最终的结果

    Kubernetes的调度方法整体共有以下几种:

    • 亲和性:包括Node的亲和性和Pod的亲和性
    • 污点(Taint)和容忍(Toleration)
    • 固定调度策略

    亲和性

    节点亲和性

    pod.spec.affinity.nodeAffinity

    • preferredDuringSchedulingIgnoredDuringExecution:软策略

      • 软策略是偏向于,更想(不)落在某个节点上,但如果实在没有,落在其他节点也可以
    • requiredDuringSchedulingIgnoredDuringExecution:硬策略

      • 硬策略是必须(不)落在指定的节点上,如果不符合条件,则一直处于Pending状态

    演示:

    requiredDuringSchedulingIgnoredDuringExecution硬策略
    # 以下策略表示:此Pod不要落在node名称为testcentos7的节点上,下边开始创建
    
    # vim node-affinity-required.yaml
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: affinity-required
      labels:
       app: node-affinity-pod
    spec:
      containers:
      - name: with-node-required
        image: nginx:1.2.1
        imagePullPolicy: IfNotPresent
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname    #节点名称
                operator: NotIn  #不是
                values:
                - testcentos7   #node节点
     
     # 如修改为in,则表示创建落在指定节点中
     affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname    #节点名称
                operator: In  #是,存在
                values:
                - testcentos7   #node节点
    
    preferredDuringSchedulingIgnoredDuringExecution软策略
    #### 以下策略表示:此Pod更想落在node节点名称为testcentos7的node中,开始创建
    apiVersion: v1
    kind: Pod
    metadata:
      name: affinity-preferred
      labels:
        app: node-affinity-pod
    spec:
      containers:
      - name: with-node-preferred
        image: nginx:1.2.1
        imagePullPolicy: IfNotPresent
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100    #权重为100,软策略中权重越高匹配到的机会越大
            preference:  #更偏向于
              matchExpressions:
              - key: kubernetes.io/hostname #node名称
                operator: In  #等于,为
                values:
                - testcentos7   #node真实名称
                
    ##### 更改一下策略,将node节点名称随便更改为不存在的node名称,例如kube-node2,以下策略表示:此Pod更想落在node名称为kube-node2的节点上,开始创建        
    affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1    #权重为1,软策略中权重越高匹配到的机会越大
            preference:  #更偏向于
              matchExpressions:
              - key: kubernetes.io/hostname #node名称
                operator: In  #等于,为
                values:
                - kube-node2   #node真实名称
    
    软硬策略结合
    # 软硬结合达到一个更为准确的node选择,以下文件意思为此Pod必须不存在k8s-node2节点中,其他的节点都可以,但最好落在label中source的值为hello的节点中
    apiVersion: v1
    kind: Pod
    metadata:
      name: affinity-node
      labels:
        app: node-affinity-pod
    spec:
      containers:
      - name: with-affinity-node
        image: nginx:v1
        imagePullPulicy: IfNotPresent
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname
                operator: NotIn
                values:
                - k8s-node2
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1 
            preference:
            matchExpressions:
            - key: source
              operator: In
              values:
               - hello
    
    键值运算关系

    如果nodeSelectorTerms下面有多个选项,满足任何一个条件就可以了;如果matchExpressions有多个选项,则必须满足这些条件才能正常调度

    • In:label 的值在某个列表里
    • NotIn:label 的值不在某个列表中
    • Gt:label 的值大于某个值
    • Lt:label 的值小于某个值
    • Exists:某个 label 存在
    • DoesNotExist:某个 label 不存在

    pod亲和性

    硬策略: podAffinity
    # 以下文件策略为:此Pod必须要和包含label为app:nginx的pod在同一node下
    apiVersion: v1
    kind: Pod
    metadata:
      name: affinity-required
      labels:
        app: pod-3
    spec:
      containers:
      - name: with-pod-required
        image: nginx:1.2.1
        imagePullPolicy: IfNotPresent
      affinity:
        podAffinity:   #在同一域下
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app    #标签key
                operator: In
                values:
                - nginx     #标签value
            topologyKey: kubernetes.io/hostname #域的标准为node节点的名称
    
    硬策略:podAnitAffinity
    # 将podAffinity改为podAnitAffinity,使它们不在用于node节点下,此策略表示,必须要和label为app:nginx的pod在不用的node节点上
    apiVersion: v1
    kind: Pod
    metadata:
      name: required-pod2
      labels:
        app: pod-3
    spec:
      containers:
      - name: with-pod-required
        image: nginx:1.2.1
        imagePullPolicy: IfNotPresent
      affinity:
        podAntiAffinity:   
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app    #标签key
                operator: In
                values:
                - nginx     #标签value
            topologyKey: kubernetes.io/hostname #域的标准为node节点的名称
    
    软策略:
    # 软策略和硬策略的方法基本类似,只是添加了权重,表示更喜欢而已,也可以接受其他,在此就不再演示
    apiVersion: v1
    kind: Pod
    metadata:
      name: affinity-prefered
      labels:
        app: pod-3
    spec:
      containers:
      - name: with-pod-prefered
        image: nginx:v1
        imagePullPolicy: IfNotPresent
      affinity:
        podAntiAffinity:    #不在同一个域下
          preferedDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - pod-2
              topologyKey: kubernetes.io/hostname
    
    亲和性/反亲和性调度策略比较如下:
    调度策略 匹配标签 操作符 拓扑域支持 调度目标
    nodeAffinity 主机 In,NotIn,Exists,DoesNotExists,Gt,Lt 指定主机
    podAffinity Pod In,NotIn,Exists,DoesNotExists,Gt,Lt pod与指定pod在一拓扑域
    podAnitAffinity Pod In,NotIn,Exists,DoesNotExists,Gt,Lt pod与指定pod不在一拓扑域

    Taint&Toleration

    Taint(污点)和 Toleration(容忍)可以作用于 node 和 pod 上,其目的是优化 pod 在集群间的调度,这跟节点亲和性类似,只不过它们作用的方式相反,具有 taint 的 node 和 pod 是互斥关系,而具有节点亲和性关系的 node 和 pod 是相吸的。另外还有可以给 node 节点设置 label,通过给 pod 设置 nodeSelector 将 pod 调度到具有匹配标签的节点上。

    Taint 和 toleration 相互配合,可以用来避免 pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taint 的 pod,是不会被该节点接受的。如果将 toleration 应用于 pod 上,则表示这些 pod 可以(但不要求)被调度到具有相应 taint 的节点上。

    设置与删除Taint

    Taints包含一个key、value和effect。

    格式

    <key>=<value>:<effect>Copy to clipboardErrorCopied
    

    为Node设置taint

    [root@kubernetes-master-01 ~]# kubectl taint node kubernetes-master-01 key=value:NoSchedule
    node/kubernetes-master-01 taintedCopy to clipboardErrorCopied
    

    执行这个命令后,除非Pod具有相应的toleration,否则不会被调度到kubernetes-master-01上。

    删除taint

    [root@kubernetes-master-01 ~]# kubectl taint node kubernetes-master-01 key:NoSchedule-
    node/kubernetes-master-01 untaintedCopy to clipboardErrorCopied
    

    taint支持的effect

    • NoSchedule:表示不能容忍taint的Pod不会被调度到这个节点,属于刚性的限制
    • PreferNoSchedule:如果集群中没有其他更合适的Node,则会调度到这个节点
    • NoExcute 上两条只是影响调度,这条还会对正在运行的Pod产生影响,如果在节点上增加一条 taint,那么如果已经运行的Pod没有设置对应的toleration,则会被立即驱逐

    在Pod中指定Toleartions

    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: mytaint
    spec:
      selector:
        matchLabels:
          app: mytaint
      template:
        metadata:
          labels:
            app: mytaint
        spec:
          containers:
            - name: nginx
              image: nginx
          tolerations:
            - key: "key"
              operator: "Equal"
              value: "value"
              effect: "NoSchedule"Copy to clipboardErrorCopied
    

    当key为空operator为Exists,这种情况将匹配所有的keys、values和effects,即对所有的瑕疵都无法忍受;当effect为空,匹配所有key的瑕疵。

    可以向单个Pod和Node增加多个tolerations和taints,Kubernetes采用类似过滤器的方式进行处理,首先遍历Node上的Taints,并与Pod的tolerations做匹配,如果有匹配的项目则忽略,最后根据剩下为匹配到的taints做判断:

    • 如果至少有一个未匹配到的taints的效果是NoSchedule,则Pod不会被调度到Node上
    • 如果仅有一个未匹配到的taints的效果是PreferNoSchedule,则尽量不向这个Node调度
    • 如果至少有一个未匹配到的taints的效果是NoExecute,则Pod不会被调度到Node上,已经在Node上运行的Pod会被驱逐。通常,一个NoExcute添加到节点后,不能容忍的Pod会被立即驱逐,可以通过tolerationSeconds设置延时驱逐。
  • 相关阅读:
    解决web服务器乱码问题
    Reporting services 打印
    moss用户管理
    乱弹超级女声。。。。。。。。。。。。
    微软项目管理[EPM]数据库应用举例1: 找到所有正在进行的项目
    ajax中另一种装载数据页面的方法
    微软项目管理[EPM]数据库剖析4:项目大纲代码的四张表
    微软项目管理[EPM]数据库应用举例2: 取得一个项目的某大纲代码的值
    支持多表头、滚动条可排序的DataGrid控件[Free]
    微软项目管理[EPM]数据库剖析3:如何取得某个项目的某个大纲代码的值
  • 原文地址:https://www.cnblogs.com/tcy1/p/13832503.html
Copyright © 2011-2022 走看看