云原生|kubernetes |一文带你搞懂pod调度策略,驱逐策略,污点、容忍调度

简介: 云原生|kubernetes |一文带你搞懂pod调度策略,驱逐策略,污点、容忍调度

前言

kubernetes集群不是简单的安装部署就完事了,还需要根据业务的性质设定一些策略,比如,某些pod不希望被调度到硬件条件比较差的节点,某些pod又希望调度到含有比如有特定的硬件GPU的节点上。又或者某个节点由于硬件资源比如CPU,内存并没有彻底耗尽,但如果在继续调度pod到此节点有造成集群崩溃的风险,如何阻止并驱逐此节点在运行的pod,以及集群需要检修或者重建某个节点,此时的节点上运行的pod应该如何处置等等各种各样的问题以及解决方案就形成了pod调度策略,驱逐策略,污点、容忍调度策略。

说人话,这些也可以说是kubernetes集群的优化策略。下面将就以上提出的情况和一些没有提到过的情况做一个总结吧!!!

主要的pod调度策略:

  • 自由调度:pod运行在哪个节点完全由scheduler经过一系列算法计算得出(如果没有定向调度,亲和性,容忍策略,此策略就是默认的啦)
  • 定向调度:采用nodeName、nodeSelector来实现pod定向调度(pod面向节点)
  • 亲和性调度:NodeAffinityinity、PodAffinity、PodAntiAffinity
  • 污点、容忍调度:Taints、Toleration(前面讲过了)

一,

节点维护状态(cordon,uncordon,drain)

节点情况举例:

例如有三个节点,k8s-node1,k8s-node2,k8s-master

[root@master ~]# k get no
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    <none>   25d   v1.18.3
k8s-node1    Ready    <none>   25d   v1.18.3
k8s-node2    Ready    <none>   25d   v1.18.3

现有两个pod在节点2运行,其中pod  kube-flannel-ds-mlb7l是daemonsets方式部署,是核心组件:

NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE     IP               NODE         NOMINATED NODE   READINESS GATES
default       busybox-7bf6d6f9b5-jg922   1/1     Running   2          24d     10.244.0.11      k8s-master   <none>           <none>
default       nginx-7c96855774-28b5w     1/1     Running   2          24d     10.244.0.12      k8s-master   <none>           <none>
default       nginx-7c96855774-d592j     1/1     Running   0          4h44m   10.244.0.13      k8s-master   <none>           <none>
default       nginx1                     1/1     Running   2          24d     10.244.2.11      k8s-node2    <none>           <none>
kube-system   coredns-76648cbfc9-lb75g   1/1     Running   2          24d     10.244.2.10      k8s-node2    <none>           <none>
kube-system   kube-flannel-ds-mhkdq      1/1     Running   7          24d     192.168.217.17   k8s-node1    <none>           <none>
kube-system   kube-flannel-ds-mlb7l      1/1     Running   6          24d     192.168.217.18   k8s-node2    <none>           <none>
kube-system   kube-flannel-ds-sl4qv      1/1     Running   2          24d     192.168.217.16   k8s-master   <none>           <none>

假如现在需要维护node2节点,那么,先需要驱逐node2节点上的所有pod,pod方式部署的直接驱逐,daemonsets的忽略:

[root@master ~]# k drain k8s-node2 --force --ignore-daemonsets
node/k8s-node2 already cordoned
WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: default/nginx1; ignoring DaemonSet-managed Pods: kube-system/kube-flannel-ds-mlb7l
evicting pod default/nginx1
evicting pod kube-system/coredns-76648cbfc9-lb75g
pod/coredns-76648cbfc9-lb75g evicted
pod/nginx1 evicted
node/k8s-node2 evicted

结果是这样的:

可以看到,coredns这个pod漂移到了node1,pod方式部署的nginx直接销毁了,kube-flannel-ds-mlb7l没有变动

