计算机系统应用教程网站

网站首页 > 技术文章 正文

k8s中三种POD调度策略介绍

btikc 2024-09-04 03:09:26 技术文章 11 ℃ 0 评论

k8s中三种POD调度策略介绍

一:三种调度POD的方法:

1)污点、容忍度

2)nodeName:让POD运行在制定的node上

3)nodeSelecter:通过标签选择器,让POD运行在制定的一组node上


二:K8S调度器 污点使用方法

默认调度是:最大空闲资源调度

调度器 预算策略

CheckNodeCondition:检查节点网络磁盘等是否正常

GeneralPredicates:通用预选策略

HostName:检查pod对象是否定义了pod.spec.hostname

podFitsHostPorts: pods.spec.containers.ports.hostPort

MatchNNodeSelector:pods.spec.nodeSelector

PodFitsResources:检查Pod资源需求能否被节点满足

NoDiskConflict:检查pod依赖的存储卷能否满足,默认不启用

PodToleratesNodeTaints:检查Pod上的spec.tolerations 容忍点是否包含节点污点

PodToleratesNodeBoExecteTaints:默认不启用

CheckNodeLabelPresence:检查节点标签存在,默认不启用

CheckServiceAffinity:根据当前pod所属对象services放在同一个node


污点调度

查看节点污点

kubectl describe node node-name

kubectl describe node 192.168.10.11

官方文档:https://kubernetes.io/zh/docs/concepts/configuration/taint-and-toleration/


节点添加污点

kubectl taint nodes node1 key=value:NoSchedule

kubectl taint nodes node1 key=value:NoExecute

kubectl taint nodes node1 key=value:PreferNoSchedule


NoSchedule: K8Snode添加这个effect类型污点,新的不能容忍的pod不能再调度过来,但是老的运行在node上不受影响

NoExecute:K8Snode添加这个effect类型污点,新的不能容忍的pod不能调度过来,老的pod也会被驱逐

PreferNoSchedule:表示k8s将尽量避免将Pod调度到具有该污点的Node上


节点删除污点:

kubectl taint nodes kube11 key:NoSchedule-


pod设置容忍一个污点

apiVersion: apps/v1Beta1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 1
    selector:
      matchLabels:
        app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        images: nginx:laste
        ports:
        - containerPort: 80       
      tolerations:  #containers同级
      - key: "key1"          #能容忍的污点key
        operator: "Equal"    #Equal等于表示key=value , Exists不等于,表示当值不等于下面value正常
        value: "value1"      #值
        effect: "NoExecute"  #effect策略,见上面
     tolerationSeconds: 3600  #原始的pod多久驱逐,注意只有effect: "NoExecute"才


三:调度taint 和tolerations 介绍

节点亲和性(affinity),是节点的一种属性,让符合条件的pod亲附于它(倾向于或者硬性要求).

污点是一种相反的行为,它会使pod抗拒此节点(即pod调度的时候不被调度到此节点)

污点和容忍结合在一起以确保pod不会被调度到不适合的节点上.当一个或者多个污点添加到某个节点上,则意味着此节点不会接受任何不容忍这些污点的pod.Tolerations作用于pod上,允许(但不是必须)pod被调度到有符合的污点(taint)的节点上

概念

可以使用kubectl taint为一个节点(node)添加污点(taint),例如:

kubectl taint nodes node1 key=value:NoSchedule

这样就把键为key,值为value,效果为NoSchedule的污点添加到了节点node1上.这样除非pod有符合的容忍(toleration),否则不会被调度到此节点上

可以通过以下命令删除刚添加的taint

kubectl taint nodes node1 key:NoSchedule-


你可以在创建pod的yml里指定一个关于toleration的PodSpec,以下两个容忍都会匹配前面创建的taint,因此它们中的任意一个创建的pod都会被调度到节点node1上

tolerations: - key: "key" operator: "Equal" value: "value" effect: "NoSchedule"

tolerations: - key: "key" operator: "Exists" effect: "NoSchedule"

只有pod的key和effect都和某一个污点的key与effect匹配,才被认为是匹配,并且要符合以下情形:

operator是Exists(这种情况下value不应当指定)

operator是 Equal 并且value相同

如果operator没有指定,则默认是Equal


以下两种情况为特殊情况:

如果key是空(是指key没有指定,而不是指key为空字符串),operator为Exists则匹配所有的key,value和effect,也即匹配任何node,

