Pod亲和与反亲和、污点与容忍、驱逐

一、Pod调度

1.1、Pod调度流程

1.2、nodeSelector简介

nodeSelector 基于node标签选择器, 将pod调度的指定的目的节点上。
https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node/

可用于基于服务类型干预Pod调度结果, 如对磁盘I/O要求高的pod调度到SSD节点, 对内存要求比较高的pod调度的内存较高的节点。

也可以用于区分不同项目的pod, 如将node添加不同项目的标签, 然后区分调度。

[root@easzlab-deploy Affinit-case]# kubectl describe node 172.16.88.157
Name:               172.16.88.157
Roles:              master
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=172.16.88.157
                    kubernetes.io/os=linux
                    kubernetes.io/role=master
Annotations:        node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Tue, 18 Oct 2022 17:08:10 +0800
Taints:             node.kubernetes.io/unschedulable:NoSchedule
Unschedulable:      true
Lease:
  HolderIdentity:  172.16.88.157
  AcquireTime:     <unset>
  RenewTime:       Thu, 27 Oct 2022 10:47:06 +0800
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Wed, 19 Oct 2022 22:11:11 +0800   Wed, 19 Oct 2022 22:11:11 +0800   CalicoIsUp                   Calico is running on this node
  MemoryPressure       False   Thu, 27 Oct 2022 10:47:08 +0800   Tue, 18 Oct 2022 17:08:10 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Thu, 27 Oct 2022 10:47:08 +0800   Tue, 18 Oct 2022 17:08:10 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Thu, 27 Oct 2022 10:47:08 +0800   Tue, 18 Oct 2022 17:08:10 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Thu, 27 Oct 2022 10:47:08 +0800   Wed, 19 Oct 2022 22:09:58 +0800   KubeletReady                 kubelet is posting ready status. AppArmor enabled
Addresses:
  InternalIP:  172.16.88.157
  Hostname:    172.16.88.157
Capacity:
  cpu:                2
  ephemeral-storage:  49869532Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             4026076Ki
  pods:               500
Allocatable:
  cpu:                2
  ephemeral-storage:  45959760616
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3718876Ki
  pods:               500
System Info:
  Machine ID:                 1a19d04d6cc141e58368dc5dcc39f1a9
  System UUID:                8f09cdfe-374c-4faf-b9f2-78f0d9d3bd9a
  Boot ID:                    d7c79d7f-c664-44a6-9d03-0bf4ad6db51b
  Kernel Version:             5.4.0-128-generic
  OS Image:                   Ubuntu 20.04.4 LTS
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  containerd://1.6.4
  Kubelet Version:            v1.24.2
  Kube-Proxy Version:         v1.24.2
PodCIDR:                      10.200.1.0/24
PodCIDRs:                     10.200.1.0/24
Non-terminated Pods:          (1 in total)
  Namespace                   Name                 CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                 ------------  ----------  ---------------  -------------  ---
  kube-system                 calico-node-xh79g    250m (12%)    0 (0%)      0 (0%)           0 (0%)         8d
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                250m (12%)  0 (0%)
  memory             0 (0%)      0 (0%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-1Gi      0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%)
Events:              <none>
[root@easzlab-deploy Affinit-case]# 

1.3、nodeSelector调度

#为node节点打标签:
[root@easzlab-deploy Affinit-case]# kubectl label node 172.16.88.160 project="magedu"
node/172.16.88.160 labeled
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl label node 172.16.88.160 disktype="ssd"
node/172.16.88.161 labeled
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl get node --show-labels=true
NAME            STATUS                     ROLES    AGE   VERSION   LABELS
172.16.88.157   Ready,SchedulingDisabled   master   8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.157,kubernetes.io/os=linux,kubernetes.io/role=master
172.16.88.158   Ready,SchedulingDisabled   master   8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.158,kubernetes.io/os=linux,kubernetes.io/role=master
172.16.88.159   Ready,SchedulingDisabled   master   8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.159,kubernetes.io/os=linux,kubernetes.io/role=master
172.16.88.160   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.160,kubernetes.io/os=linux,kubernetes.io/role=node,project=magedu
172.16.88.161   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.161,kubernetes.io/os=linux,kubernetes.io/role=node
172.16.88.162   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.162,kubernetes.io/os=linux,kubernetes.io/role=node
172.16.88.163   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.163,kubernetes.io/os=linux,kubernetes.io/role=node
172.16.88.164   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.164,kubernetes.io/os=linux,kubernetes.io/role=node
172.16.88.165   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.165,kubernetes.io/os=linux,kubernetes.io/role=node
[root@easzlab-deploy Affinit-case]# 

#将pod调度到目的node, yaml文件中指定的key与value必须精确匹配:
[root@easzlab-deploy Affinit-case]# vi case1-nodeSelector.yaml 
[root@easzlab-deploy Affinit-case]# cat case1-nodeSelector.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 4
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine 
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 1
            memory: "512Mi"
          requests:
            cpu: 500m
            memory: "512Mi"
      nodeSelector:
        project: magedu
        disktype: ssd
[root@easzlab-deploy Affinit-case]# kubectl apply -f case1-nodeSelector.yaml 
deployment.apps/magedu-tomcat-app2-deployment created
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          3d20h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          44h     10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-75d7bb596c-n2c2s   1/1     Running   0          11m     10.200.40.212    172.16.88.160   <none>           <none>
magedu-tomcat-app2-deployment-75d7bb596c-pk2c2   1/1     Running   0          11m     10.200.40.214    172.16.88.160   <none>           <none>
magedu-tomcat-app2-deployment-75d7bb596c-pvf8c   1/1     Running   0          11m     10.200.40.215    172.16.88.160   <none>           <none>
magedu-tomcat-app2-deployment-75d7bb596c-z7klc   1/1     Running   0          11m     10.200.40.213    172.16.88.160   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

指定节点创建

[root@easzlab-deploy Affinit-case]# vi case2-nodename.yaml 
[root@easzlab-deploy Affinit-case]# cat case2-nodename.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      nodeName: 172.16.88.161
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine 
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 1
            memory: "512Mi"
          requests:
            cpu: 500m
            memory: "512Mi"