[root@master ~]# k get po -A -owide
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE     IP               NODE         NOMINATED NODE   READINESS GATES
default       busybox-7bf6d6f9b5-jg922   1/1     Running   2          24d     10.244.0.11      k8s-master   <none>           <none>
default       nginx-7c96855774-28b5w     1/1     Running   2          24d     10.244.0.12      k8s-master   <none>           <none>
default       nginx-7c96855774-d592j     1/1     Running   0          4h52m   10.244.0.13      k8s-master   <none>           <none>
kube-system   coredns-76648cbfc9-z8kh5   1/1     Running   0          2m2s    10.244.1.8       k8s-node1    <none>           <none>
kube-system   kube-flannel-ds-mhkdq      1/1     Running   7          24d     192.168.217.17   k8s-node1    <none>           <none>
kube-system   kube-flannel-ds-mlb7l      1/1     Running   6          24d     192.168.217.18   k8s-node2    <none>           <none>
kube-system   kube-flannel-ds-sl4qv      1/1     Running   2          24d     192.168.217.16   k8s-master   <none>           <none>

这个时候的节点是部分禁用的(这里的意思是scheduler服务不会调度新的pod到此节点,但,如果强制nodeselector,仍然会运行新pod)

此时的scheduler不会调度新pod到node2节点

[root@master ~]# k get no
NAME         STATUS                     ROLES    AGE   VERSION
k8s-master   Ready                      <none>   25d   v1.18.3
k8s-node1    Ready                      <none>   25d   v1.18.3
k8s-node2    Ready,SchedulingDisabled   <none>   25d   v1.18.3

节点维护状态和解除节点维护状态:

[root@master coredns]# k cordon k8s-node2
node/k8s-node2 cordoned
[root@master coredns]# k uncordon k8s-node2
node/k8s-node2 uncordoned

小结:

cordon,uncordon,drain这三个命令主要是用在节点维护场景,drain有安全驱逐pod的功能,pod会实现漂移,但此驱逐并非硬性驱逐,管不了pod的指定调度策略。

适用范围是比较窄的哦,比如,使用了本地存储卷的pod或者有状态pod不适合使用drain,因为drain了相关服务就完蛋了。

二,

taints--节点污点

关于污点的解释

[root@master coredns]# k explain node.spec.taints
KIND:     Node
VERSION:  v1
RESOURCE: taints <[]Object>
DESCRIPTION:
     If specified, the node's taints.
     The node this Taint is attached to has the "effect" on any pod that does
     not tolerate the Taint.
FIELDS:
   effect <string> -required-
     Required. The effect of the taint on pods that do not tolerate the taint.
     Valid effects are NoSchedule, PreferNoSchedule and NoExecute.
   key  <string> -required-
     Required. The taint key to be applied to a node.
   timeAdded  <string>
     TimeAdded represents the time at which the taint was added. It is only
     written for NoExecute taints.
   value  <string>
     The taint value corresponding to the taint key.

taint的子选项effect有三个结果定义:

1,NoSchedule:表示k8s将不会将Pod调度到具有该污点的Node上
2,PreferNoSchedule:表示k8s将尽量避免将Pod调度到具有该污点的Node上
3,NoExecute:表示k8s将不会将Pod调度到具有该污点的Node上,同时会将Node上已经存在的Pod驱逐出去

污点的设置:

例如设置node2节点污点为NoExecute(这里的key=value 可以随意设置,比如,A=B:noExecute也是OK的,但最好有意义,后面的容忍会用到key和values的值):

kubectl taint nodes k8s-node2 key=value:NoExecute

查看节点和pod(可以看到,node2不可调度,并且其上的pod都被Terminating,因为busybox这个pod我是设置了nodeSelector   ):

[root@master coredns]# k get no
NAME         STATUS                     ROLES    AGE   VERSION
k8s-master   Ready                      <none>   25d   v1.18.3
k8s-node1    Ready                      <none>   25d   v1.18.3
k8s-node2    Ready,SchedulingDisabled   <none>   25d   v1.18.3
[root@master coredns]# k get po -A -owide
NAMESPACE     NAME                       READY   STATUS        RESTARTS   AGE    IP               NODE         NOMINATED NODE   READINESS GATES
default       busybox-68c4f6755d-24f79   0/1     Terminating   0          18s    <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-26f5j   0/1     Terminating   0          34s    <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-28m4l   0/1     Terminating   0          42s    <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-2bb7z   0/1     Terminating   0          39s    <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-2gkss   0/1     Terminating   0          4s     <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-2gpq4   0/1     Terminating   0          87s    <none>           k8s-node2    <none>           <none>
kube-system   kube-flannel-ds-mlb7l      1/1     Terminating   6          25d    192.168.217.18   k8s-node2    <none>           <none>