tolerations: - operator: "Exists"

空的effect匹配所有effect

tolerations: - key: "key" operator: "Exists"

以上会匹配所有key为key的所有taint节点


你可以为一个节点(node)添加多个污点,也可以为一个pod添加多个容忍(toleration).kubernetes处理多个污点(taint)或者多个容忍(toleration)类似于过滤器:起初包含所有污点,然后忽略掉pod匹配的污点,剩下不可被忽略的污点决定此节点对pod的效果,特别地:

如果至少有一个不可忽略的NoSchedule类型的效果(effect),kubernetes不会调度pod到此节点上来.

如果没有不可忽略的NoSchedule类型的效果(effect),但是至少有一个PreferNoSchedule类型的效果,则kubernetes会尝试调度pod到此节点上

如果至少有一个NoExecute类型的效果(effect),则此pod会被驱离此节点(当然,前提此pod在此节点上),并且如果pod不在此节点上,也不会被调度到此节点上

所谓驱离是指pod被从此节点上移除,调度到其它节点上


示例,假如你有一个以下类型的节点

kubectl taint nodes node1 key1=value1:NoSchedule kubectl taint nodes node1 key1=value1:NoExecute kubectl taint nodes node1 key2=value2:NoSchedule

和以下类型的pod

tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute"

这种情况下,pod不会被调度到node1上,因为没有容忍(toleration)来匹配第三个taint.但是如果它运行在此节点上,它仍然可以继续运行在此节点上,因为它仅仅不匹配第三个taint.(而第三个taint的效果是NoSchedule,指示不要被调度到此节点)


通常情况下,一个效果类型为NoExecute的taint被添加到一个节点上后,所有不容忍此taint的pod会被马上驱离,容忍的永远不会被驱离(上述例子符合容忍条件).但是效果类型NoExecute可以指定一个tolerationSeconds字段来指示当NoExecute效果类型的污点被添加到节点以后,pod仍然可以继续在在指定时间内留存在此节点上.

例如:

tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600

它意味着如果pod运行在一个可以容忍的节点上,则它可以继续运行3600秒,然后被驱离,在此段时间内如果污点被移除,则pod不会被驱离.

以上可以理解为有条件容忍,即便匹配也不能一直运行在此节点上,只能在符合条件的时段内运行在此节点上.


实例:

taint和toleration可以非常灵活地把指示pod不要调度到不合适的节点或者把已经存在的pod驱离节点,以下列举出一些用例:

专用节点 假如你想让某些节点供特定的用户专用,你可以为这些节点添加污点,

例如:

kubectl taint nodes nodename dedicated=groupName:NoSchedule

然后给专用这些节点的pod添加容忍(toleration),容忍节点污点的pod被允许调度到节点上,当然也可以调度到集群中的其它节点上(没有taint的节点,有taint的必须容忍).如果你想要pod仅被调度到专用的节点,则需要添加标签(使用前面讲到过的亲和属性)

pod的亲和性是以pod为中心的,而节点的污点则是以节点为中心.想要使pod被调度到指定节点,需要亲和属性,想要节点排斥非专用pod,则需要使用taint,同时使用亲和性和污点可以保证专用节点被特定pod专用,特定pod仅使用专用节点

配有特殊硬件的节点 在一个集群中,有部分节点包含特殊硬件(例如特殊GPU),理想的情况是把让不需要特殊硬件的pod不被调度到这些节点上以便为可能需要特殊硬件的节点留存空间,这种情况下就可以用给指定节点添加污点(taint)的方法来实现效果.(例如kubectl taint nodes nodename special=true:NoSchedule or kubectl taint nodes nodename special=true:PreferNoSchedule),然后给需要使用特殊硬件的pod添加符合的容忍(toleration).

基于taint的驱离策略(测试功能),当节点出现问题时,把不容忍的pod驱离.


基于taint的驱离策略

前面我们提到过NoExecute效果类型的taint,它将对已经存在于此节点上的pod产生效果:

不容忍此taint的pod会被马上驱离

容忍此taint但是没有指定tolerationSeconds的pod将会永远运行在此节点

容忍此taint但是包含tolerationSeconds属性的节点将会在此节点上留存指定时间(虽然容忍,但是是有条件的,仅在一段时间内容忍)