[root@easzlab-deploy Affinit-case]# kubectl apply -f case2-nodename.yaml 
deployment.apps/magedu-tomcat-app2-deployment configured
[root@easzlab-deploy Affinit-case]#
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          3d20h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          44h     10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-756bb8b58b-xcd5f   1/1     Running   0          49s     10.200.233.116   172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]#

二、node节点亲和性

affinity是Kubernetes 1.2版本后引入的新特性, 类似于nodeSelector, 允许使用者指定一些Pod在Node间调度的约束, 目前支持两种形式:

  • requiredDuringSchedulingIgnoredDuringExecution #必须满足pod调度匹配条件, 如果不满足则不进行调度
  • preferredDuringSchedulingIgnoredDuringExecution #倾向满足pod调度匹配条件, 不满足的情况下会调度的不符合条件的Node上
  • IgnoreDuringExecution表示如果在Pod运行期间Node的标签发生变化, 导致亲和性策略不能满足, 也会继续运行当前的Pod。
  • Affinity与anti-affinity的目的也是控制pod的调度结果, 但是相对于nodeSelector, Affinity(亲和)与anti-affinity(反亲和)的功能更加强大

affinity与nodeSelector对比:
1、亲和与反亲和对目的标签的选择匹配不仅仅支持and, 还支持In、 NotIn、 Exists、 DoesNotExist、 Gt、 Lt。

  • In: 标签的值存在匹配列表中(匹配成功就调度到目的node, 实现node亲和)
  • NotIn: 标签的值不存在指定的匹配列表中(不会调度到目的node, 实现反亲和)
  • Gt: 标签的值大于某个值(字符串)
  • Lt: 标签的值小于某个值(字符串)
  • Exists: 指定的标签存在

2、可以设置软匹配和硬匹配, 在软匹配下, 如果调度器无法匹配节点, 仍然将pod调度到其它不符合条件的节点。
3、还可以对pod定义亲和策略, 比如允许哪些pod可以或者不可以被调度至同一台node。
注:

  • 如果定义一个nodeSelectorTerms(条件)中通过一个matchExpressions基于列表指定了多个operator条件, 则只要满足其中一个条件, 就会被调度到相应的节点上, 即or的关系, 即如果nodeSelectorTerms下面有多个条件的话, 只要满足任何一个条件就可以了。
  • 如果定义一个nodeSelectorTerms中都通过一个matchExpressions(匹配表达式)指定key匹配多个条件, 则所有的目的条件都必须满足才会调度到对应的节点, 即and的关系, 即果matchExpressions有多个选项的话, 则必须同时满足所有这些条件才能正常调度。

2.1、硬亲和-nodeAffinity-requiredDuring-matchExpressions-1

affinity:
 nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
  nodeSelectorTerms:
  - matchExpressions: #匹配条件1,有一个key但是有多个values、 则只要匹配成功一个value就可以调度
   - key: disktype
     operator: In
     values:
     - ssd #只有一个value是匹配成功也可以调度
     - xxx
  - matchExpressions: #匹配条件2,多个matchExpressions加上以及每个matchExpressions 有一个key及多个values只有其中一个value匹配成功就可以调度
   - key: project
     operator: In
     values:
     - mmm #即使这俩条件都匹配不上也可以调度, 即多个matchExpressions只要有任意一个能匹配任何一个value就可以调用。
     - nnn

验证测试

[root@easzlab-deploy Affinit-case]# vi case3-1.1-nodeAffinity-requiredDuring-matchExpressions.yaml 
[root@easzlab-deploy Affinit-case]# cat case3-1.1-nodeAffinity-requiredDuring-matchExpressions.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 5
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions: #匹配条件1,有一个key但是有多个values、则只要匹配成功一个value就可以调度 
              - key: disktype
                operator: In
                values:
                - ssd # 只有一个value是匹配成功也可以调度
                - xxx
            - matchExpressions: #匹配条件1,有一个key但是有多个values、则只要匹配成功一个value就可以调度 
              - key: project
                operator: In
                values:
                - mmm  #即使这俩条件都匹配不上也可以调度,即多个matchExpressions只要有任意一个能匹配任何一个value就可以调用。
                - nnn

[root@easzlab-deploy Affinit-case]# kubectl apply -f case3-1.1-nodeAffinity-requiredDuring-matchExpressions.yaml 
deployment.apps/magedu-tomcat-app2-deployment configured
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          3d20h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          45h     10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-555df55d49-4qfkc   1/1     Running   0          25s     10.200.233.122   172.16.88.161   <none>           <none>
magedu-tomcat-app2-deployment-555df55d49-89psp   1/1     Running   0          28s     10.200.40.216    172.16.88.160   <none>           <none>
magedu-tomcat-app2-deployment-555df55d49-8trjm   1/1     Running   0          25s     10.200.40.218    172.16.88.160   <none>           <none>
magedu-tomcat-app2-deployment-555df55d49-h6rrn   1/1     Running   0          28s     10.200.233.120   172.16.88.161   <none>           <none>
magedu-tomcat-app2-deployment-555df55d49-slkm8   1/1     Running   0          28s     10.200.40.217    172.16.88.160   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

2.2、硬亲和-nodeAffinity-requiredDuring-matchExpressions-2

affinity:
 nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
   nodeSelectorTerms:
   - matchExpressions: #匹配条件1, 同一个key的多个value只有有一个匹配成功就认为当前key匹配成功
    - key: disktype
      operator: In
      values:
      - ssd
      - hdd
    - key: project #匹配条件2, 当前key也要匹配成功一个value, 即条件1和条件2必须同时每个key匹配成功一个value,否则不调度
      operator: In
      values:
      - magedu

验证测试

[root@easzlab-deploy Affinit-case]# vi case3-1.2-nodeAffinity-requiredDuring-matchExpressions.yaml 
[root@easzlab-deploy Affinit-case]# cat case3-1.2-nodeAffinity-requiredDuring-matchExpressions.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions: #匹配条件1,同一个key的多个value只有有一个匹配成功就认为当前key匹配成功 
              - key: disktype
                operator: In
                values:
                - ssd
                - hddx
              - key: project #匹配条件2,当前key也要匹配成功一个value,即条件1和条件2必须同时每个key匹配成功一个value,否则不调度
                operator: In
                values:
                - magedu
