Node节点亲和性,Pod节点亲和性,污点和容忍度测试

####Node节点亲和性####

查看资源类型help
kubectl explain pods.spec.affinity

Node节点选择器
创建pod.yaml
指定nodeName/nodeSelector
spec:
  nodeName: Node1

spec:
  nodeSelector:
    disk:ceph  //需要给node打标签    

#查看全部node节点包含指定标签的node
kubectl  get nodes -l "zone=bar"
#添加node标签
kubectl label nodes node01 disk=ceph
#删除label
kubectl label nodes node01     disk-
#修改label的值
kubectl label nodes node01 disk-ceph2 --overwrite
#查看全部node标签
kubectl get node --show-labels
#查看指定node节点标签
kubectl get nodes node01 --show-labels


污点和容忍度
    node节点亲和性:kubectl explain  pods.spec.affinity.nodeAffinity
    preferredDuringSchedulingIgnoredDuringExecution //表示有节点尽量满足这个位置定义的亲和性,这不是一个必须的条件,软亲和性
    requiredDuringSchedulingIgnoredDuringExecution  //表示必须有节点满足这个位置定义的亲和性,这是个硬性条件,硬亲和性
    
硬亲和性 //kubectl explain  pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms
我们检查当前节点中有任意一个节点拥有zone标签的值是foo或者bar,就可以把pod调度到这个node节点的foo或者bar标签上的节点上    
[root@master01 yaml]# cat pod-nodeaffinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
        name: pod-node-affinity-demo
        namespace: default
        labels:
            app: myapp
            tier: frontend
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
    affinity:
        nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
                   nodeSelectorTerms:
                   - matchExpressions:
                     - key: zone
                       operator: In
                       values:
                       - foo
                       - bar


软亲和性 //kubectl explain  pods.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution
即使node没有标签也是会调度的
[root@master01 yaml]# cat pod-nodeaffinity-demo-2.yaml
apiVersion: v1
kind: Pod
metadata:
        name: pod-node-affinity-demo-2
        namespace: default
        labels:
            app: myapp
            tier: frontend
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
    affinity:
        nodeAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
            - preference:
               matchExpressions:
               - key: zone1
                 operator: In
                 values:
                 - foo1
                 - bar1
              weight: 60


####Pod节点亲和性####
pod自身的亲和性调度有两种表示形式 (Pod需要labelSelector)
podaffinity:pod和pod更倾向腻在一起,把相近的pod结合到相近的位置,如同一区域,同一机架,这样的话pod和pod之间更好通信,比方说有两个机房,这两个机房部署的集群有1000台主机,那么我们希望把nginx和tomcat都部署同一个地方的node节点上,可以提高通信效率;
podunaffinity:pod和pod更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响。
kubectl explain pods.spec.affinity.podAffinity

requiredDuringSchedulingIgnoredDuringExecution: 硬亲和性
preferredDuringSchedulingIgnoredDuringExecution:软亲和性

例1:pod节点亲和性
定义两个pod,第一个pod做为基准,第二个pod跟着它走
[root@master01 yaml]# cat pod-required-affinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  labels:
    app2: myapp2
    tier: frontend
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  labels:
    app: backend
    tier: db
spec:
    containers:
    - name: busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sh","-c","sleep 3600"]
    affinity:
      podAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
         - labelSelector:
              matchExpressions:
              - {key: app2, operator: In, values: ["myapp2"]}
           topologyKey: kubernetes.io/hostname

[root@master01 yaml]# kubectl  get pod -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
pod-first    1/1     Running   0          10s   100.95.185.204   node02   <none>           <none>
pod-second   1/1     Running   0          10s   100.95.185.205   node02   <none>           <none>

例2:pod节点反亲和性
定义两个pod,第一个pod做为基准,第二个pod跟它调度节点相反
[root@master01 yaml]# cat pod-required-anti-affinity-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  labels:
    app1: myapp1
    tier: frontend
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  labels:
    app: backend
    tier: db
spec:
    containers:
    - name: busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sh","-c","sleep 3600"]
    affinity:
      podAntiAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
         - labelSelector:
              matchExpressions:
              - {key: app1, operator: In, values: ["myapp1"]}
           topologyKey: kubernetes.io/hostname

#例3. 修改 topologykey (第一个pod调度到zone标签节点后,第二个pod无法调度zone标签节点)
kubectl label nodes  node1  zone=foo
kubectl label nodes  node2  zone=foo --overwrite

[root@master01 yaml]# cat pod-first-required-anti-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  labels:
    app3: myapp3
    tier: frontend
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1

[root@master01 yaml]# cat pod-second-required-anti-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  labels:
    app: backend
    tier: db
spec:
    containers:
    - name: busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sh","-c","sleep 3600"]
    affinity:
      podAntiAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
         - labelSelector:
              matchExpressions:
              - {key: app3 ,operator: In, values: ["myapp3"]}
           topologyKey:  zone
           
           
