kubernetes Pod 资源调度

1 概述

1 总述

API server 接受客户端提交的POD对象创建请求操作过程中,需要kube-scheduler 从当前集群中选择一个可用的最佳节点接受并运行,通常是默认调度器复制此类任务,对于每个待创建的POD来说,需要经过三个步骤。
1 预选(predicate)
节点预选: 基于一系列预选规则(podfitsresources 和 matchnode-selector等)对每个节点进行检查,将那些不符合条件的节点过滤。
如果需要某些特殊服务,则需要通过组合节点标签,以及POD标签或标签选择器等来激活特定的预选策略以完成高级调度
2 优选 (priority)
3 选定 (select)
选定: 从优先级排序结果中挑出优先级最高的节点运行POD对象,当此类节点多于一个时,则从中随机选择一个。


K8S 内建了适合绝大多数场景的POD资源调度需求的默认调度器,支持同时使用算法基于原生及可定制的工具来选择出集群中适合运行当前POD 资源的一个节点,其核心在于资源可用性POD资源公平分布与集群节点之上。

他们用于为用户提供自定义POD亲和性或反亲和性,节点亲和性以及基于污点容忍度的调度机制。

2 预选策略(一票否决制)

1 概述

执行预选操作时,调度器将对每个节点基于配置使用的预选策略以特定次序逐一选择,并根据一票否决机制进行淘汰,若预选过后不存在任何一个满足条件的节点,则POD被置于pending状态,直到至少有一个几点可用为止。

目前支持的预选策略

1 checknodecondition : 检查是否可以在节点写入磁盘,网络不可用或为准备好的情况下将POD对象调度与其上。


2 hostname: 若POD 对象拥有spec.hostname 属性,则检查节点名称字符串与此属性是否匹配,并不是必须这个POD运行在这个节点上,是否定义了hostname并且是否匹配
pods.spec.hostname


3 podfitsHostPorts: 若POD 定义了Ports.hostPort 属性,则检查其值指定的端口是否已经被节点上其他容器或服务占用


4 matchNodeselector: 若POD 对象定义了spec.nodeSelector 属性,则检查节点标签是够能匹配此属性值


5 NoDiskConflict: 检查POD对象请求的存储卷在此节点是否可用,若不存在冲突则通过检查,默认并没有启用


6 PODFITSresources: 检查节点是否有足够的资源满足POD对象的运行需求,节点声明可用容量,那些在注解中标记为关键性(critical)的POD资源不受此预选策略控制,是否有足够的资源来满足相关的需求,每一个节点都会声明其节点资源的可用量

[[email protected] ~]# kubectl describe nodes node1
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits



cpu 100m (2%) 100m (2%)
memory 50Mi (5%) 50Mi (5%)


7 PODToleratesNodeTaints: 若POD对象定义了spec.tolerations 属性,则检查其值是否能够接纳节点定义的污点(taints),不过,其仅关注具有NoSchedule 和 Noexecute 两个效用标识的污点 ,检查pod上的污点。其默认是没有被启用的。


8 PODTOleratesNodeNoExecuteTaints: 若POD 对象定义了spec.tolerations属性,则检查其是否能够接纳节点定义的NOexecute类型的污点。


9 checknodelabelpresence: 仅检查节点上指定的所有标签的存在性,要检查的标签以及其可否存在于用户的定义,当集群中部署的节点以regions/zones/racks 的拓扑方式放置且置于此类标签对其进行位置标识时,预选策略可以根据此类标识将POD资源调度至此类节点上。不在预选策略内,没有启用。


10 checkserviceaffinity: 根据当前POD对象所属的service已有的其他POD对象所运行的节点进行调度,其目的在于将相同service的POD 对象放置与同一个或同一类节点上以提高效率,此预选此类试图将那些在其节点选择器中带有特定标签的POD资源调度至拥有同样标签的节点上,具体的标签则取决于用户的定义。默认没有启用。


11 MAxEBsVOLUMEconunt: 检查节点上已挂载的EBS存储卷数量是够超过了设置的最大值,默认为39 EBS 亚马逊的弹性存储卷。


12 MaxGCEPDVolumeCount: 检查节点上已挂载的GCE PD存储卷数量是否超过了设置的最大值,默认为16


13 MaxAzureDiskVolumeCount: 检查节点上已挂载的Azure Disk 存储卷数量是否超过设置的最大值,默认为16.


14 CheckVolumeBinding:检查节点上已绑定和未绑定的PVC是否能够满足POD对象的存储卷需求,对于已绑定的PVC,此预选策略将检查给定节点是够能够兼容相应的PV,而对于未绑定的PVC,预选策略将搜索那些可满足PVC申请的可用PV,并确保他可与给定的节点兼容。


