Kubernetes高级调度2

一.Taint和Toleration

1.为什么使用taint

(1)不让pod被部署到被设置为污点的节点上。

(2)不让master节点部署业务,只部署系统组件

(3)除了指点pod外,不想让节点部署其他pod

2.为什么使用Toleration

        让被设置为污点的节点能部署pod

3.污点和容忍的基本概念

        Taint(污点)作用在节点上,能够是节点排斥一类特定的pod

        Toleration(容忍)作用在pod上,也就是可以兼容某类污点

        比如有一批GPU服务器只能部署要使用GPU的Pod。每个节点上都可以应用一个或多个Taint,这表示对于那些不能容忍这些Taint的Pod是不能部署在该服务器上的。如果Pod配置了Toleration,则表示这些Pod可以被调度到设置了Taint的节点上,当然没有设置Taint的节点也是可以部署的。

        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的节点上

        使用kubeadm部署的k8s集群,应用是不会调度到master节点上的。因为kubeadm部署的k8s集群默认为master节点添加了Taints(污点)

4.污点的使用

(1)创建污点语法

ku Taint node 节点名称 键=值:effect

(2)查看节点是否为污点

ku describe node 节点名 | grep Taints

(3)移除污点,只需在添加污点的命令后加一个“-”即可

ku Taint node 节点名 键=值:effect

每个污点有一个key和value作为污点的标签,其中value可以为空,effect描述污点的作用key=value:effect

(4)effect支持的选项

  • NoSchedule:表示k8s将不会将Pod调度到具有该污点的Node上,不会驱逐已存在该节点上的pod
  • PreferNoSchedule:表示k8s将尽量避免将pod调度到具有该污点的node上,不会驱逐已存在该节点上的pod
  • NoExecute:表示k8s将不会将pod调度到具有该污点的Node上,同时回将Node上已存在的Pod驱逐出去,若节点上设置了污点并用的是NoExecute策略,node节点上的pod会被全部驱逐,但是如果是Deployment和StatefulSet资源类型,为了维持副本数量则会在别的Node上创建新的pod

5.容忍的定义

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

6.示例

(1)设置污点

[root@k8s-master ~]# ku taint node node01 check=mycheck:NoSchedule
node/node01 tainted
[root@k8s-master ~]# ku taint node node02 check=mycheck:NoSchedule
node/node02 tainted

(2)创建测试模版

[root@k8s-master ~]# vim pod1.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01
spec:
  containers:
  - name: with-node-affinity
    image: nginx:1.7.9

(3)运行

[root@k8s-master ~]# ku create -f pod1.yaml 
pod/myapp01 created

(4)查看pod

[root@k8s-master ~]# ku get pod -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
myapp01   0/1     Pending   0          22s   <none>   <none>   <none>           <none>

备注:因为设置了污点,在查看到的NODE字段上值为<none>,并每一节点对应的名称

(5)修改测试模版(为pod1添加容忍)

[root@k8s-master ~]# vim pod2.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01
spec:
  containers:
  - name: with-node-affinity
    image: nginx:1.7.9
  tolerations:
  - key: check
    operator: Equal
    value: mycheck
    effect: NoSchedule
    #tolerationSeconds: 60

备注:当effect为NoExecute时可以设置TolerationSeconds用于描述当Pod需要被驱逐时可以在Node上继续保留运行的时间,即60秒后该pod会被驱逐掉,默认的是一天。

在pod中定义容忍度说明

(6) 运行pod

[root@k8s-master ~]# ku create -f pod2.yaml 
pod/myapp01 created

(7)查看运行结果

[root@k8s-master ~]# ku get pod -o wide 
NAME      READY   STATUS    RESTARTS   AGE   IP              NODE     NOMINATED NODE   READINESS GATES
myapp01   1/1     Running   0          9s    10.244.140.92   node02   <none>           <none>

(8)取消污点

[root@k8s-master ~]# ku taint node node01 check=mycheck:NoSchedule-
node/node01 untainted
[root@k8s-master ~]# ku taint node node02 check=mycheck:NoSchedule-
node/node02 untainted

[root@k8s-master ~]# ku describe node node02 | grep Taint
Taints:             <none>
[root@k8s-master ~]# ku describe node node01 | grep Taint
Taints:             <none>