第二个节点现是pending,因为两个节点是同一个位置,现在没有不是同一个位置的了,而且我们要求反亲和性,所以就会处于pending状态,如果在反亲和性这个位置把required改成preferred,那么也会运行。
podaffinity:pod节点亲和性,pod倾向于哪个pod
nodeaffinity:node节点亲和性,pod倾向于哪个node


####污点和容忍度####
给了节点选择的主动权,节点打一个污点,不容忍的pod就运行不上来,污点就是定义在节点上的键值属性数据,可以定决定拒绝那些pod;
taints是键值数据,用在节点上,定义污点;
tolerations是键值数据,用在pod上,定义容忍度,能容忍哪些污点
pod亲和性是pod属性;但是污点是节点的属性,污点定义在nodeSelector上
kubectl explain node.spec.taints

[root@master01 yaml]# kubectl  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.

taints的effect用来定义对pod对象的排斥等级(效果):
NoSchedule:
仅影响pod调度过程,当pod能容忍这个节点污点,就可以调度到当前节点,后来这个节点的污点改了,加了一个新的污点,使得之前调度的pod不能容忍了,那这个pod会怎么处理,对现存的pod对象不产生影响

NoExecute:
既影响调度过程,又影响现存的pod对象,如果现存的pod不能容忍节点后来加的污点,这个pod就会被驱逐

PreferNoSchedule:
最好不,也可以,是NoSchedule的柔性版本

在pod对象定义容忍度的时候支持两种操作:
1.等值密钥:key和value上完全匹配
2.存在性判断:key和effect必须同时匹配,value可以是空
在pod上定义的容忍度可能不止一个,在节点上定义的污点可能多个,需要逐个检查容忍度和污点能否匹配,每一个污点都能被容忍,才能完成调度,如果不能容忍怎么办,那就需要看pod的容忍度了

管理节点污点
[root@xianchaomaster1]# kubectl taint –help

例1:把node02当成是生产环境专用的,其他node是测试的
kubectl  taint node node02 node-type=production:NoSchedule   //执行前的运行的pod不影响,再次新建pod如不添加污点无法调度成功。

例2: node01 污点 kubectl taint node node01 node-type=dev:NoExecute //node01 当前存在的pod全部驱逐
[root@master01 yaml]# kubectl get pod -o wide
NAME         READY   STATUS        RESTARTS   AGE   IP                NODE     NOMINATED NODE   READINESS GATES
pod-first    1/1     Running       0          97m   100.95.185.207    node02   <none>           <none>
pod-second   0/1     Terminating   1          96m   100.117.144.133   node01   <none>           <none>


[root@master01 yaml]# cat pod-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-deploy
  namespace: default
  labels:
    app: myapp
    release: canary
spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - key: "node-type"
        operator: "Equal"
        value: "production"
        effect: "NoExecute"
        tolerationSeconds: 3600



[root@master01 yaml]# kubectl get pod
NAME           READY   STATUS    RESTARTS   AGE
myapp-deploy   0/1     Pending   0          2m6s
pod-first      1/1     Running   0          102m
 
Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 1 node(s) had taint {node-type: dev}, that the pod didn't tolerate, 1 node(s) had taint {node-type: production}, that the pod didn't tolerate.
Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 1 node(s) had taint {node-type: dev}, that the pod didn't tolerate, 1 node(s) had taint {node-type: production}, that the pod didn't tolerate.

还是显示pending,因为我们使用的是equal(等值匹配),所以key和value,effect必须和node节点定义的污点完全匹配才可以,把上面配置effect: "NoExecute"变成
effect: "NoSchedule"成;
tolerationSeconds: 3600这行去掉

修改后正常启动yaml
[root@master01 yaml]# cat pod-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-deploy
  namespace: default
  labels:
    app: myapp
    release: canary
spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - key: "node-type"
        operator: "Equal"
        value: "production"
        effect: "NoSchedule"

例3:再次修改(只要对应的键是存在的,exists,其值被自动定义成通配符)
apiVersion: v1
kind: Pod
metadata:
  name: myapp-deploy
  namespace: default
  labels:
    app: myapp
    release: canary
spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - key: "node-type"
        operator: "Exists"
        value: ""
        effect: "NoSchedule"
        
例4:再次修改(有一个node-type的键,不管值是什么,不管是什么效果,都能容忍)
[root@master01 yaml]# cat pod-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-deploy
  namespace: default
  labels:
    app: myapp
    release: canary
spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - key: "node-type"
        operator: "Exists"
        value: ""
        effect: ""

删除污点
[root@master01 yaml]# kubectl taint nodes node01 node-type:NoExecute-
node/node01 untainted
[root@master01 yaml]# kubectl taint nodes node02 node-type-
node/node02 untainted

https://www.cnblogs.com/cheyunhua/p/15899059.html

posted @ 2022-02-08 13:46  NeilyoX  阅读(487)  评论(0)    收藏  举报