15 NovolumeZoneConflict:在给定区域(zone)限制的前提下,检查在此节点上部署POD对象是否存在存储卷冲突,


16 CheckNodeMemoryPressure: 若给定的节点已经报告了在内存资源压力过大的状态,则检查当前Pod对象是否可调度到此节点上,目前,最低优先级的BestEffort Qos类型的Pod资源也不能调度至此类节点上,因为其可能随时内存溢出。


17 CheckNodePIDPressure:若给定的节点已经报告了POD资源压力多大状态,则检查当前Pod对象是否可调度至节点之上。


18 CheckNodeDiskPressure:若给定节点已经报告了存在磁盘资源压力过大的状态,则检查当前Pod对象是否可调度至此节点之上。


19 MatchinterPodAffinity:检查给定节点是否能够满足Pod对象的亲和性和反亲和性条件,用于实现Pod亲和性调度或反亲和性调度。


其中第checknodelabelpresence条和MatchinterPodAffinity条可根据相关的情况而匹配,其可称为可选配置策略,余下的均称为静态策略,另外 NoDiskConflict 、 PODToleratesNodeTaints、checknodelabelpresence、checkserviceaffinity 没有包含在默认预选策略中。

3 优选策略

1 概述

调度器向每个通过预选的节点传递一系列的优选函数来计算其优先级分值,优先级分值介于0到10 之间,其中0表示不适用,10表示最合适托管该POD对象

调度器还支持为每个优选函数指定一个简单的由正数值表示的权重,进行节点优先级分值的计算时,首先将每个优选函数的计算得分乘以权重,然后将所有优选函数的得分相加从而得到最终的优先级分值。

2 优选策略

1 leastrequestedpriority:由节点空间资源与节点总容量的比值进行计算的,由CPU或内存资源的总容量减去已有POD对象需求的容量总和,再减去当前要创建的POD对象的需求容量得到的结果除以总容量。CPU 和 内存具有相同的权重,资源空间比例越高的界定得分就越高,计算公式为
(cpu((capacity-sum (requested)) 10/capacity) + memory ((capacity-sum (requested))\10 /capacity))/2
乘以10的原因是其优选的最高是10分,通过此得出的结果是0-10之间的数。


2 balancedresourceallocation: 以CPU 和内存资源占用率的相近程序作为评估标准,二者月接近节点权重越高,该优选及函数不能单独使用,他需要leastrequestedpriority组合使用来平衡优化节点资源使用状况,已选择那些在部署当前POD资源后系统资更为均衡的节点 。

Nodepreferavoidpodspriority 优先比例占用很高,如果其倾向于不能运行此POD,则一般都不能运行此POD,节点注解信息,没这个注解,则得分高


3 NodePreferAvoidPodsPriority: 此优选函数权限默认为10000,其将根据节点是够设置了注解信息"sheduler.alpha.kubernetes.io/preferAvoidPods"来计算其优先级,计算方式为: 给定节点无此注解信息,其得分乘以10以权重10000;存在此注解信息时,对于那些由replicationcontroller或replicaset控制器管控的POD对象得分为0,其他POD对象会被忽略


4 NodeAffinityPriority: 基于节点亲和性调度偏好进行优先级评估,其将根据POD资源中的nodeselector 对给定节点进行匹配度检查,成功匹配到的条目却多得分越高.


5 TaintTolerationPriority: 基于Pod资源对节点的污点容忍度偏好进行优先级评估,它将Pod对象的tolerations列表与节点的污点进行匹配度检查,成功匹配的条目越多,则节点得分越低。


6 selectorSpreadpriority: 首先查找与当前POD对象匹配的service、replicationcontroller、replicaset和statusfulset,尽量调度到多个不同的节点上。如果指定了区域,调度器则会尽量把Pod分散在不同区域的不同节点上。当一个Pod的被调度时,会先查找Pod对于的service或者replication controller,然后查找service或replication controller中已存在的Pod,运行Pod越少的节点的得分越高。

SelectorSpreadPriority举例说明:这里主要针对多实例的情况下使用。例如,某一个服务,可能存在5个实例,例如当前节点已经分配了2个实例了,则本节点的得分为10*((5-2)/ 5)=6分,而没有分配实例的节点,则得分为10 * ((5-0) / 5)=10分。没有分配实例的节点得分越高。

注:1.0版本被称之为ServiceSpreadingPriority,1.0之后版本变更为SelectorSpreadPriority,为了向前兼容ServiceSpreadingPriority名称仍然保留。