7.多污点和多容忍配置

        系统允许在同一个node上设置多个taint,也可以在pod上设置多个Toleration

        Kubernetes调度器处理多个Taint和Toleration能够匹配的部分,剩下的没有忽略掉的Taint就是对Pod的效果了。下面是儿种特殊情况

  • 如果剩余的Taint中存在effect=NoSchedule,则调度器不会把该pod调度到这一节点上。
  • 如果剩余的Taint中没有NoSchedule的效果,但是有PreferNoSchedule效果,则调度器会尝试不会将pod指派给这个节点。        
  • 如果剩余Taint的效果有NoExecute的,并且这个pod已经在该节点运行,则会被驱逐;如果没有在该节点运行,也不会再被调度到该节点上。

        ubecti taint nodesK8nodeke       L:NoSchedule
        kubectl taint nodes k8s-node1 keyl=valuel:NoExecute
        kubectl taint nodes k8s-node1 key2=value2:NoSchedule
    去除污点:
        kubectl taint nodes k8s-node1 keyl=valuel:NoSchedule
        kubectl taint nodes k8s-node1 keyl=valuel:NoExecute-
        ubecttaintodes 8         key2=value2:Noschedule 

二.警戒(cordon)和转移(drain)

1.警戒

(1)警戒是指将Node标记为不可调度的状态

(2)设置警戒(node01)

[root@k8s-master ~]# ku cordon node01
node/node01 cordoned

(3)查看警戒(node将会变成SchedulingDisabled)

[root@k8s-master ~]# ku get node
NAME         STATUS                     ROLES                  AGE   VERSION
k8s-master   Ready                      control-plane,master   9d    v1.23.0
node01       Ready,SchedulingDisabled   <none>                 9d    v1.23.0
node02       Ready                      <none>                 9d    v1.23.0

(4)取消警戒

[root@k8s-master ~]# ku uncordon  node01
node/node01 uncordoned

[root@k8s-master ~]# ku get node
NAME         STATUS   ROLES                  AGE   VERSION
k8s-master   Ready    control-plane,master   9d    v1.23.0
node01       Ready    <none>                 9d    v1.23.0
node02       Ready    <none>                 9d    v1.23.0

2.驱逐(转移)pod

        kubectl drain 可以让Node节点开始释放所有pod,并且不接收新的pod进程。drain本意排水,意思是将出问题的Node下的Pod转移到其他Node下运行

[root@k8s-master ~]# ku drain node02 --ignore-daemonsets --delete-local-data --force

Flag --delete-local-data has been deprecated, This option is deprecated and will be deleted. Use --delete-emptydir-data.
node/node02 cordoned
WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: default/myapp01; ignoring DaemonSet-managed Pods: kube-system/calico-node-dzh75, kube-system/kube-proxy-52t4l
evicting pod kube-system/coredns-6d8c4cb4d-tl7gc
evicting pod kubernetes-dashboard/dashboard-metrics-scraper-7fcdff5f4c-wcddq
evicting pod kube-system/metrics-server-66bdc46d86-p5rsg
evicting pod default/myapp01
pod/myapp01 evicted
pod/dashboard-metrics-scraper-7fcdff5f4c-wcddq evicted
pod/metrics-server-66bdc46d86-p5rsg evicted
pod/coredns-6d8c4cb4d-tl7gc evicted
node/node02 drained

执行上述操作:节点会被设置为警戒状态(cordon),evict(驱逐)了Pod 

备注:

--ignore-daemonsets:无视Daemonset管理下的Pod

--delete-local-data:如果有mount local volume的pod,会强制杀掉该pod

--force:强制释放不是控制器管理的pod,例如Kube-proxy

3.取消警戒(做了转移后节点会进入警戒状态)

[root@k8s-master ~]# ku uncordon node02
node/node02 uncordoned
[root@k8s-master ~]# ku get node
NAME         STATUS   ROLES                  AGE   VERSION
k8s-master   Ready    control-plane,master   9d    v1.23.0
node01       Ready    <none>                 9d    v1.23.0
node02       Ready    <none>                 9d    v1.23.0

三. k8s亲和性和非亲和性

1.亲和性调度可以分成软策略和硬策略两种

  • 硬策略:可以理解为必须,就是如果没有满足条件的节点的话,就不断重试直到满足条件为止。对应的配置规则为requiredDuringSchedulingIgnoredDuringExecution。
  • 软策略:可以理解为尽量,就是如果没有满足调度要求的节点的话,pod就会忽略这条规则,继续完成调度的过程,即:满足条件最好,不满足也无所谓。对应的配置规则为preferredDuringSchedulingIgnoredDuringExecution。