解除污点

kubectl taint nodes k8s-node2 key:NoExecute-
kubectl uncordon k8s-node2

污点的查看

[root@master ~]# kubectl describe nodes k8s-node2 |grep Taints
Taints:             key=value:NoSchedule

OK,现在node2有污点,此节点不调度新pod,那么,我们来部署一个三副本的pod看看能否成功:

[root@master coredns]# cat test.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
 #     nodeName: k8s-node2
      containers:
      - name: busybox
        image: busybox:1.28.3
        imagePullPolicy: IfNotPresent
        args:
        - /bin/sh
        - -c
        - sleep 10; touch /tmp/healthy; sleep 30000

可以看到,pod确实没有在node2上,即使副本数修改为10个,仍然是不会调度到node2这个节点。

[root@master coredns]# k get po -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
busybox-7bf6d6f9b5-5qzfn   1/1     Running   0          44s   10.244.1.10   k8s-node1    <none>           <none>
busybox-7bf6d6f9b5-j72q7   1/1     Running   0          44s   10.244.0.14   k8s-master   <none>           <none>
busybox-7bf6d6f9b5-mgt8j   1/1     Running   0          44s   10.244.0.15   k8s-master   <none>           <none>

关于污点的小结

污点存在的意义:

使用 kubectl taint 命令可以给某个 node节点设置污点,Node 被设置上污点之后就和 Pod 之间存在了一种互斥的关系,可以让 Node 拒绝 Pod 的调度执行,甚至将 Node 已经存在的 Pod 驱逐出去:

key=value:effect

通过给节点设置不同的污点,可以制定一个总的策略,例如,新节点使用effect NoExecute,那么,想在此节点运行pod就必须是有设置tolerations(容忍策略)的特定pod了,无疑安全性会大大提高,一般master节点是不建议运行非核心服务的pod的,因此,也可以给master打上NoSchedule污点,以保护master。

稍作总结,三种污点effect里,NoSchedule和PreferNoSchedule是比较温和的,NoExecute是最为严厉的,即使pod设置了nodeSelector或者nodeSelectorTerm,设置了此effect的节点也是不可使用的,也可以算是真正的节点禁用,因此,NoExecute是慎用的。

NoSchedule等于是节点维护状态,PreferNoSchedule等于是无所谓,你非要调度到这个节点也行。

以上都是面向某个节点内的所有pod调度,未免对于pod的调度不够精细,例如,NoExecute直接将节点内的pod全部清空,太暴力了(虽然这么做,整个节点的安全性非常高,和iptables防火墙一样的策略嘛,先禁止所有,然后在放开部分,相当于tolerations,其实这也是容忍存在的意义嘛)。那么,下面的调度策略将针对的是单个pod。

污点的effect可以设置多个

三,

容忍策略---tolerations

容忍是相对于污点来说的,容忍是在pod内设置的。光说不练假把式对吧,直接看kube-flannel的部署清单文件内的相关内容吧:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
        effect: NoSchedule

此段容忍表示,默认的容忍污点的effec 是NoSchedule的节点,也就是说即使此node节点设置了NoSchedule,该pod仍然可以部署,为什么是这样设置呢?其实此清单文件是可以使用在kubeadmin部署的集群内,默认的kubeadmin部署的集群会对master节点设置NoSchedule的污点。

查看node2的污点(假设我已经提前设置好了污点):

[root@master coredns]# k describe node k8s-node2 |grep Taints
Taints:             key=values:NoExecute

此pod将不会被创建:

[root@master coredns]# cat nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeaffinity-preferred
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.18
  affinity:  #亲和性设置
    nodeAffinity: #设置node亲和性
      preferredDuringSchedulingIgnoredDuringExecution: # 软限制
      - weight: 1
        preference:
          matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有)
          - key: nodeweb
            operator: In
            values: ["dsfsd","web"]
  nodeName: k8s-node2

修改成如下的pod才可以被创建(容忍三行):

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.18
  tolerations:
  - operator: Exists
    effect: NoExecute
  affinity:  #亲和性设置
    nodeAffinity: #设置node亲和性
      preferredDuringSchedulingIgnoredDuringExecution: # 软限制
      - weight: 1
        preference:
          matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有)
          - key: nodeweb
            operator: In
            values: ["dsfsd","web"]
  nodeName: k8s-node2