7 interpodaffinitypriority: 遍历Pod对象的亲和性条目,并将那些能够匹配到给定节点的条目的权重相加,结果值越大得分越高


8 mostrequestedpriority:与优选函数leastrequestedpriority的评估节点得分方式相同,其不同的是,资源占用比例越大的节点,其得分越高。


9 NodeAffinityPriority:Kubernetes调度中的亲和性机制。Node Selectors(调度时将pod限定在指定节点上),支持多种操作符(In, NotIn, Exists, DoesNotExist, Gt, Lt),而不限于对节点labels的精确匹配。另外,Kubernetes支持两种类型的选择器,一种是“hard(requiredDuringSchedulingIgnoredDuringExecution)”选择器,它保证所选的主机必须满足所有Pod对主机的规则要求。这种选择器更像是之前的nodeselector,在nodeselector的基础上增加了更合适的表现语法。另一种是“soft(preferresDuringSchedulingIgnoredDuringExecution)”选择器,它作为对调度器的提示,调度器会尽量但不保证满足NodeSelector的所有要求。
NodePreferAvoidPodsPriority(权重1W):如果 节点的 Anotation 没有设置 key-value:scheduler. alpha.kubernetes.io/ preferAvoidPods = "...",则节点对该 policy 的得分就是10分,加上权重10000,那么该node对该policy的得分至少10W分。如果Node的Anotation设置了,scheduler.alpha.kubernetes.io/preferAvoidPods = "..." ,如果该 pod 对应的 Controller 是 ReplicationController 或 ReplicaSet,则该 node 对该 policy 的得分就是0分。
TaintTolerationPriority : 使用 Pod 中 tolerationList 与 节点 Taint 进行匹配,配对成功的项越多,则得分越低。

另外在优选的调度规则中,有几个未被默认使用的规则:


10 ImageLocalityPriority:根据Node上是否存在一个pod的容器运行所需镜像大小对优先级打分,分值为0-10。遍历全部Node,如果某个Node上pod容器所需的镜像一个都不存在,分值为0;如果Node上存在Pod容器部分所需镜像,则根据这些镜像的大小来决定分值,镜像越大,分值就越高;如果Node上存在pod所需全部镜像,分值为10。

Kubernetes 的默认调度器以预选。优选、选定机制完成将每个新的POD资源绑定至为其选出的目标节点上,不过,其是默认调度器,使用中,用户还可以自定义调度器插件,并在定义POD资源配置清单时通过spec.schedulerName指定即可使用。

4 选定

当有多个相同的优选选项时,则进行随机选择

2 节点亲和度和Pod资源亲和度

1 节点亲和度概述

1 概述

亲和性调度时用来确定Pod对象调度位置的规则,其是基于节点上自定义的标签和Pod对象上指定的标签选择器进行定义的,节点亲和性允许Pod对象针对一组可以调度于其上的节点设置亲和性和反亲和性,但无法具体到某个节点。

2 节点亲和度的两种规则:

1 硬亲和:强制性规则,是Pod调度必须满足的调遣,在不存在满足此条件的节点存在时,其将一直处于pending状态。

2 软亲和:其倾向于将Pod对象运行与某类特定的节点之上,而调度器也将尽量满足需求,若无满足条件的节点,其也将会选择一个节点运行此Pod。

3 定义节点亲和性的关键要素

1 为节点设置符合的标签
2为Pod对象定义合理的标签选择器

4 节点亲和度应用场景

若Pod调度至此节点后此节点标签发生变化而不再符合亲和性规则,则调度器不会将其Pod对象从节点移除,因为其仅对新建的Pod对象生效。

2 节点亲和度

1节点硬亲和度

1 概述

为POD 对象使用nodeselector属性可以基于节点标签匹配的方式将POD对象强制调度至某一类特定的节点上,不过他仅能基于简单的等值关系定义标签选择器,而nodeaffinity中支持使用matchExpressions 属性构建更为复杂的标签选择机制

2 核心字段

pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions  

pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions.key :键名称 

pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions.operator : 指定匹配规则,有包含IN ,不包含NotIn,Exists 存在 ,DoesNotExist 不存在 

pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions.values : 指定key对应value值的列表

3 应用

查看节点标签

配置硬亲和性
实例

[[email protected] all]# cat demo.yaml
apiVersion: v1
kind: Pod
metadata:
    name: demo2
    namespace: default