2.亲和性的配置规则

分为Node亲和,Pod亲和,Pod反亲和:

  • nodeAffinity:节点亲和性,用来控制Pod要部署在哪些节点上,以及不能部署在哪些节点上,这个是Pod与Node之间的匹配规则
  • PodAffinity:Pod亲和性,这个是Pod与Pod之间匹配规则的。
  • PodAntiAffinity:Pod反亲和性,与PodAffinity相反,用来指定Pod不要部署到哪些节点

备注:

        节点的亲和性通过pod.spec.affinity.nodeAffinity字段定义,支持使用matchExpressions属性构建更为复杂的标签选择器。         

3.Node节点亲和

节点亲和分为节点硬亲和节点软亲和

 节点硬亲和性实验

(1)设置节点标签

        首先对两个node加标签,设置两个node标签分别为node01和node02。

        加标签的语法:kubectl label Nodes 节点名称 标签键=标签值

[root@k8s-master ~]# ku label node node01 type=node01

[root@k8s-master ~]# ku label node node02 type=node02

(2)查看节点标签

[root@k8s-master ~]# ku get node --show-labels;

NAME         STATUS   ROLES                  AGE   VERSION   LABELS
k8s-master   Ready    control-plane,master   9d    v1.23.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
node01       Ready    <none>                 9d    v1.23.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux,type=node01
node02       Ready    <none>                 9d    v1.23.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux,type=node02

(3)设置pod亲和性为type=node01

[root@k8s-master ~]# vim test01.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: pod01
spec:
  #亲和性调度
  affinity:
    #节点亲和性调度
    nodeAffinity:
      #亲和策略:节点硬亲和
      requiredDuringSchedulingIgnoredDuringExecution:
        #指定亲和性  
        nodeSelectorTerms:
        - matchExpressions:
          - {key: type, operator: In, values: ["node01"]}
  containers:
    - name: pod01
      image: nginx:1.7.9

(4)部署pod并查看其信息

[root@k8s-master ~]# ku create -f test01.yaml 
pod/pod01 created

[root@k8s-master ~]# ku get pod pod01 -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
pod01   1/1     Running   0          24s   10.244.196.151   node01   <none>           <none>

也可以将{key: type, operator: In, values: ["node01"]}的node01改为node02,让其pod部署到node02节点上

[root@k8s-master ~]# ku create -f test02.yaml 
pod/pod02 created

[root@k8s-master ~]# ku get pod pod02 -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP              NODE     NOMINATED NODE   READINESS GATES
pod02   1/1     Running   0          20s   10.244.140.93   node02   <none>           <none>

节点软亲和性实验

        节点软亲和性为节点选择提供了一种柔性的控制器逻辑,当条件满足时,也能够接受被编排在其他不符合条件的节点之上。同时他为每种倾向性提供了weight属性以便用于自定义优先级,范围时1-100,越大越优先。但是在节点软亲和并不适用,而是按照节点的先后顺序部署。

(1)为pod设置软亲和

[root@k8s-master ~]# vim test03.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: pod03
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 60
          preference:
            matchExpressions:
            - {key: type, operator: In, values: ["node02"]}
        - weight: 90
          preference:
            matchExpressions:
            - {key: tpye, operator: In, values: ["node01"]}
  containers:
    - name: pod03
      image: nginx:1.7.9

(2)创建pod并查看其部署情况

[root@k8s-master ~]# ku create -f test03.yaml 
pod/pod03 created

[root@k8s-master ~]# ku get pod pod03 -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP              NODE     NOMINATED NODE   READINESS GATES
pod03   1/1     Running   0          10s   10.244.140.94   node02   <none>           <none>

备注:可以发现pod被部署到了node02上,并没有被部署到权重为90的node01上,所以权重对于节点软亲和并不适用。

4.pod亲和性

         出于某些需求,将一些Pod对象组织在相近的位置(同一个节点,机架,区域等)此时这些Pod对象间的关系为Pod亲和性。

        Pod的亲和性调度也存在硬软/亲和性的区别,它们表示的约束意义同节点亲和性相似。

Pod硬亲和性

        Pod硬亲和性调度也使用  requiredDuringSchedulingIgnoredDuringExecution  属性进行定义

        首先创建两个基础Pod,并对它打标签,分别部署到node01和node02上