容忍定义小结:

  • 污点和容忍是相呼应的关系,也就是说有污点才有容忍,光有容忍是没有意义的。
  • operator的值只有两个Equal和Exists两个,从字面翻译看,Equal表示必须相等,Exists表示默认情况。
  • operator 的值为 Exists 时将会忽略 value 值,也可以直接省略values定义。
  • operator 的值为 Exists 时可以省略key值,此时表示表示容忍所有的污点 key,例如:
tolerations:
- operator: “Exists”
  • effect可以省略,省略effect 值时,表示容忍所有的污点作用,例如:
tolerations:
- key: “key”
operator: “Exists”

下面是一个比较完整的示例:

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”

 

三,

pod调度策略

这些策略都是写在资源清单文件内的,针对单独的pod

默认情况下,一个pod被调度到哪个node节点是由scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的,但是在实际使用中,这并不能满足所以要求,很多时候我们想控制某些pod到达某些节点,所以kubernetes就为我们提供了4种pod的调度策略来解决该问题。


(1)定向调度

主要是指定pod定向调度到哪个node节点上

a)

nodeName策略

注:kubectl集群节点名nodeName称可以通过kubectl get nodes查看,例如本例:

[root@master coredns]# k get no
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    <none>   25d   v1.18.3
k8s-node1    Ready    <none>   25d   v1.18.3
k8s-node2    Ready    <none>   25d   v1.18.3

 

资源清单文件内使用:

[root@master coredns]# cat nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.18
  nodeName: k8s-node1 # 指定调度到node1节点上,注意此字段是pod属性,所以和containers在同一列

毫无疑问,此pod必定会在node2节点运行,即使有drain或者train设置了NoScheduler

b)

NodeSelector策略

NodeSelector用于将pod调度到添加了指定标签的node节点上。它是通过kubernetes的label-selector机制实现的,也就是说,在pod创建之前,会由scheduler使用MatchNodeSelector调度策略进行label匹配,找出目标node,然后将pod调度到目标节点,该匹配规则是强制约束。简单的说就是给kubectl集群的node节点打上标签,然后调度器将pod调度到指定标签的node上。

例如给node2节点设置标签,并查询标签:

kubectl label nodes k8s-node2 node=LAMP
[root@master coredns]# k get nodes --show-labels
NAME         STATUS   ROLES    AGE   VERSION   LABELS
k8s-master   Ready    <none>   25d   v1.18.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux
k8s-node1    Ready    <none>   25d   v1.18.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux
k8s-node2    Ready    <none>   25d   v1.18.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux,node=LAMP

截取资源清单文件相关部分:

  volumes:
    - name: mysql-persistent-storage
      persistentVolumeClaim:
        claimName: mysql-pvc #对应到pvc的名字
  nodeSelector:
    node: LAMP

这里说明一哈,比如kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,这个是kubernetes.io/arch架构相关的,因此,这个是没法使用的。而我们新建的标签是kubernetes.io/os级别,操作系统类的,因此可以使用。

(2)

亲和性pod调度

pod和node节点标签之间的定向调度

上面的定向调度还是比较粗糙的方式,因为如果我们设置了定向调度,但标签忘记打了,或者标签写错了,nodeSelector又设置了,那么部署将会变成pending。无疑,我们还是希望每次的部署都是成功的,因此,我们需要一种或者几种更为精细的pod调度。

a)

NodeAffinity(节点亲和性)

pod.spec.affinity.nodeAffinity
  requiredDuringSchedulingIgnoredDuringExecution  Node节点必须满足指定的所有规则才可以,相当于硬限制(找不到会调度失败)
    nodeSelectorTerms  节点选择列表
      matchFields   按节点字段列出的节点选择器要求列表
      matchExpressions   按节点标签列出的节点选择器要求列表(推荐)
        key    键
        values 值
        operator 关系符 支持Exists(存在), DoesNotExist(不存在), In(范围), NotIn(范围取反), Gt(大于), Lt(小于)
  preferredDuringSchedulingIgnoredDuringExecution 优先调度到满足指定的规则的Node,相当于软限制 (倾向,找不到不会调度失败)
    preference   一个节点选择器项,与相应的权重相关联
      matchFields   按节点字段列出的节点选择器要求列表
      matchExpressions   按节点标签列出的节点选择器要求列表(推荐)
        key    键
        values 值
        operator 关系符 支持In, NotIn, Exists, DoesNotExist, Gt, Lt
  weight 倾向权重,在范围1-100。