[root@easzlab-deploy Affinit-case]#
[root@easzlab-deploy Affinit-case]# kubectl delete -f case3-1.1-nodeAffinity-requiredDuring-matchExpressions.yaml #删除旧的pod
deployment.apps "magedu-tomcat-app2-deployment" deleted
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu  #确认是否删除
NAME                                         READY   STATUS    RESTARTS   AGE
magedu-jenkins-deployment-79bbd88cb7-84999   1/1     Running   0          3d21h
magedu-jenkins-deployment-79bbd88cb7-pmd9z   1/1     Running   0          45h
[root@easzlab-deploy Affinit-case]# kubectl apply -f case3-1.2-nodeAffinity-requiredDuring-matchExpressions.yaml 
deployment.apps/magedu-tomcat-app2-deployment created
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          3d21h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          45h     10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-585f4864c4-brw6j   1/1     Running   0          15s     10.200.40.219    172.16.88.160   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

2.3、软亲和-nodeAffinity-preferredDuring

affinity:
 nodeAffinity:
  preferredDuringSchedulingIgnoredDuringExecution:
  - weight: 80 #软亲和条件1, weight值越大优先级越高, 越优先匹配调度
    preference:
     matchExpressions:
     - key: project
       operator: In
       values:
        - magedu
  - weight: 60 #软亲和条件2, 在条件1不满足时匹配条件2
    preference:
     matchExpressions:
     - key: disktype
       operator: In
       values:
        - ssd

验证测试

[root@easzlab-deploy Affinit-case]# kubectl delete -f case3-1.2-nodeAffinity-requiredDuring-matchExpressions.yaml #删除旧的pod
deployment.apps "magedu-tomcat-app2-deployment" deleted
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu #确实是否彻底删除
NAME                                         READY   STATUS    RESTARTS   AGE
magedu-jenkins-deployment-79bbd88cb7-84999   1/1     Running   0          3d21h
magedu-jenkins-deployment-79bbd88cb7-pmd9z   1/1     Running   0          45h
[root@easzlab-deploy Affinit-case]# 

#修改node label, 测试pod能否调度软策略优先级教高的节点 [root@easzlab
-deploy Affinit-case]# kubectl label node 172.16.88.160 project- #取消160节点 project标签 node/172.16.88.160 unlabeled [root@easzlab-deploy Affinit-case]# kubectl label node 172.16.88.161 project=magedu #指定161节点 project标签 node/172.16.88.161 labeled [root@easzlab-deploy Affinit-case]# kubectl get node --show-labels=true NAME STATUS ROLES AGE VERSION LABELS 172.16.88.157 Ready,SchedulingDisabled master 8d v1.24.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.157,kubernetes.io/os=linux,kubernetes.io/role=master 172.16.88.158 Ready,SchedulingDisabled master 8d v1.24.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.158,kubernetes.io/os=linux,kubernetes.io/role=master 172.16.88.159 Ready,SchedulingDisabled master 8d v1.24.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.159,kubernetes.io/os=linux,kubernetes.io/role=master 172.16.88.160 Ready node 8d v1.24.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.160,kubernetes.io/os=linux,kubernetes.io/role=node 172.16.88.161 Ready node 8d v1.24.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.161,kubernetes.io/os=linux,kubernetes.io/role=node,project=magedu 172.16.88.162 Ready node 8d v1.24.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.162,kubernetes.io/os=linux,kubernetes.io/role=node 172.16.88.163 Ready node 8d v1.24.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.163,kubernetes.io/os=linux,kubernetes.io/role=node 172.16.88.164 Ready node 8d v1.24.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.164,kubernetes.io/os=linux,kubernetes.io/role=node 172.16.88.165 Ready node 8d v1.24.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.165,kubernetes.io/os=linux,kubernetes.io/role=node [root@easzlab-deploy Affinit-case]# [root@easzlab-deploy Affinit-case]# vi case3-2.1-nodeAffinity-preferredDuring.yaml [root@easzlab-deploy Affinit-case]# cat case3-2.1-nodeAffinity-preferredDuring.yaml kind: Deployment #apiVersion: extensions/v1beta1 apiVersion: apps/v1 metadata: labels: app: magedu-tomcat-app2-deployment-label name: magedu-tomcat-app2-deployment namespace: magedu spec: replicas: 1 selector: matchLabels: app: magedu-tomcat-app2-selector template: metadata: labels: app: magedu-tomcat-app2-selector spec: containers: - name: magedu-tomcat-app2-container image: tomcat:7.0.94-alpine imagePullPolicy: IfNotPresent #imagePullPolicy: Always ports: - containerPort: 8080 protocol: TCP name: http affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 80 #软亲和条件1,weight值越大优先级越高,越优先匹配调度 preference: matchExpressions: - key: project operator: In values: - magedu - weight: 60 #软亲和条件2,在条件1不满足时匹配条件2 preference: matchExpressions: - key: disktype operator: In values: - ssd [root@easzlab-deploy Affinit-case]# kubectl apply -f case3-2.1-nodeAffinity-preferredDuring.yaml deployment.apps/magedu-tomcat-app2-deployment created [root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES magedu-jenkins-deployment-79bbd88cb7-84999 1/1 Running 0 3d21h 10.200.104.250 172.16.88.163 <none> <none> magedu-jenkins-deployment-79bbd88cb7-pmd9z 1/1 Running 0 45h 10.200.105.177 172.16.88.164 <none> <none> magedu-tomcat-app2-deployment-56c9bdffdd-sl62q 1/1 Running 0 18s 10.200.233.123 172.16.88.161 <none> <none> [root@easzlab-deploy Affinit-case]#

硬亲和与软亲和结合使用-nodeAffinity-requiredDuring-preferredDuring