(1)部署第一个基础Pod(标签pod04,节点node01)

[root@k8s-master ~]# vim test04.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: pod04
  labels:
    app: pod04
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - {key: type, operator: In, values: ["node01"]}
  containers:
    - name: pod04
      image: nginx:1.7.9


[root@k8s-master ~]# ku create -f test04.yaml 
pod/pod04 created

[root@k8s-master ~]# ku get pod pod04 -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
pod04   1/1     Running   0          17s   10.244.196.152   node01   <none>           <none>

(2)部署第二个基础Pod (标签pod05,节点node02)

[root@k8s-master ~]# vim test05.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: pod05
  labels:
    app: pod05
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - {key: type, operator: In, values: ["node02"]}
  containers:
    - name: pod05
      image: nginx:1.7.9

[root@k8s-master ~]# ku create -f test05.yaml 
pod/pod05 created

[root@k8s-master ~]# ku get pod pod05 -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP              NODE     NOMINATED NODE   READINESS GATES
pod05   1/1     Running   0          5s    10.244.140.95   node02   <none>           <none>

(3)创建亲和Pod05的Pod

[root@k8s-master ~]# vim test06.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: pod06
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: app, operator: In, values: ["pod05"]}
        topologyKey: kubernetes.io/hostname
  containers:
  - name: pod06
    image: nginx:1.7.9

注意:

matchExpressions的values值为Pod的标签。是哪个Pod的标签,就亲和到那个Pod所在的弄的节点

(4)部署此pod (并查看所在节点)

[root@k8s-master ~]# ku create -f test06.yaml 
pod/pod06 created

[root@k8s-master ~]# ku get pod pod06 pod05 -o wide
NAME    READY   STATUS    RESTARTS   AGE     IP              NODE     NOMINATED NODE   READINESS GATES
pod06   1/1     Running   0          93s     10.244.140.96   node02   <none>           <none>
pod05   1/1     Running   0          7m35s   10.244.140.95   node02   <none>           <none>

此时pod05和pod06在同一个节点

Pod软亲和 

 Pod软亲和和node软亲和使用方法类似

(1)编写pod7的pod

[root@k8s-master ~]# vim test07.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: pod07
spec:
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 20
        podAffinityTerm:
          labelSelector:
            matchExpressions:
              - {key: app, operator: In, values: ["pod05"]}
          topologyKey: kubernetes.io/hostname
      - weight: 80
        podAffinityTerm:
          labelSelector:
            matchExpressions:
              - {key: app, operator: In, values: ["pod04"]}
          topologyKey: kubernetes.io/hostname
  containers:
    - name: pod07
      image: nginx:1.7.9

注释:
 values:["pod05"]是pod5的pod的标签
 values:["pod04"]是pod04的pod的标签
正则匹配了pod的标签“pod04”,带有pod4标签的pod是pod04,该pod在node1上,于是pod07的pod也调度到了node01上。
注意:
node软亲和中的权重值不影响pod的调度,谁在前面,就亲和谁。
pod软亲和中的权重值是会影响调度到的节点的,pod软亲和中谁的权重高就调度到谁那里

(2)创建并查看所在节点

[root@k8s-master ~]# ku create -f test07.yaml 
pod/pod07 created

[root@k8s-master ~]# ku get pod pod07 pod05 pod04 -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
pod07   1/1     Running   0          19s   10.244.196.153   node01   <none>           <none>
pod05   1/1     Running   0          15m   10.244.140.95    node02   <none>           <none>
pod04   1/1     Running   0          16m   10.244.196.152   node01   <none>           <none>

 5.Pod反亲和

Pod反亲和就是不亲和该Pod所在的节点

(1)编写反亲和文件(反亲和node05)

[root@k8s-master ~]# vim test09.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: pod09
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: app, operator: In, values: ["pod05"]}
        topologyKey: kubernetes.io/hostname
  containers:
  - name: test09
    image: nginx:1.7.9

(2)创建反亲和并查看

[root@k8s-master ~]# ku create -f test09.yaml 
pod/pod09 created
[root@k8s-master ~]# ku get pod pod09 pod05 pod04 -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
pod09   1/1     Running   0          19s   10.244.196.154   node01   <none>           <none>
pod05   1/1     Running   0          22m   10.244.140.95    node02   <none>           <none>
pod04   1/1     Running   0          23m   10.244.196.152   node01   <none>           <none>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值