spec:
    containers:
        - name: demo2
          image: nginx:1.14
    affinity:  #定义亲和性
        nodeAffinity:  #定义节点亲和性
            requiredDuringSchedulingIgnoredDuringExecution:  #定义节点硬亲和性
                nodeSelectorTerms:  #定义选择器方式
                    - matchExpressions:  #定义选择策略
                        - key: service  #定义选择器key值
                          operator: In #定义关系为包含关系
                          values: ["web1"]  #定义values值

部署

 kubectl apply -f demo.yaml

查看

其不能被调度到任何节点上

修改节点标签

kubectl label nodes 192.168.1.30  service=web1 --overwrite

查看节点标签和Pod运行状态

此时运行正常。

requiredDuringSchedulingIgnoredDuringExecution 字段的值是一个对象列表,用以定义节点硬亲和性,其可由一个或多个nodeSelectorTerms 定义的对象组成,彼此之间为"逻辑或"的关系,进行匹配度检查时,多个nodeSelectorTerms之间是或的关系,只要满足其中之一即可,nodeselectorterm:用于定义节点选择器的条目,其值为对象列表,其可由一个或多个matchExpressions对象定义的匹配规则组成,多个规则之前为"逻辑与"的关系,而matchexpression对象由可由多个标签选择器组成,多个标签选择器之间彼此为"逻辑与"的关系。


节点硬亲和性实现的功能与节点选择器相似,但亲和性支持使用匹配表达式来挑选节点,此比节点选择器更加灵活。

2 节点软亲和性

1 概述

节点软亲和性为节点选择机制提供了一种柔性控制逻辑,被调度的POD对象不再是“必须”而是“应该”放置于某个特定节点之上,当条件不满足时,他也能够接受被编排与其他不符合调节的节点之上,另外,其还为每种倾向性提供了weight 属性以便用户定义其优先级,取值范围1-100, 数字越大优先级越高。

2 核心字段

pods.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference : 定义选择策略

pods.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.weight: 定义倾向性优先级,数字越大越优先
为节点1添加标签

3 应用

实例

#[[email protected] all]# cat demo1.yaml
apiVersion: v1
kind: Pod
metadata:
    name: demo3
    namespace: default
spec:
    containers:
        - name: demo3
          image: nginx:1.14
    affinity:  #定义亲和性
        nodeAffinity:  #定义节点亲和性
            preferredDuringSchedulingIgnoredDuringExecution:  #定义节点软亲和性
                - weight: 60  #定义倾向性
                  preference: #定义匹配规则
                    matchExpressions:
                        - {key: rule, operator: In, values: ["test"]}
                - weight: 30
                  preference:
                    matchExpressions:
                        - {key: service, operator: In, values: ["db1"]}

部署

 kubectl apply -f demo1.yaml

查看

Pod 资源模板定义了对rule和service的标签选择,其对应的value都不匹配,但由于rule设置了高倾向性,则选择了具有rule标签key值对应的节点,若有足够多的节点,则其将被视为三类:
1 同时满足以上两种标签
2 仅具有任何一种标签
3 不具备任何标签

同时部署多个服务

[[email protected] all]# cat demo1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: demo
    namespace: default
spec:
    selector:
        matchLabels:
            app: nginx10
    replicas: 3
    template:
        metadata:
            name: demo3
            namespace: default
            labels:
                app: nginx10
        spec:
            containers:
                - name: demo3
                  image: nginx:1.14
            affinity:  #定义亲和性
                nodeAffinity:  #定义节点亲和性
                    preferredDuringSchedulingIgnoredDuringExecution:  #定义节点软亲和性
                        - weight: 60  #定义优先级
                          preference: #定义匹配规则
                            matchExpressions:
                                - {key: rule, operator: In, values: ["test"]}
                        - weight: 30
                          preference:
                            matchExpressions:
                                - {key: service, operator: In, values: ["db1"]}

部署

 kubectl apply -f demo1.yaml 

查看

及结果显示,其不止运行与192.168.1.30节点上,因为此处预选策略都已通过,但其需要优选策略进行选择,选择结果即为上述结果

3 Pod资源亲和度

1 概述

其原理将第一个POD放置在随意节点上,而后其他POD与其有亲和或反亲和关系的POD据此动态完成位置编排

POD 的亲和性定义存在硬亲和和软亲和,其与节点亲和性定义大体相同。

kubernetes 调度器通过内建的MatchinterPodAffinity 预选策略为这种调度方式完成节点预选,并基于InterPodAffinityPriority优选函数进行各个节点的优先级评估


2 位置拓扑