基于硬亲和和软亲和实现pod调度: 1.绝对不会调度在哪些node 2.倾向于调度到哪些node
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution: #硬策略
      nodeSelectorTerms:
      - matchExpressions: #硬匹配条件1
        - key: "kubernetes.io/role" 
          operator: NotIn
          values:
          - "master" #硬性匹配key 的值kubernetes.io/role不包含master的节点,即绝对不会调度到master节点(node反亲和)
    preferredDuringSchedulingIgnoredDuringExecution: #软策略
    - weight: 80 
      preference: 
        matchExpressions: 
        - key: project 
          operator: In 
          values: 
            - magedu
    - weight: 60 
      preference: 
        matchExpressions: 
        - key: disktype
          operator: In 
          values: 
            - ssd

验证测试

[root@easzlab-deploy Affinit-case]# vi case3-2.2-nodeAffinity-requiredDuring-preferredDuring.yaml 
[root@easzlab-deploy Affinit-case]# cat case3-2.2-nodeAffinity-requiredDuring-preferredDuring.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution: #硬亲和
            nodeSelectorTerms:
            - matchExpressions: #硬匹配条件1
              - key: "kubernetes.io/role" 
                operator: NotIn
                values:
                - "master" #硬性匹配key 的值kubernetes.io/role不包含master的节点,即绝对不会调度到master节点(node反亲和)
          preferredDuringSchedulingIgnoredDuringExecution: #软亲和
          - weight: 80 
            preference: 
              matchExpressions: 
              - key: project 
                operator: In 
                values: 
                  - magedu
          - weight: 60 
            preference: 
              matchExpressions: 
              - key: disktype
                operator: In 
                values: 
                  - hdd
[root@easzlab-deploy Affinit-case]# kubectl delete -f case3-2.1-nodeAffinity-preferredDuring.yaml 
deployment.apps "magedu-tomcat-app2-deployment" deleted
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                         READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999   1/1     Running   0          3d21h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z   1/1     Running   0          45h     10.200.105.177   172.16.88.164   <none>           <none>
[root@easzlab-deploy Affinit-case]# kubectl apply -f case3-2.2-nodeAffinity-requiredDuring-preferredDuring.yaml 
deployment.apps/magedu-tomcat-app2-deployment created
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          3d21h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          45h     10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-7564998d64-6565f   1/1     Running   0          4s      10.200.233.125   172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

2.4、反亲和-nodeantiaffinity

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions: #匹配条件1
        - key: disktype
          operator: NotIn #调度的目的节点没有key为disktype且值为hdd的标签
          values:
          - hdd #绝对不会调度到含有label的key为disktype且值为hdd的hdd的节点,即会调度到没有key为disktype且值为hdd的hdd的节点

验证测试

[root@easzlab-deploy Affinit-case]# kubectl delete -f case3-2.2-nodeAffinity-requiredDuring-preferredDuring.yaml #删除旧的pod
deployment.apps "magedu-tomcat-app2-deployment" deleted
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                         READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999   1/1     Running   0          3d23h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z   1/1     Running   0          47h     10.200.105.177   172.16.88.164   <none>           <none>
[root@easzlab-deploy Affinit-case]#
[root@easzlab-deploy Affinit-case]# vi case3-3.1-nodeantiaffinity.yaml 
[root@easzlab-deploy Affinit-case]# cat case3-3.1-nodeantiaffinity.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 5
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions: #匹配条件1
              - key: disktype
                operator: NotIn #调度的目的节点没有key为disktype且值为hdd的标签
                values:
                - hdd #绝对不会调度到含有label的key为disktype且值为hdd的hdd的节点,即会调度到没有key为disktype且值为hdd的hdd的节点
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl label node 172.16.88.162 disktype="hdd"
node/172.16.88.162 labeled
[root@easzlab-deploy Affinit-case]# kubectl get node --show-labels=true
NAME            STATUS                     ROLES    AGE   VERSION   LABELS
172.16.88.157   Ready,SchedulingDisabled   master   8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.157,kubernetes.io/os=linux,kubernetes.io/role=master
172.16.88.158   Ready,SchedulingDisabled   master   8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.158,kubernetes.io/os=linux,kubernetes.io/role=master
172.16.88.159   Ready,SchedulingDisabled   master   8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.159,kubernetes.io/os=linux,kubernetes.io/role=master
172.16.88.160   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.160,kubernetes.io/os=linux,kubernetes.io/role=node
172.16.88.161   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.161,kubernetes.io/os=linux,kubernetes.io/role=node,project=magedu
172.16.88.162   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=hdd,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.162,kubernetes.io/os=linux,kubernetes.io/role=node
172.16.88.163   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.163,kubernetes.io/os=linux,kubernetes.io/role=node
172.16.88.164   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.164,kubernetes.io/os=linux,kubernetes.io/role=node
172.16.88.165   Ready                      node     8d    v1.24.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.88.165,kubernetes.io/os=linux,kubernetes.io/role=node
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl apply -f case3-3.1-nodeantiaffinity.yaml 
deployment.apps/magedu-tomcat-app2-deployment created
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          3d23h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          47h     10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-5c5fc87946-5mcrk   1/1     Running   0          96s     10.200.105.186   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-5c5fc87946-629nd   1/1     Running   0          96s     10.200.233.127   172.16.88.161   <none>           <none>
magedu-tomcat-app2-deployment-5c5fc87946-k9gv7   1/1     Running   0          96s     10.200.245.38    172.16.88.165   <none>           <none>
magedu-tomcat-app2-deployment-5c5fc87946-ls5p7   1/1     Running   0          96s     10.200.40.220    172.16.88.160   <none>           <none>
magedu-tomcat-app2-deployment-5c5fc87946-sklbb   1/1     Running   0          96s     10.200.104.201   172.16.88.163   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

三、Pod Affinity与anti-affinity简介