关系符operator的使用说明:

- matchExpressions:
  - key: nodeenv              # 匹配存在标签的key为nodeenv的节点,只匹配key就行
    operator: Exists
  - key: nodeenv              # 匹配标签的key为nodeenv,且value是"xxx"或"yyy"的节点,key和value都要匹配
    operator: In
    values: ["xxx","yyy"]
  - key: nodeenv              # 匹配标签的key为nodeenv,且value大于"xxx"的节点
    operator: Gt
    values: "xxx"

例子1:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.18
  tolerations:
  - operator: Exists
    effect: NoExecute
  nodeName: k8s-node2
  affinity:  #亲和性设置
    nodeAffinity: #申明是node亲和策略
      requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
        nodeSelectorTerms:
        - matchExpressions: # 匹配env的值在["web","dev"]中的标签,实际没有设置此标签,所以会匹配失败
          - key: node
            operator: In
            values: ["web","dev"]

这个亲和策略表示只要node标签里有web或者dev就可以成功部署此pod,否则,必定不能部署,现在先运行一哈,查看pod的状态,可以看到状态是NodeAffinity ,部署不成功:

[root@master coredns]# k get po -A -owide
NAMESPACE     NAME                       READY   STATUS         RESTARTS   AGE    IP               NODE         NOMINATED NODE   READINESS GATES
default       nginx                      0/1     NodeAffinity   0          18s    <none>           k8s-node2    <none>           <none>
kube-system   coredns-76648cbfc9-87fc7   1/1     Running        1          12h    10.244.0.17      k8s-master   <none>           <none>
kube-system   kube-flannel-ds-2jqg2      1/1     Running        0          111m   192.168.217.17   k8s-node1    <none>           <none>
kube-system   kube-flannel-ds-jd6p7      1/1     Running        0          111m   192.168.217.16   k8s-master   <none>           <none>
kube-system   kube-flannel-ds-k4qx9      1/1     Running        0          105m   192.168.217.18   k8s-node2    <none>           <none>

那么,现在就给node1设置标签值为web吧:

kubectl label nodes k8s-node1 node=dev

再次部署就会成功了。

例子2:

[root@master coredns]# cat nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeaffinity-preferred
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.18
  affinity:  #亲和性设置
    nodeAffinity: #设置node亲和性
      preferredDuringSchedulingIgnoredDuringExecution: # 软限制
      - weight: 1
        preference:
          matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有)
          - key: nodeenv
            operator: In
            values: ["3432","ewrew"]

这里设置的values是我随便乱写的,自然是随便调度到了某个节点,如果确实有,那自然会调度成功。

(3)

PodAffinity(Pod亲和性)

pod亲和性是相对pod来说的,比如,A pod已经在某个节点或者作用域运行了,现在B pod需要和A pod在同一个节点或者作用域运行,反亲和就是A pod不和B pod在同一个node或者作用域。

PodAffinity的可配置项:

pod.spec.affinity.podAffinity
  requiredDuringSchedulingIgnoredDuringExecution  硬限制
    namespaces       指定参照pod的namespace
    topologyKey      指定调度作用域
    labelSelector    标签选择器
      matchExpressions  按节点标签列出的节点选择器要求列表(推荐)
        key    键
        values 值
        operator 关系符 支持In, NotIn, Exists, DoesNotExist.
      matchLabels    指多个matchExpressions映射的内容
  preferredDuringSchedulingIgnoredDuringExecution 软限制
    podAffinityTerm  选项
      namespaces      
      topologyKey
      labelSelector
        matchExpressions  
          key    键
          values 值
          operator
        matchLabels 
    weight 倾向权重,在范围1-100
topologyKey用于指定调度时作用域,例如:
    如果指定为kubernetes.io/hostname,那就是以Node节点为区分范围
    如果指定为beta.kubernetes.io/os,则以Node节点的操作系统类型来区分