POD 亲和性调度需要各相关的POD对象运行在"同一位置",而反亲和性则要求他们不能运行于同一位置。 如果以基于各节点的hostname标签作为评判标准,则"同一位置"意味着同一个节点,不同节点及不同位置。如果基于标签选择,则可以按照设定的标签来评判。
在定义POD对象的亲和性与反亲和性时,需要借助标签选择器来选择被依赖的POD对象,并根据选出的POD对象所在的节点的标签来判断同一位置的意义。

3 POD 硬亲和度

1 概述

POD 强制约束的亲和性调度也使用pods.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution属性进行定义,POD亲和性用于描述一个POD对象与具有某些特征的现存POD对象运行位置的依赖关系

2 应用

1 创建一个人具有特定标签的POD对象

kubectl  run  tomcat -l app=tomcat  --image=tomcat:alpine

查看服务,其运行于192.168.1.40节点,且其label为app=tomcat

实例

[[email protected] all]# cat demo.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: demo-dep
    namespace: default
spec:
    selector:
        matchLabels:
            app: nginx
    replicas: 3
    template:
        metadata:
            namespace: default
            labels:
                app: nginx
        spec:
            containers:
                - name: nginx-demo
                  image: nginx:1.14
            affinity:
                podAffinity:  #配置节点亲和性
                    requiredDuringSchedulingIgnoredDuringExecution:  #配置硬亲和性
                        - labelSelector:
                            matchExpressions:  # 配置匹配亲和性的标签
                                - {key: app,operator: In,values: ["tomcat"]}
                          topologyKey: kubernetes.io/hostname #位置拓扑键,其是基于hostname级别的位置

部署

kubectl apply -f demo.yaml

查看

其所有POD都匹配到192.168.1.40节点上去

3 选择过程

1 调度器首先会基于标签选择查询拥有标签"app=tomcat"的所有POD资源
2 若存在多个则会分别获取到其所属节点的hostname标签值
3 接着查询这些拥有hostname标签值的所有节点,
4 若存在多个,则会根据优选函数进行优选处理,从而选出合适运行的节点。

kubernetes.io/hostname 标签时kubernetes集群节点的内建标签,其值是当前界定啊的节点主机名标识,对各个节点各有不同。

基于单节点的POD亲和性只能在个别情况中用到,较为常用的是基于同一地区region,区域zone或机架rack的位置拓扑约束,其只需要修改上述 deployment.spec.template.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution.topologyKey 字段的属性值即可。

4 POD 软亲和调度

1 概述

pods.spec.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution
调度器会尽力确保满足亲和性的调度逻辑,然而在约束条件不满足的情况下,它允许将POD对象调度至其他节点运行。

2 应用

创建另一个应用

kubectl run tomcat1  -l  app=tomcat1 --image=tomcat:alpine

查看

实例

[[email protected] all]# cat demo.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: demo-dep
    namespace: default
spec:
    selector:
        matchLabels:
            app: nginx
    replicas: 3
    template:
        metadata:
            namespace: default
            labels:
                app: nginx
        spec:
            containers:
                - name: nginx-demo
                  image: nginx:1.14
            affinity:
                podAffinity:  #配置节点亲和性
                    preferredDuringSchedulingIgnoredDuringExecution:
                        - weight: 80  #定义权重
                          podAffinityTerm:
                            labelSelector:
                                matchExpressions:  #配置匹配规则
                                    - {key: app,operator: In,values: ["tomcat"]}
                            topologyKey: service

                        - weight: 40
                          podAffinityTerm:
                            labelSelector:
                                matchExpressions:
                                    - {key: app,operator: In,values: ["tomcat1"]}
                            topologyKey: service

部署

kubectl apply -f demo.yaml 

查看

上述定义了两组亲和性判断机制,一种是选择值为tomcat的POD所在的节点的service标签,并赋予了较高的权限,另一种是选择值为tomcat1的POD所在的service标签,其权限较低,然其权限较高的节点192.168.1.40上具有两个POD,但另一个POD仍然运行在权限较低的192.168.1.30节点上,这既是软亲和性。

4 POD 反亲和调度

1 概述

pods.spec.affinity.podAntiAffinity
反亲和度一般用于分散同一类应用的POD对象,也包括将不同安全级别的POD对象调度至不同的区域,机架或节点。

2 反亲和度硬亲和

删除之前配置

kubectl delete -f demo.yaml
kubectl delete deployment tomcat1

查看当前服务情况

配置服务的反亲和性硬亲和性
实例

[[email protected] all]# cat demo.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: demo-dep
    namespace: default