3.1、Pod Affinity与anti-affinity简介

  • Pod亲和性与反亲和性可以基于已经在node节点上运行的Pod的标签来约束新创建的Pod可以调度到的目的节点, 注意不是基于node上的标签而是使用的已经运行在node上的pod标签匹配。
  • 其规则的格式为如果 node节点 A已经运行了一个或多个满足调度新创建的Pod B的规则, 那么新的Pod B在亲和的条件下会调度到A节点之上, 而在反亲和性的情况下则不会调度到A节点至上。
  • 其中规则表示一个具有可选的关联命名空间列表的LabelSelector, 只所以Pod亲和与反亲和需可以通过LabelSelector选择namespace, 是因为Pod是命名空间限定的而node不属于任何nemespace所以node的亲和与反亲和不需要namespace, 因此作用于Pod标签的标签选择算符必须指定选择算符应用在哪个命名空间。
  • 从概念上讲, node节点是一个拓扑域(具有拓扑结构的域), 比如k8s集群中的单台node节点、 一个机架、云供应商可用区、 云供应商地理区域等, 可以使用topologyKey来定义亲和或者反亲和的颗粒度是node级别还是可用区级别, 以便kubernetes调度系统用来识别并选择正确的目的拓扑域。
  • Pod 亲和性与反亲和性的合法操作符(operator)有 In、 NotIn、 Exists、 DoesNotExist。
  • 在Pod亲和性配置中, 在requiredDuringSchedulingIgnoredDuringExecution和preferredDuringSchedulingIgnoredDuringExecution中, topologyKey不允许为空(Empty topologyKey is not allowed.)。
  • 在Pod反亲和性中配置中, requiredDuringSchedulingIgnoredDuringExecution和preferredDuringSchedulingIgnoredDuringExecution 中, topologyKey也不可以为空(Empty topologyKey is not allowed.)。
  • 对于requiredDuringSchedulingIgnoredDuringExecution要求的Pod反亲和性, 准入控制器LimitPodHardAntiAffinityTopology被引入以确保topologyKey只能是 kubernetes.io/hostname, 如果希望 topologyKey 也可用于其他定制拓扑逻辑, 可以更改准入控制器或者禁用。
  • 除上述情况外, topologyKey 可以是任何合法的标签键。

3.2、部署web服务测试

编写yaml文件,在magedu anmespace部署一个nginx服务,nginx pod将用于后续的pod 亲和及反亲和测试,且pod的label如下:

  • app: python-nginx-selector
  • project: python
[root@easzlab-deploy Affinit-case]# kubectl delete -f case3-3.1-nodeantiaffinity.yaml #删除旧的pod
deployment.apps "magedu-tomcat-app2-deployment" deleted
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                         READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999   1/1     Running   0          3d23h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z   1/1     Running   0          47h     10.200.105.177   172.16.88.164   <none>           <none>
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# vi case4-4.1-nginx.yaml 
[root@easzlab-deploy Affinit-case]# cat case4-4.1-nginx.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: python-nginx-deployment-label
  name: python-nginx-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: python-nginx-selector
  template:
    metadata:
      labels:
        app: python-nginx-selector
        project: python
    spec:
      containers:
      - name: python-nginx-container
        image: nginx:1.20.2-alpine
        #command: ["/apps/tomcat/bin/run_tomcat.sh"]
        #imagePullPolicy: IfNotPresent
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
          name: http
        - containerPort: 443
          protocol: TCP
          name: https
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
#        resources:
#          limits:
#            cpu: 2
#            memory: 2Gi
#          requests:
#            cpu: 500m
#            memory: 1Gi

---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: python-nginx-service-label
  name: python-nginx-service
  namespace: magedu
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30014
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
    nodePort: 30453
  selector:
    app: python-nginx-selector
    project: python #一个或多个selector,至少能匹配目标pod的一个标签 
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl apply -f case4-4.1-nginx.yaml 
deployment.apps/python-nginx-deployment created
service/python-nginx-service created
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                         READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999   1/1     Running   0          3d23h   10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z   1/1     Running   0          2d      10.200.105.177   172.16.88.164   <none>           <none>
python-nginx-deployment-5c658bf86b-qvzpn     1/1     Running   0          86s     10.200.233.65    172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

3.3、Pod Affinity-软亲和

基于软亲和实现多pod在一个node:先创建一个nginx服务,后续的服务和nginx运行在同一个node节点
[root@easzlab-deploy Affinit-case]# vi case4-4.1-nginx.yaml 
[root@easzlab-deploy Affinit-case]# cat case4-4.1-nginx.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: python-nginx-deployment-label
  name: python-nginx-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: python-nginx-selector
  template:
    metadata:
      labels:
        app: python-nginx-selector
        project: python
    spec:
      containers:
      - name: python-nginx-container
        image: nginx:1.20.2-alpine
        #command: ["/apps/tomcat/bin/run_tomcat.sh"]
        #imagePullPolicy: IfNotPresent
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
          name: http
        - containerPort: 443
          protocol: TCP
          name: https
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
#        resources:
#          limits:
#            cpu: 2
#            memory: 2Gi
#          requests:
#            cpu: 500m
#            memory: 1Gi

---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: python-nginx-service-label
  name: python-nginx-service
  namespace: magedu
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30014
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
    nodePort: 30453
  selector:
    app: python-nginx-selector
    project: python #一个或多个selector,至少能匹配目标pod的一个标签 
[root@easzlab-deploy Affinit-case]# kubectl apply -f case4-4.1-nginx.yaml 
deployment.apps/python-nginx-deployment created
service/python-nginx-service created
[root@easzlab-deploy Affinit-case]#
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                         READY   STATUS    RESTARTS   AGE   IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999   1/1     Running   0          4d    10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z   1/1     Running   0          2d    10.200.105.177   172.16.88.164   <none>           <none>
python-nginx-deployment-5c658bf86b-qvzpn     1/1     Running   0          86s    10.200.233.67    172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

#实现软亲和pod调度
[root@easzlab-deploy Affinit-case]# vi case4-4.2-podaffinity-preferredDuring.yaml 
[root@easzlab-deploy Affinit-case]# cat case4-4.2-podaffinity-preferredDuring.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
      affinity:
        podAffinity:  #Pod亲和
          #requiredDuringSchedulingIgnoredDuringExecution: #硬亲和,必须匹配成功才调度,如果匹配失败则拒绝调度。
          preferredDuringSchedulingIgnoredDuringExecution: #软亲和,能匹配成功就调度到一个topology,匹配不成功会由kubernetes自行调度。
          - weight: 100
            podAffinityTerm:
              labelSelector: #标签选择
                matchExpressions: #正则匹配
                - key: project
                  operator: In
                  values:
                    - python
              topologyKey: kubernetes.io/hostname 
              namespaces:
                - magedu
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl apply -f  case4-4.2-podaffinity-preferredDuring.yaml 
deployment.apps/magedu-tomcat-app2-deployment created
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE   IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          4d    10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          2d    10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-74d68bdfcf-xsxs6   1/1     Running   0          12s   10.200.233.69    172.16.88.161   <none>           <none>
python-nginx-deployment-5c658bf86b-qvzpn         1/1     Running   0          96s   10.200.233.67    172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

