47、K8S-调度机制-Pod调度之反亲和性-podAntiAffinity

发布时间 2023-04-06 11:38:56作者: 小粉优化大师

Kubernetes学习目录

1、基础知识

1.1、简介

所谓的反亲和,其实就是满足条件的话,就离这个pod远远的,从此不见面。与亲和正好相反

1.2、属性解析

kubectl explain pod.spec.affinity.podAntiAffinity

requiredDuringSchedulingIgnoredDuringExecution -- 硬亲和性:
  labelSelector   选择跟那组Pod亲和,前提得知道如何判断
  namespaces      选择哪个命名空间进行条件匹配
  topologyKey     指定节点上的哪个键,这是一个必选项
注意:这三个条件是一个逻辑与的关系

preferredDuringSchedulingIgnoredDuringExecution -- 软亲和性:
  podAffinityTerm   与权重关联的亲和选项,这是一个必选项
    labelSelector   标签选择器
    namespaces      命令空间名称
    topologyKey     指定节点上的哪个键,这是一个必选项
  weight            权重,这是一个必选项
  
注意:Pod反亲和性场景,当应用服务A和数据库服务B要求尽量不要在同一台节点上的时候。

2、Pod调度之反亲和性-podAntiAffinity-实践

2.1、硬反亲和性-实践

2.1.1、需求

不要跟包含有标签env=dev运行的pod,放在一起

2.1.2、给节点打标签【用于给env运行pod分开调度节点】

kubectl label node node2 env=test  
kubectl label node node1 env=dev

2.1.3、创建env=test、env=dev的运行pod

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: pod-dev
  labels:
    env: dev
spec:
  containers:
  - name: pod-test
    image: 192.168.10.33:80/k8s/pod_test:v0.1
    imagePullPolicy: IfNotPresent
  nodeSelector:
    env: dev
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-test
  labels:
    env: test
spec:
  containers:
  - name: pod-test
    image: 192.168.10.33:80/k8s/pod_test:v0.1
    imagePullPolicy: IfNotPresent
  nodeSelector:
    env: test
EOF

# 该pod的调度策略,env: test调度到node2,env: dev调度到node1

2.1.4、查询标签env运行的pod是否被分别调度到不同节点上

master1 ~]# kubectl get pods -o wide --show-labels 
NAME       READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES   LABELS
pod-dev    1/1     Running   0          8s    10.244.3.63   node1   <none>           <none>            env=dev
pod-test   1/1     Running   0          8s    10.244.4.93   node2   <none>           <none>            env=test

2.1.5、定义资源配置清单且应用【场景:强制不往标签env=dev运行pod的节点上调度】

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: pod-antiaffinity
spec:
  containers:
  - name: pod-test
    image: 192.168.10.33:80/k8s/pod_test:v0.1
    imagePullPolicy: IfNotPresent
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: env, operator: In, values: ["dev"]}
        topologyKey: kubernetes.io/hostname
EOF

2.1.6、查询调度的结果

master1 ~]# kubectl get pods -o wide --show-labels 
NAME               READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES   LABELS
pod-antiaffinity   1/1     Running   0          4s      10.244.4.94   node2   <none>           <none>            <none>
pod-dev            1/1     Running   0          4m41s   10.244.3.63   node1   <none>           <none>            env=dev
pod-test           1/1     Running   0          4m41s   10.244.4.93   node2   <none>           <none>            env=test

总结:
因为排它条件env=dev,所以不会调度跟运行pod标签带有env=dev相同的节点上

2.2、软反亲和性-实践

2.2.1、需求

最好不要哪些pod放在一起,使用给标签设置权重,按权重调度最佳节

2.2.2、设置标签

kubectl label node node2 env=test  
kubectl label node node1 env=dev

2.2.3、创建env=test、env=dev的运行pod

创建方法请查看: 2.1.2、创建env=test、env=dev的运行pod

2.2.4、查询标签env运行的pod是否被分别调度到不同节点上

master1 ~]# kubectl get pods -o wide --show-labels 
NAME       READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES   LABELS
pod-dev    1/1     Running   0          8s    10.244.3.63   node1   <none>           <none>            env=dev
pod-test   1/1     Running   0          8s    10.244.4.93   node2   <none>           <none>            env=test

2.2.5、定义资源配置清单且应用【场景:不往标签权重最高的env=dev运行pod的节点上调度】

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: pod-antiaffinity
spec:
  containers:
  - name: pod-test
    image: 192.168.10.33:80/k8s/pod_test:v0.1
    imagePullPolicy: IfNotPresent
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchExpressions:
              - {key: env, operator: In, values: ["dev"]}
            topologyKey: kubernetes.io/hostname
        - weight: 50
          podAffinityTerm:
            labelSelector:
              matchExpressions:
              - {key: env, operator: In, values: ["test"]}
            topologyKey: kubernetes.io/hostname
EOF

2.2.6、查询调度的结果

master1 ~]# kubectl get pods -o wide --show-labels 
NAME               READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES   LABELS
pod-antiaffinity   1/1     Running   0          2s    10.244.4.95   node2   <none>           <none>            <none>
pod-dev            1/1     Running   0          12m   10.244.3.63   node1   <none>           <none>            env=dev
pod-test           1/1     Running   0          12m   10.244.4.93   node2   <none>           <none>            env=test

总结:
因为是反亲和性,dev的权重最高,所以不往dev调度

3、为什么没有node反亲和性-nodeAntiAffinity

affinity.nodeAffinity.nodeSelectorTerms.matchExpressions.operator
操作符
NotIn:标签的值不在某个列表中
DoesNotExist:某个标签不存在

因为NotIn和DoesNotExist可以提供相同的功能。