spec:
    selector:
        matchLabels:
            app: nginx
    replicas: 3
    template:
        metadata:
            namespace: default
            labels:
                app: nginx
        spec:
            containers:
                - name: nginx-demo
                  image: nginx:1.14
            affinity:
                podAntiAffinity:
                    requiredDuringSchedulingIgnoredDuringExecution:  #定义反亲和性的硬亲和度
                        - labelSelector:
                            matchExpressions:
                                - {key: app,operator: In,values: ["tomcat"]}
                          topologyKey: kubernetes.io/hostname  #以节点为区域进行划分

部署

kubectl apply -f demo.yaml 

查看

3 反亲和度软亲和

POD反亲和性调度也支持使用柔性调度约束机制,在调度时,它将尽量满足将不同位置相斥的Pod对象调度在同一位置,但是,当约束关系无法满足时,也可以违反约束而调度,其实例与上述POD的柔性调度类似,此处便不一一举例了。

3 污点和容忍度

1 概述

污点 taints 是定义在节点之上的键值属性数据,用于拒绝将POD调度运行于其节点上,除非该POD对象具有接纳污点的容忍度,而容忍度是定义在POD对象上的键值性属性数据,用于配置节点可容忍的节点污点,而且调度器仅能将POD对象调度至其能容忍该节点污点的节点之上。

污点容忍度是通过向节点添加污点信息来控制POD对象的调度结果,从而赋予了节点控制何种POD对象能够调度特定节点上

kubernetes 使用podtoleratesnodetaints预选策略和 tainttolerationpriority优选函数来完成此种类型的高级调度机制。

2 定义污点和容忍度

1 污点

1 核心字段

nodes.spec.taintsd 核心字段
nodes.spec.taints.effect :用于定义POD对象的排斥等级,主要包含三种类型:
  1 NoSchedule: 不能容忍此污点的新POD对象不可调度至当前节点,属于强制约束关系,节点上现存的POD对象不受影响
  2 PreferNoSchedule:noschedule的柔性约束版本,即不能容忍此污点的新POD对象尽量不要调度至当前节点,不过无其他节点可提供调度时才允许接收相应的POD对象,节点现存的POD对象不受影响
  3 NoExecute:不能容忍此污点的新POD对象不可调度至当前节点,属于强制型约束关系,而且节点上现存的POD对象因节点污点变动或POD容忍度变动而不再满足匹配规则时,该POD对象将会被驱逐,即影响调度过程,也影响现存的节点,不能容忍的POD将会被直接驱逐。

nodes.spec.taints.key:定义匹配的key值
nodes.spec.taints.value: 定义匹配的value值 

2 容忍度

1 核心字段

pods.spec.tolerations.operator : 定义容忍度匹配方式
    POD 对象定义容忍度时,支持两种操作符:
    1 等值比较(Equal): 表示容忍度与污点必须在key、value和effect三者之上完全匹配
    2 存在性判断(Exists): 表示两者的key值和effect必须完全匹配,而容忍度中的value字段要使用空值。
pods.spec.tolerations.key :定义匹配的KEY
pods.spec.tolerations.effect:定义与污点匹配的排斥等级,此处为空切operator为Exists是表示可容忍所有级别的污点,但其他还需和key匹配决定。
pods.spec.tolerations.tolerationSeconds: 定义被驱逐的时长,仅当effect 为 NoExecute 时使用
pods.spec.tolerations.value:匹配的value值

一个节点可以配置使用多个污点,一个POD对象也可以有多个容忍度,但必须遵循以下逻辑:
1 首先处理每个有着与之匹配的容忍度的污点

2 不能匹配到的污点上,如果存在了一个污点使用了Noschedule 效用标识,则拒绝调度POD对象至此节点,各个污点之间是与的关系,及一个不满足,则全部不会被调度到此节点上。

3 不能匹配到的污点上,若没有任何一个使用了noschedule 效用标识,但至少有一个使用了preferNoshedule,则应尽量避免将POD对象调度至此节点

4 如果至少有一个不匹配的污点使用了NoExecute 效用标识,则节点将立即驱除POD对象,或不予以调度至给定节点,另外,即便容忍度可以匹配到使用了Noexcute效用标识的污点,若在定义容忍度时还同时使用了tolerationseconds属性定义了容忍时限,则超出时间后其也将被节点驱逐。


kubernetes中视同kuebadm部署集群时,其master节点自动添加了污点信息以组织不能容忍此污点的POD对象调度至此节点,若是单节点,则需注意此处,但在kubernetes中,kube-proxy 和kube-flannel等,都在资源创建时就已经添加了容忍度来确保其能够调度至master节点。

3 管理节点污点

1 污点定义规则