3.4、Pod Affinity-硬亲和

[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          4d      10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          2d      10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-74d68bdfcf-xsxs6   1/1     Running   0          5m52s   10.200.233.69    172.16.88.161   <none>           <none>
python-nginx-deployment-5c658bf86b-qvzpn         1/1     Running   0          7m16s   10.200.233.67    172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# vi case4-4.3-podaffinity-requiredDuring.yaml 
[root@easzlab-deploy Affinit-case]# cat case4-4.3-podaffinity-requiredDuring.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 3
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution: #硬亲和
          - labelSelector:
              matchExpressions:
              - key: project
                operator: In
                values:
                  - python
            topologyKey: "kubernetes.io/hostname"
            namespaces:
              - magedu
[root@easzlab-deploy Affinit-case]# kubectl appy -f case4-4.3-podaffinity-requiredDuring.yaml 
error: unknown command "appy" for "kubectl"

Did you mean this?
    apply
[root@easzlab-deploy Affinit-case]# kubectl apply -f case4-4.3-podaffinity-requiredDuring.yaml 
deployment.apps/magedu-tomcat-app2-deployment configured
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          4d      10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          2d      10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-68c5977495-48m5g   1/1     Running   0          28s     10.200.233.73    172.16.88.161   <none>           <none>
magedu-tomcat-app2-deployment-68c5977495-nldc2   1/1     Running   0          23s     10.200.233.72    172.16.88.161   <none>           <none>
magedu-tomcat-app2-deployment-68c5977495-pjgck   1/1     Running   0          25s     10.200.233.74    172.16.88.161   <none>           <none>
python-nginx-deployment-5c658bf86b-qvzpn         1/1     Running   0          8m18s   10.200.233.67    172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

3.5、podAntiAffinity-硬反亲和

[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          4d      10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          2d      10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-68c5977495-48m5g   1/1     Running   0          28s     10.200.233.73    172.16.88.161   <none>           <none>
magedu-tomcat-app2-deployment-68c5977495-nldc2   1/1     Running   0          23s     10.200.233.72    172.16.88.161   <none>           <none>
magedu-tomcat-app2-deployment-68c5977495-pjgck   1/1     Running   0          25s     10.200.233.74    172.16.88.161   <none>           <none>
python-nginx-deployment-5c658bf86b-qvzpn         1/1     Running   0          8m18s   10.200.233.67    172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# vi case4-4.4-podAntiAffinity-requiredDuring.yaml 
[root@easzlab-deploy Affinit-case]# cat case4-4.4-podAntiAffinity-requiredDuring.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: project
                operator: In
                values:
                  - python
            topologyKey: "kubernetes.io/hostname"
            namespaces:
              - magedu
[root@easzlab-deploy Affinit-case]# kubectl apply -f case4-4.4-podAntiAffinity-requiredDuring.yaml 
deployment.apps/magedu-tomcat-app2-deployment configured
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE   IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          4d    10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          2d    10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-85f7f8f6d9-cl4ll   1/1     Running   0          46s   10.200.2.42      172.16.88.162   <none>           <none>
python-nginx-deployment-5c658bf86b-qvzpn         1/1     Running   0          11m   10.200.233.67    172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

3.6、podAntiAffinity-软反亲和

[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE   IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          4d    10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          2d    10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-85f7f8f6d9-cl4ll   1/1     Running   0          46s   10.200.2.42      172.16.88.162   <none>           <none>
python-nginx-deployment-5c658bf86b-qvzpn         1/1     Running   0          11m   10.200.233.67    172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# vi case4-4.5-podAntiAffinity-preferredDuring.yaml 
[root@easzlab-deploy Affinit-case]# cat case4-4.5-podAntiAffinity-preferredDuring.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: project 
                  operator: In
                  values:
                    - pythonx
              topologyKey: kubernetes.io/hostname 
              namespaces: 
                - magedu
[root@easzlab-deploy Affinit-case]# kubectl apply -f  case4-4.5-podAntiAffinity-preferredDuring.yaml 
deployment.apps/magedu-tomcat-app2-deployment configured
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                            READY   STATUS    RESTARTS   AGE   IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999      1/1     Running   0          4d    10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z      1/1     Running   0          2d    10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app2-deployment-5b4596845-xfhs4   1/1     Running   0          18s   10.200.40.221    172.16.88.160   <none>           <none>
python-nginx-deployment-5c658bf86b-qvzpn        1/1     Running   0          13m   10.200.233.67    172.16.88.161   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

四、污点与容忍

4.1、污点简介

污点(taints),用于node节点排斥 Pod调度, 与亲和的作用是完全相反的,即taint的node和pod是排斥调度关系。
容忍(toleration),用于Pod容忍node节点的污点信息, 即node有污点信息也会将新的pod调度到node

  • https://kubernetes.io/zh/docs/concepts/scheduling-eviction/taint-and-toleration/

污点的三种类型

  • NoSchedule: 表示k8s将不会将Pod调度到具有该污点的Node上
  • PreferNoSchedule: 表示k8s将尽量避免将Pod调度到具有该污点的Node上
  • NoExecute: 表示k8s将不会将Pod调度到具有该污点的Node上, 同时会将Node上已经存在的Pod强制驱逐出去
[root@easzlab-deploy Affinit-case]# kubectl taint nodes 172.16.88.160 key1=value1:NoSchedule #设置污点
node/172.16.88.160 tainted
[root@easzlab-deploy Affinit-case]# kubectl describe node 172.16.88.160 #查看污点
Name:               172.16.88.160
Roles:              node
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    disktype=ssd
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=172.16.88.160
                    kubernetes.io/os=linux
                    kubernetes.io/role=node
Annotations:        node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Tue, 18 Oct 2022 17:09:40 +0800
Taints:             key1=value1:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  172.16.88.160
  AcquireTime:     <unset>
  RenewTime:       Thu, 27 Oct 2022 14:56:20 +0800
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Wed, 19 Oct 2022 22:12:21 +0800   Wed, 19 Oct 2022 22:12:21 +0800   CalicoIsUp                   Calico is running on this node
  MemoryPressure       False   Thu, 27 Oct 2022 14:55:59 +0800   Wed, 19 Oct 2022 14:30:48 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Thu, 27 Oct 2022 14:55:59 +0800   Wed, 19 Oct 2022 14:30:48 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Thu, 27 Oct 2022 14:55:59 +0800   Wed, 19 Oct 2022 14:30:48 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Thu, 27 Oct 2022 14:55:59 +0800   Wed, 19 Oct 2022 22:10:59 +0800   KubeletReady                 kubelet is posting ready status. AppArmor enabled
Addresses:
  InternalIP:  172.16.88.160
  Hostname:    172.16.88.160
Capacity:
  cpu:                4
  ephemeral-storage:  49869532Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             8148220Ki
  pods:               500
Allocatable:
  cpu:                4
  ephemeral-storage:  45959760616
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             7841020Ki
  pods:               500
System Info:
  Machine ID:                 1a19d04d6cc141e58368dc5dcc39f1a9
  System UUID:                591ea877-a39d-4aab-81e2-76cf3a9b08cd
  Boot ID:                    e7ce258c-2b9a-4a2a-8bc8-e91af3888bd4
  Kernel Version:             5.4.0-128-generic
  OS Image:                   Ubuntu 20.04.4 LTS
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  containerd://1.6.4
  Kubelet Version:            v1.24.2
  Kube-Proxy Version:         v1.24.2
PodCIDR:                      10.200.3.0/24
PodCIDRs:                     10.200.3.0/24
Non-terminated Pods:          (4 in total)
  Namespace                   Name                                             CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                             ------------  ----------  ---------------  -------------  ---
  kube-system                 calico-kube-controllers-5c8bb696bb-5nrbl         0 (0%)        0 (0%)      0 (0%)           0 (0%)         8d
  kube-system                 calico-node-68k76                                250m (6%)     0 (0%)      0 (0%)           0 (0%)         8d
  magedu                      magedu-tomcat-app2-deployment-5b4596845-xfhs4    0 (0%)        0 (0%)      0 (0%)           0 (0%)         8m55s
  velero-system               velero-858b9459f9-4jbns                          500m (12%)    1 (25%)     128Mi (1%)       512Mi (6%)     8d
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                750m (18%)  1 (25%)
  memory             128Mi (1%)  512Mi (6%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-1Gi      0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%)
Events:              <none>
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl taint node 172.16.88.160 key1:NoSchedule- #取消污点 
node/172.16.88.160 untainted
[root@easzlab-deploy Affinit-case]# kubectl describe node 172.16.88.160 |grep Taints
Taints:             <none>
[root@easzlab-deploy Affinit-case]# 

4.2、容忍简介

tolerations容忍

  • 定义 Pod 的容忍度(可以接受node的哪些污点), 容忍后可以将Pod调度至含有该污点的node。

基于operator的污点匹配:

  • 如果operator是Exists, 则容忍度不需要value而是直接匹配污点类型。
  • 如果operator是Equal, 则需要指定value并且value的值需要等于tolerations的key。

验证测试

[root@easzlab-deploy Affinit-case]# kubectl delete -f case4-4.1-nginx.yaml #删除旧的Pod
deployment.apps "python-nginx-deployment" deleted
service "python-nginx-service" deleted
[root@easzlab-deploy Affinit-case]# kubectl delete -f case5.1-taint-tolerations.yaml #删除旧得pod
deployment.apps "magedu-tomcat-app1-deployment" deleted
service "magedu-tomcat-app1-service" deleted
[root@easzlab-deploy Affinit-case]# 
[root@easzlab-deploy Affinit-case]# kubectl taint nodes 172.16.88.160 key1=value1:NoExecute  #节点设置不可调度
node/172.16.88.160 tainted
[root@easzlab-deploy Affinit-case]# kubectl taint nodes 172.16.88.163 key1=value1:NoSchedule #节点打上污点信息 
node/172.16.88.163 tainted
[root@easzlab-deploy Affinit-case]# kubectl describe node 172.16.88.160 |grep Taints
Taints: key1=value1:NoExecute
[root@easzlab-deploy Affinit-case]# kubectl describe node 172.16.88.163 |grep Taints
Taints: key1=value1:NoSchedule
[root@easzlab-deploy Affinit-case]#
[root@easzlab-deploy Affinit-case]# vi case5.1-taint-tolerations.yaml 
[root@easzlab-deploy Affinit-case]# cat case5.1-taint-tolerations.yaml 
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app1-deployment-label
  name: magedu-tomcat-app1-deployment
  namespace: magedu
spec:
  replicas: 5
  selector:
    matchLabels:
      app: magedu-tomcat-app1-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app1-selector
    spec:
      containers:
      - name: magedu-tomcat-app1-container
        #image: harbor.magedu.net/magedu/tomcat-app1:v7
        image: tomcat:7.0.93-alpine 
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
      tolerations: 
      - key: "key1"
        operator: "Equal"
        value: "value1"
        effect: "NoSchedule"
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: magedu-tomcat-app1-service-label
  name: magedu-tomcat-app1-service
  namespace: magedu
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    #nodePort: 40003
  selector:
    app: magedu-tomcat-app1-selector
[root@easzlab-deploy Affinit-case]# kubectl apply -f case5.1-taint-tolerations.yaml #测试对污点容忍和不容忍分别能否调度 
deployment.apps/magedu-tomcat-app1-deployment created
service/magedu-tomcat-app1-service created
[root@easzlab-deploy Affinit-case]#
[root@easzlab-deploy Affinit-case]# kubectl get pod -n magedu -owide
NAME                                             READY   STATUS    RESTARTS   AGE   IP               NODE            NOMINATED NODE   READINESS GATES
magedu-jenkins-deployment-79bbd88cb7-84999       1/1     Running   0          4d    10.200.104.250   172.16.88.163   <none>           <none>
magedu-jenkins-deployment-79bbd88cb7-pmd9z       1/1     Running   0          2d    10.200.105.177   172.16.88.164   <none>           <none>
magedu-tomcat-app1-deployment-785c799fc9-5f8gw   1/1     Running   0          22s   10.200.233.81    172.16.88.161   <none>           <none>
magedu-tomcat-app1-deployment-785c799fc9-cps9r   1/1     Running   0          22s   10.200.105.189   172.16.88.164   <none>           <none>
magedu-tomcat-app1-deployment-785c799fc9-npthx   1/1     Running   0          22s   10.200.245.41    172.16.88.165   <none>           <none>
magedu-tomcat-app1-deployment-785c799fc9-rmqxl   1/1     Running   0          22s   10.200.104.206   172.16.88.163   <none>           <none>
magedu-tomcat-app1-deployment-785c799fc9-rxf5g   1/1     Running   0          22s   10.200.2.46      172.16.88.162   <none>           <none>
[root@easzlab-deploy Affinit-case]# 

删除node节点限制规则

[root@easzlab-deploy Affinit-case]# kubectl taint nodes 172.16.88.163 key1:NoSchedule-
node/172.16.88.163 untainted
[root@easzlab-deploy Affinit-case]# kubectl taint nodes 172.16.88.160 key1:NoExecute- node/172.16.88.160 untainted [root@easzlab-deploy Affinit-case]# kubectl describe node 172.16.88.160 |grep Taints Taints: <none> [root@easzlab-deploy Affinit-case]# kubectl describe node 172.16.88.163 |grep Taints Taints: <none> [root@easzlab-deploy Affinit-case]#

五、kubernetes pod驱逐

5.1、驱逐简介

        驱逐是由各kubelet进程主动终止Pod, 以回收节点上的内存、 磁盘空间等资源的过程, kubelet监控当前node节点的CPU、 内存、 磁盘空间和文件系统的inode等资源, 当这些资源中的一个或者多个达到特定的消耗水平, kubelet就会主动地将节点上一个或者多个Pod强制驱逐, 以防止当前node节点资源无法正常分配而引发的OOM(OutOfMemory)。

https://kubernetes.io/zh/docs/concepts/scheduling-eviction/node-pressure-eviction/

宿主机内存

  • memory.available #node节点可用内存, 默认 <100Mi

nodefs是节点的主要文件系统,用于保存本地磁盘卷、 emptyDir、 日志存储等数据, 默认是/var/lib/kubelet/, 或者是通过kubelet通过--root-dir所指定的磁盘挂载目录

  • nodefs.inodesFree #nodefs的可用inode, 默认<5%
  • nodefs.available #nodefs的可用空间,默认<10%

imagefs是可选文件系统, 用于给容器提供运行时存储容器镜像和容器可写层。

  • imagefs.inodesFree #imagefs的inode可用百分比
  • imagefs.available #imagefs的磁盘空间可用百分比, 默认<15%
  • pid.available #可用pid百分比

示例:

evictionHard:

  • imagefs.inodesFree: 5%
  • imagefs.available: 15%
  • memory.available: 300Mi
  • nodefs.available: 10%
  • nodefs.inodesFree: 5%
  • pid.available: 5%

kube-controller-manager实现 eviction:

  • node宕机后的驱逐

kubelet实现的eviction:

  • 基于node负载、 资源利用率等进行pod驱逐。

驱逐(eviction, 节点驱逐), 用于当node节点资源不足的时候自动将pod进行强制驱逐, 以保证当前node节点的正常运行。

 

Kubernetes基于是QoS(服务质量等级)驱逐Pod , Qos等级包括目前包括以下三个:

Guaranteed: #limits和request的值相等, 等级最高、 最后被驱逐
 resources:
  limits:
    cpu: 500m
    memory: 256Mi
  requests:
    cpu: 500m
    memory: 256Mi
Burstable: #limit和request不相等, 等级折中、 中间被驱逐
 resources:
  limits:
    cpu: 500m
    memory: 256Mi
  requests:
    cpu: 256m
    memory: 128Mi
BestEffort: #没有限制, 即resources为空, 等级最低、 最先被驱逐

5.2、驱逐条件

eviction-signal:kubelet捕获node节点驱逐触发信号,进行判断是否驱逐,比如通过cgroupfs获取memory.available的值来进行下一步匹配。

operator:操作符,通过操作符对比条件是否匹配资源量是否触发驱逐。

quantity:使用量,即基于指定的资源使用值进行判断,如memory.available: 300Mi、nodefs.available: 10%等。

  • 比如:nodefs.available<10% #当node节点磁盘空间可用率低于10%就会触发驱逐信号

软驱逐

软驱逐不会立即驱逐pod, 可以自定义宽限期, 在条件持续到宽限期还没有恢复, kubelet再强制杀死pod并触发驱逐:

软驱逐条件:

  • eviction-soft: 软驱逐触发条件, 比如memory.available < 1.5Gi, 如果驱逐条件持续时长超过指定的宽限期, 可以触发Pod驱逐。
  • eviction-soft-grace-period: 软驱逐宽限期, 如 memory.available=1m30s, 定义软驱逐条件在触发Pod驱逐之前必须保持多长时间。
  • eviction-max-pod-grace-period: 终止pod的宽限期, 即在满足软驱逐条件而终止Pod时使用的最大允许宽限期(以秒为单位) 。

硬驱逐

硬驱逐条件没有宽限期, 当达到硬驱逐条件时, kubelet 会强制立即杀死 pod并驱逐:

kubelet 具有以下默认硬驱逐条件(可以自行调整):

  • memory.available<100Mi
  • nodefs.available<10%
  • imagefs.available<15%
  • nodefs.inodesFree<5%(Linux 节点)

kubelet service文件:

  • # vim /etc/systemd/system/kubelet.service

kubelet配置文件:

  • # vim /var/lib/kubelet/config.yaml

evictionHard:

  • imagefs.available: 15%
  • memory.available: 300Mi
  • nodefs.available: 10%
  • nodefs.inodesFree: 5%
 
posted @ 2022-10-27 12:01  cyh00001  阅读(434)  评论(0编辑  收藏  举报