第三点的言外之意即为即便容忍,但是超过容忍时间后仍然会被驱离

此外,kubernetes 1.6引入了对节点问题的展示.也就是说当满足了特定条件,节点控制器会自动为符合条件的节点添加taint,以下是一些内置的taint


node.kubernetes.io/not-ready,节点还没有准备好,对应节点状态Ready值为false

node.kubernetes.io/unreachable,节点控制器无法触及节点,对应节点状态ready值为Unknown

node.kubernetes.io/out-of-disk,磁盘空间不足

node.kubernetes.io/memory-pressure,节点存在内存压力

node.kubernetes.io/disk-pressure,节点磁盘存在压力

node.kubernetes.io/network-unavailable,节点网络不可用

node.kubernetes.io/unschedulable,节点不可被调度

node.cloudprovider.kubernetes.io/uninitialized


四:案例介绍

污点的设置和去除

使用kubectl设置和去除污点的命令示例如下:

# 设置污点

kubectl taint nodes node1 key1=value1:NoSchedule

# 去除污点

kubectl taint nodes node1 key1:NoSchedule-


接下来看一个具体的例子,使用kubeadm部署和初始化的Kubernetes集群,master节点被设置了一个node-role.kubernetes.io/master:NoSchedule的污点,可以使用kubectl describe node 命令查看。这个污点表示默认情况下master节点将不会调度运行Pod,即不运行工作负载。对于使用二进制手动部署的集群设置和移除这个污点的命令如下:

kubectl taint nodes node-role.kubernetes.io/master=:NoSchedule

kubectl taint nodes node-role.kubernetes.io/master:NoSchedule-


注意:kubeadm初始化的Kubernetes集群,master节点也被打上了一个node-role.kubernetes.io/master=的label,标识这个节点的角色为master。

给Node设置Label和设置污点是两个不同的操作。

设置Label和移除Label的操作命令如下

# 设置Label

kubectl label node node1 node-role.kubernetes.io/master=

# 移除Label

kubectl label node node1 node-role.kubernetes.io/master-

kubectl get node


容忍(Tolerations)

设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到Node上。 但我们可以在Pod上设置容忍(Toleration),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上。

通过在Pod的spec中设置tolerations字段,给Pod设置上容忍点Toleration:

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
  tolerationSeconds: 3600
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
- key: "key2"
  operator: "Exists"
  effect: "NoSchedule"


其中key, vaule, effect要与Node上设置的taint保持一致

operator的值为Exists将会忽略value值

tolerationSeconds用于描述当Pod需要被驱逐时可以在Pod上继续保留运行的时间


下面看一下在Pod上设置容忍的两个特例:

示例1: 当不指定key值时,表示容忍所有的污点key:

tolerations:

- operator: "Exists"

示例2:当不指定effect值时,表示容忍所有的污点作用:

tolerations:

- key: "key"

operator: "Exists"


实践:Kubernetes master节点不运行工作负载

Kubernetes集群的Master节点是十分重要的,一个高可用的Kubernetes集群一般会存在3个以上的master节点,为了保证master节点的稳定性,一般不推荐将业务的Pod调度到master节点上。 下面将介绍一下我们使用Kubernetes调度的Taints和和Tolerations特性确保Kubernetes的Master节点不执行工作负载的实践

我们的Kubernetes集群中总共有3个master节点,节点的名称分别为k8s-01、k8s-02、k8s-03。 为了保证集群的稳定性,同时提高master节点的利用率,我们将其中一个节点设置为node-role.kubernetes.io/master:NoSchedule,另外两个节点设置为node-role.kubernetes.io/master:PreferNoSchedule,这样保证3个节点中的1个无论在任何情况下都将不运行业务Pod,而另外2个载集群资源充足的情况下尽量不运行业务Pod


kubectl taint nodes k8s-01 node-role.kubernetes.io/master=:NoSchedule

kubectl taint nodes k8s-02 node-role.kubernetes.io/master=:PreferNoSchedule

kubectl taint nodes k8s-03 node-role.kubernetes.io/master=:PreferNoSchedule


另外对于我们部署在集群中的一些非业务组件,例如Kubernetes Dashboard、jaeger-collector、jaeger-query、Prometheus、kube-state-metrics等组件,通过设置Tolerations和Pod Affinity(亲和性)将这些组件运行在master节点上,而其他的业务Pod运行在普通的Node节点上




Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表