这些都是node节点的标签在管理,例如有的集群有beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64
也可能有arrch架构的操作系统
这里weight权重的作用是,一个pod节点可以有多个软策略,每个软策略可以有不同的权重,然后根据权重由高到选择不同软策略,直到选中符合条件的节点。如果设置了多个软策略,权重价值就体现出来了。比如张三节点权重为4,先看看三节点符不符合选中条件,不符合,再看权重为3的李四节点符不符合选中条件...直到找到符合选中条件的节点。也就是说,权重按值高低来确定,越高越优先

例子1:

有一个A pod,此pod有如下pod标签并设置了nodename:

  labels:
    podenv: pro #设置标签

硬策略B pod:

apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-required
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.18
  affinity:  #亲和性设置
    podAffinity: #设置pod亲和性
      requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
      - labelSelector:  #标签选择器
          matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签
          - key: podenv
            operator: In
            values: ["fdsfdsf","pro"]
        topologyKey: kubernetes.io/hostname   #调度作用域,即如果匹配到,就调度到目标pod同一节点上

上面配置表达的意思是:新Pod必须要与拥有标签podenv=fdsfdsf或者podenv=pro的pod在同一Node上

关于PodAffinity的 preferredDuringSchedulingIgnoredDuringExecution(软策略),这里不再演示,和硬策略基本一样。

(4)

PodAntiAffinity(Pod反亲和性)

PodAntiAffinity主要实现以运行的Pod为参照,让新创建的Pod跟参照pod不在一个区域中的功能。

它的配置方式和选项跟PodAffinty是基本一样的,只修改一个地方即可,其余的都一样

 affinity:  #亲和性设置
    podAntiAffinity: #设置pod亲和性

那么,符合条件的Apod将不会和Bpod部署到一起。




资源限制策略

资源限制策略指的是某些场景如节点 NotReady,或者某一个节点的硬件资源达到预设阈值后,节点内的pod就进入驱逐状态

硬件资源限制主要是有kube-controller-manager和kubelet这两个核心服务来进行的,也就是它们的配置文件来设定阈值的,一般kube-controller-manager是不做设定,主要是由kubelet设定。

以二进制安装的集群为例,在config文件内配置:

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
  - 10.0.0.2
clusterDomain: cluster.local
failSwapOn: false
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 2m0s
    enabled: true
  x509:
    clientCAFile: /opt/kubernetes/ssl/ca.pem
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110

关于硬驱逐的阈值, nodefs.available: 10%表示节点服务器剩余磁盘空间小于百分之10就触发,那么,现在在node1节点上有两个pod在运行:

[root@master cfg]# k get po -A -owide
NAMESPACE     NAME                         READY   STATUS    RESTARTS   AGE     IP               NODE         NOMINATED NODE   READINESS GATES
default       pod-nodeaffinity-preferred   1/1     Running   0          133m    10.244.1.16      k8s-node1    <none>           <none>
kube-system   coredns-76648cbfc9-z8kh5     1/1     Running   1          8h      10.244.1.9       k8s-node1    <none>           <none>
kube-system   kube-flannel-ds-99lsb        1/1     Running   1          6h42m   192.168.217.16   k8s-master   <none>           <none>
kube-system   kube-flannel-ds-w2kjl        1/1     Running   6          6h42m   192.168.217.17   k8s-node1    <none>           <none>
kube-system   kube-flannel-ds-xdm6r        1/1     Running   0          6h22m   192.168.217.18   k8s-node2    <none>           <none>

将nodefs.available: 10%修改为nodefs.available: 90%,然后在重启node1节点上的kubelet会发生什么呢?

答案是该节点的所有pod会转成Terminating状态,因为这个节点有一个coredns服务。

