k8s pod的调度

能够影响Pod调度的资源属性主要有如下5种:

  1. NodeSelector (工作节点选择器)
  2. NodeAffinity (工作节点级亲和性)
  3. PodAffinity (Pod级的亲和性)
  4. Taints和Tolerations(污点和容忍)
  5. pod的资源限制和要求   

NodeSelector(硬性要求)

根据node上的标签,指定Pod可以调度到哪些node工作节点上。如果所有的node节点上都没有符合标签,则Pod不会被创建。

使用方式如下:
template.spec.nodeselector:键值对(k:v,标签)

NodeAffinity

Affinity的优点:

1.匹配有更多的逻辑组合,不只是字符串的完全相等


2.调度分成软策略(soft)和硬策略(hard),在软策略下,如果没有满足调度条件的节点,pod会忽略这条规则,继续完成调度。


目前主要的node affinity:

1.requiredDuringSchedulingIgnoredDuringExecution表示pod必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试。其中IgnoreDuringExecution表示pod部署之后运行的时候,如果节点标签发生了变化,不再满足pod指定的条件,pod也会继续运行。
2.requiredDuringSchedulingRequiredDuringExecution表示pod必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试。其中RequiredDuringExecution表示pod部署之后运行的时候,如果节点标签发生了变化,不再满足pod指定的条件,则重新选择符合要求的节点。
3.preferredDuringSchedulingIgnoredDuringExecution表示优先部署到满足条件的节点上,如果没有满足条件的节点,就忽略这些条件,按照正常逻辑部署。
4.preferredDuringSchedulingRequiredDuringExecution表示优先部署到满足条件的节点上,如果没有满足条件的节点,就忽略这些条件,按照正常逻辑部署。其中RequiredDuringExecution表示如果后面节点标签发生了变化,满足了条件,则重新调度到满足条件的节点。


对于软策略还可以为其设置权重weight

一个官方实例:

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
 - name: with-node-affinity
    image: gcr.io/google_containers/pause:2.0

  

这里的匹配逻辑是label在某个列表中,可选的操作符有:

In: label的值在某个列表中


NotIn:label的值不在某个列表中


Exists:某个label存在


DoesNotExist:某个label不存在


Gt:label的值大于某个值(字符串比较)


Lt:label的值小于某个值(字符串比较)


可利用NotIn和DoesNotExist来实现对node排斥的功能

特别注意

如果同时定义了nodeselector和NodeAffinity,则需要两者同时满足
如果定义了多个nodeselectorTerms,则只需要有一个满足
如果定义了多个matchExpressions,只需要满足所有的matchExpressions

PodAffinity

实现能够考虑pod之间的关系,而不只是pod与node的关系来进行调度。情况1(亲和):有两个应用pod交互的比较多,希望在同一node;情况2(互斥):有两个Pod都有大读写,希望不要调度在同一个node上。

通过topologyKey来表达对node节点的选择,topologyKey指向node节点内置标签的KEY;意为表达节点所属的topology范围:

kubernetes.io/hostname


failure-domain.beta.kubernetes.io/zone


failure-domain.beta.kubernetes.io/region


和node affinity相似,pod affinity 也有requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution,意义也和之前一样。如果使用亲和性,在 affinity 下面添加 podAffinity 字段,如果要使用互斥性,在 affinity 下面添加 podAntiAffinity 字段。

先定义一个参照目标pod:

apiVersion: v1
kind: Pod
metadata:
  name: pod-flag
  labels:
    security: "S1"
    app: "nginx"
spec:
  containers:
  - name: nginx
    image: nginx

  

Pod亲和性调度

下面是一个亲和性调度的示例

apiVersion: v1
kind: Pod
metadata:
  name: pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: kubernetes.io/hostname
  containers:
  - name: with-pod-affinity
    image: gcr.io/google_containers/pause:2.0

  

创建后可以看到这个pod与上面那个参照的pod位于同一个node上,另外,如果将这个node上的kubernetes.io/hostname标签干掉,将会发现pod会一直处于pending状态,这是因为找不到满足条件的node了。