任何符合其键值规范要求的字符串均可用以定义污点信息:仅可使用字母,数字,连接符,点号和下划线,且仅能以字母或数字开头,其中键名的长度上限为253个字符,值最长为63个字符。

2 污点操作

添加污点
其使用kubectl taint 命令即可向节点添加污点,命令语法如下

kubectl taint NODE NAME KEY_1=VAL_1:TAINT_EFFECT_1 ...
KEY_N=VAL_N:TAINT_EFFECT_N [options]

为192.168.1.30节点定义污点,使其不能容忍此污点的POD不能调度至此节点上,其key为node-type,value为web

kubectl taint nodes 192.168.1.30 node-type=web:NoSchedule

查看污点信息

 kubectl get  nodes 192.168.1.30   -o go-template={{.spec.taints}}

删除污点
语法

 kubectl get  nodes 192.168.1.30   -o go-template={{.spec.taints}}
kubectl taint nodes 192.168.1.30 node-type:NoSchedule-

查看

删除节点上所有污点

kubectl patch nodes  192.168.1.30 -p ‘{"spec": {"taints": []}}‘

3 配置容忍度

1 添加节点污点

kubectl taint  nodes 192.168.1.30 app=web:NoSchedule
kubectl taint  nodes 192.168.1.40 app=db:NoSchedule

查看

2 实例

kubectl run nginx --image=nginx:1.14  --replicas=2

查看

其不能被调度至任何节点

配置有容忍度的POD资源

[[email protected] all]# cat demo1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: my-deployment
    namespace: default
spec:
    replicas: 3
    selector:
        matchLabels:
            app: myapp
            release: canary
    template:
        metadata:
            labels:
                app: myapp
                release: canary
        spec:
            containers:
                - name: myapp
                  image: ikubernetes/myapp:v2
                  ports:
                    - name: http
                      containerPort: 80
            tolerations:
                - key: "app"  #定义key值
                  effect: "NoSchedule"  #定义容忍度类别
                  operator: "Equal"  #定义匹配方式为等值匹配
                  value: "web"  #定义匹配值

部署

kubectl apply -f demo1.yaml 

查看

可以部署到指定节点和其相关匹配的标签所在的节点上

3 部署存在性判断

[[email protected] all]# cat demo2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: my-deployment1
    namespace: default
spec:
    replicas: 3
    selector:
        matchLabels:
            app: myapp1
            release: canary
    template:
        metadata:
            labels:
                app: myapp1
                release: canary
        spec:
            containers:
                - name: myapp1
                  image: ikubernetes/myapp:v2
                  ports:
                    - name: http
                      containerPort: 80
            tolerations:
                - key: "app"  #定义key值
                  effect: "NoSchedule"  #定义容忍度类别,若此处为空,则表示容忍所有级别的污点
                  operator: "Exists"  #定义匹配方式为存在性判断,只要键和容忍级别和键相同,即可调度至该节点上
                  value: ""  #定义匹配值,若是存在性判断,则此处可以为空

删除之前部署并重新部署

kubectl  delete  deployment demo-dep
kubectl apply -f demo2.yaml 

查看结果

4 配置 NoExecute
删除之前192.168.1.40配置,并重新定义污点

kubectl taint nodes 192.168.1.40 app:NoSchedule-
kubectl taint  nodes 192.168.1.40 app=db:NoExecute

查看服务

这些服务因为不匹配而导致其处于为未成功调度状态。

4 扩展

内建的污点:
1  node.kubernetes.io/not-ready: 节点进入"NotReady"状态时被自动添加的污点
2 node.alpha.kubernetes.io/unreadchable: 节点进入"NotReachable"状态时被自动添加的污点
3 node.kubernetes.io/out-of-disk: 节点进入"outOfDisk"状态时被自动添加的污点
4 node.kubernetes.io/memory-pressure: 节点磁盘资源面临压力
5 node.kubernetes.io/network-unavailable: 节点网络不可用
6 node.cloudprovider.kubernetes.io/uninitialized:kubelet由外部的云环境程序启动时,将自动为节点添加此污点,待到云控制器管理器中的控制器初始化此节点时再将其删除。

原文地址:https://blog.51cto.com/11233559/2380360

时间: 2024-11-01 09:19:52

kubernetes Pod 资源调度的相关文章

详解 Kubernetes Pod 的实现原理