未完待续@@@@@@!!!!!!!!!!!!

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
4天前
|
存储 运维 Kubernetes
Kubernetes 集群的监控与维护策略
【4月更文挑战第23天】 在微服务架构日益盛行的当下,容器编排工具如 Kubernetes 成为了运维工作的重要环节。然而,随着集群规模的增长和复杂性的提升,如何确保 Kubernetes 集群的高效稳定运行成为了一大挑战。本文将深入探讨 Kubernetes 集群的监控要点、常见问题及解决方案,并提出一系列切实可行的维护策略,旨在帮助运维人员有效管理和维护 Kubernetes 环境,保障服务的持续可用性和性能优化。
|
3月前
|
Kubernetes 监控 调度
Kubernetes Pod调度:从基础到高级实战技巧
Kubernetes Pod调度:从基础到高级实战技巧
191 0
|
4月前
|
Kubernetes 负载均衡 Cloud Native
猿创征文|云原生|kubernetes二进制1.18单master扩展为多master
猿创征文|云原生|kubernetes二进制1.18单master扩展为多master
54 0
|
3月前
|
Kubernetes Cloud Native 调度
云原生技术专题 | 云原生容器编排问题盘点,总结分享年度使用Kubernetes的坑和陷阱
随着云原生的兴起,越来越多的应用选择基于Kubernetes进行部署,可以说Kubernetes 是最流行的容器编排和部署平台。它的强大功能特性,可以保障在生产中可靠地运行容器化应用程序,相关的DevOps等工具也应运而生,下面就是小编简单化了一个Kubernetes的逻辑架构图。
327 9
云原生技术专题 | 云原生容器编排问题盘点,总结分享年度使用Kubernetes的坑和陷阱
|
4月前
|
Kubernetes Cloud Native 应用服务中间件
云原生|kubernetes 你真的学废了吗---实战k8s 一(jsonpath实战)
云原生|kubernetes 你真的学废了吗---实战k8s 一(jsonpath实战)
67 0
|
2天前
|
存储 运维 Kubernetes
构建高效自动化运维体系:Ansible与Kubernetes的协同策略
【4月更文挑战第25天】 在当今快速迭代的软件开发过程中,自动化运维已成为提升效率、保证一致性和降低人为错误的关键。本文将探讨如何利用Ansible作为配置管理工具,以及Kubernetes作为容器编排系统,共同构建一个高效、可靠的自动化运维体系。文章首先概述了自动化运维的基本概念及其重要性,随后详细分析了Ansible与Kubernetes在自动化流程中的作用与优势,并通过一系列实践案例,展示了两者如何协同工作以优化部署、扩缩容和灾难恢复等关键运维任务。最后,文中还讨论了在实际应用中可能遇到的挑战及相应的解决策略,为读者提供了一套完整的自动化运维解决方案参考。
|
14天前
|
Kubernetes 监控 Cloud Native
构建高效云原生应用:基于Kubernetes的微服务治理实践
【4月更文挑战第13天】 在当今数字化转型的浪潮中,企业纷纷将目光投向了云原生技术以支持其业务敏捷性和可扩展性。本文深入探讨了利用Kubernetes作为容器编排平台,实现微服务架构的有效治理,旨在为开发者和运维团队提供一套优化策略,以确保云原生应用的高性能和稳定性。通过分析微服务设计原则、Kubernetes的核心组件以及实际案例,本文揭示了在多变的业务需求下,如何确保系统的高可用性、弹性和安全性。
17 4
|
1月前
|
Kubernetes Cloud Native Docker
【云原生】kubeadm快速搭建K8s集群Kubernetes1.19.0
Kubernetes 是一个开源平台,用于管理容器化工作负载和服务,提供声明式配置和自动化。源自 Google 的大规模运维经验,它拥有广泛的生态支持。本文档详细介绍了 Kubernetes 集群的搭建过程,包括服务器配置、Docker 和 Kubernetes 组件的安装,以及 Master 和 Node 的部署。此外,还提到了使用 Calico 作为 CNI 网络插件,并提供了集群功能的测试步骤。
219 0
|
1月前
|
Kubernetes 网络安全 调度
容器服务ACK常见问题之容器服务ACK的eci调度卡住如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
1月前
|
监控 Cloud Native 测试技术
云原生应用的持续交付与自动化测试策略
【2月更文挑战第30天】 在快速迭代和市场驱动的软件开发领域,云原生应用的持续交付(CD)已成为企业维持竞争力的关键手段。本文将详细探讨云原生环境中实现高效持续交付的策略,并深入分析自动化测试在此过程中的作用。我们将讨论如何通过容器化、微服务架构、以及声明式基础设施来优化部署流程,以及如何利用持续集成(CI)/持续部署(CD)管道中的质量关卡确保软件质量。此外,文中还将展示如何通过测试自动化框架和监控工具来提升测试覆盖率和准确性,最终实现缩短开发周期,降低风险,提高产品质量的目标。

热门文章

最新文章