pod互斥性调度

下面是一个互斥性调度的示例:

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: "failure-domain.beta.kubernetes.io/zone"
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: kubernetes.io/hostname
  containers:
  - name: with-pod-affinity
    image: gcr.io/google_containers/pause:2.0

  

这个例子要求这个新pod与security=S1的pod为同一个zone,但是不与security=S2的pod为同一个node。

原则上,topologyKey可以使用任何合法的标签Key赋值,但是出于性能和安全方面的考虑,对topologyKey有如下限制:

1.在pod亲和性和RequiredDuringScheduling的pod互斥性的定义中,不允许使用空的topologyKey


2.如果admissioncontroller包含了LimitPodHardAntiAffinityTopology,那么针对RequiredDuringScheduling的pod互斥性定义就被限制为kubernetes.io/hostname,要使用自定义的topologyKey,就要改写或禁用该控制器


3.在PerferredDuringScheduling类型的Pod互斥性定义中,空的topologyKey会被解释为kubernetes.io/hostname、failure-domain.beta.kubernetes.io/zone及failure-domain.beta.kubernetes.io/region的组合


podAffinity规则设置的注意事项:

在labelSelector和topologyKey同级,还可以定义namespaces列表,表示匹配哪些namespace里面的pod,默认情况下,会匹配定义的pod所在的namespace,如果定义了这个字段,但是它的值为空,则匹配所有的namespaces。
所有关联requiredDuringSchedulingIgnoredDuringExecution的matchExpressions全都满足之后,系统才能将pod调度到某个node上。

Taint(污点)和Toleration(容忍)

Taint需要与Toleration配合使用,让pod避开那些不合适的node。在node上设置一个或多个Taint后,除非pod明确声明能够容忍这些“污点”,否则无法在这些node上运行。Toleration是pod的属性,让pod能够(注意,只是能够,而非必须)运行在标注了Taint的node上。

举例说明

设置node的污点

kubectl taint nodes node1  key=value:NoSchedule

  

Taint污点的组成有KEY表示键名,VALUE表示KEY的值,NoSchedule表示效果。
效果一共有三种:

a.NoSchedule:Pod除非设置容忍这个属性,否则无法调度到此node


b.PreferNoSchedule:Pod除非设置容忍这个属性,否则避免调度到此node


c.NoExecute:pod的驱逐行为,以应对节点故障。NoExecute这个Taint效果对节点上正在运行的pod有以下影响:


1.没有设置Toleration的Pod会被立刻驱逐


2.配置了对应Toleration的pod,如果没有为tolerationSeconds赋值,则会一直留在这一节点中


3.配置了对应Toleration的pod且指定了tolerationSeconds值,则会在指定时间后驱逐

设置pod的容忍

apiVersion: v1
kind: Pod
metadata:
  name: pod-taints
spec:
  tolerations:
 - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"
  containers:
    - name: pod-taints
      image: busybox:latest

  

也可以写成如下:

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

  

pod的Toleration中的key和effect需要与Taint的设置保持一致,并且满足以下条件之一

  • operator的值为Exists,这时无需指定value
  • operator的值为Equal并且value相等(默认)

多污点和多容忍

Kubernetes调度器处理Toleration对Taint进行匹配,剩下的没有匹配掉的Taint就是对Pod的效果了。下面是几种特殊情况:

 

1.如果剩余的Taint中存在effect=NoSchedule,则调度器不会把该pod调度到这一节点上。


2.如果剩余的Taint中没有NoSchedule的效果,但是有PreferNoSchedule效果,则调度器会尝试不会pod指派给这个节点


3,如果剩余Taint的效果有NoExecute的,并且这个pod已经在该节点运行,则会被驱逐;如果没有在该节点运行,也不会再被调度到该节点上。

 


原文链接:https://blog.csdn.net/weixin_42155272/article/details/100518318

 

posted @ 2021-05-07 18:23  sucre_tan  阅读(248)  评论(0编辑  收藏  举报