Pod.Service.Volume 和 Namespace 是 Kubernetes 集群中四大基本对象,它们能够表示系统中部署的应用.工作负载.网络和磁盘资源,共同定义了集群的状态.Kubernetes 中很多其他的资源其实只对这些基本的对象进行了组合. Pod 是 Kubernetes 集群中能够被创建和管理的最小部署单元,想要彻底和完整的了解 Kubernetes 的实现原理,我们必须要清楚 Pod 的实现原理以及最佳实践. 在这里,我们将分两个部分对 Pod 进行解析,第一部分主要会从

Kubernetes Pod故障归类与排查方法

Pod概念 Pod是kubernetes集群中最小的部署和管理的基本单元,协同寻址,协同调度. Pod是一个或多个容器的集合,是一个或一组服务(进程)的抽象集合. Pod中可以共享网络和存储(可以简单理解为一个逻辑上的虚拟机,但并不是虚拟机). Pod被创建后用一个UID来唯一标识,当Pod生命周期结束,被一个等价Pod替代时UID将重新生成. Kubernetes Pod中最常用Docker容器运行,当然Pod也能支持其他的容器运行,比如rkt.podman等. Kubernetes集群中的P

Kubernetes Pod 控制器

在机器人技术和自动化中,控制环是一个控制系统状态的不终止的循环 这是一个控制环的例子:"房间里的温度自动调节器"当你设置了温度,告诉了温度自动调节器你的"期望状态",房间的实际温度是"当前状态".通过对设备的开关控制,温度自动调节器让其当前状态无限接近于期望状态.控制器通过 k8s的apiserver 去监控集群的公共状态,并致力于将当前状态转变为所期望的状态. 中文参考官方:怎么描述Kubernetes架构控制器的 kubernetes 之Po

Python Django撸个WebSSH操作Kubernetes Pod(下)- 终端窗口自适应Resize

追求完美不服输的我,一直在与各种问题斗争的路上痛并快乐着 上一篇文章Django实现WebSSH操作Kubernetes Pod最后留了个问题没有解决,那就是terminal内容窗口的大小没有办法调整,这会导致的一个问题就是浏览器上可显示内容的区域太小,当查看/编辑文件时非常不便,就像下边这样,红色可视区域并没有被用到 RESIZE_CHANNEL 前文说到kubectl exec有两个参数COLUMNS和LINES可以调整tty内容窗口的大小,命令如下: kubectl exec -i -t

[Kubernetes]Pod基本概念

Pod是Kubernetes项目的原子调度单位 为什么需要Pod? 容器是未来云计算系统中的进程,容器镜像就是这个系统里的".exe"安装包,那Kubernetes就是操作系统. 在一个真正的操作系统里,进程不是独自运行的,而是以进程组的方式组织在一起.对操作系统来说,进程组更方便管理,比如Linux只要将信号SIGKILL信号发送给一个进程组,那么该进程组中的所有进程都会收到这个信号而终止运行. 可以通过下面这个命令查看进程组,进程后面括号里的数字就是它的进程组ID(process

Kubernetes Pod应用的滚动更新(八)

一.环境准备 我们紧接上一节的环境,进行下面的操作,如果不清楚的,可以先查看上一篇博文. 滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新.滚动更新的最大的好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性. 二.更新 我们查看一下上一节的配置文件mytest-deploy.yaml. apiVersion: extensions/v1beta1 kind: Deployment metadata: name: mytest spec: repl

Kubernetes Pod概述

Pod简介 Pod是Kubernetes创建或部署的最小/最简单的基本单位,一个Pod代表集群上正在运行的一个进程. 一个Pod封装一个应用容器,Pod代表部署的一个单位. Pods提供两种共享资源:网络和存储. 网络:每个Pod被分配一个独立的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口. 存储:Pod可以指定一组共享存储volumes.Pod中的所有容器都可以访问共享volumes,允许这些容器共享数据. Pod不会自愈.如果Pod运行的Node故障,或者是调度器本身

Kubernetes系列之Kubernetes Pod控制器

#一.常见Pod控制器及含义 ###1. ReplicaSets ReplicaSet是下一代复本控制器.ReplicaSet和 Replication Controller之间的唯一区别是现在的选择器支持.Replication Controller只支持基于等式的selector(env=dev或environment!=qa),但ReplicaSet还支持新的,基于集合的selector(version in (v1.0, v2.0)或env notin (dev, qa)).大多数kub

docker管理神器—kubernetes—pod篇

前面介绍了pod是个容器组,那么现在就来创建一个pod,就像dockerfile一样. vi nginx-pod.yaml(要十分注意空格,一般为两个空格) 添加: apiVersion: v1 kind: Pod metadata: name: nginx1 spec: containers: - name: nginx1 image: docker.io/nginx ports: - containerPort: 9001 启动Pod kubectl create -f nginx-pod.