一、亲和性简介

1、节点亲和性

pod.spec.nodeAffinity
preferredDuringSchedulingIgnoredDuringExecution:软策略
requiredDuringSchedulingIgnoredDuringExecution: 硬策略

2、Pod 亲和性

pod.spec.affinity.podAffinity/podAntiAffinity
preferredDuringSchedulingIgnoredDuringExecution:软策略
requiredDuringSchedulingIgnoredDuringExecution: 硬策略

详细解释

软策略:结合下面的 “operator: NotIn”,意思就是尽量不要将 pod 调度到匹配到的节点,但是如果没有不匹配的节点的话,也可以调度到匹配到的节点

硬策略:结合下面的 “operator: In”,意思就是必须调度到满足条件的节点上,否则就等着 Pending

举例说明

1.可以把自己理解成一个Pod,当你来学云计算,如果你更倾向去zhangsan老师带的班级,把不同老师带的班级当作一个node的话,这个就是节点亲和性。如果你是必须要去zhangsan老师带的班级,这就是硬策略;而你说你想去并且最好能去zhangsan老师带的班级,这就是软策略

2.如果你有一个很好的朋友叫lisi,你倾向和lisi同学在同一个班级,这个就是Pod亲和性。如果你一定要去lisi同学在的班级,这就是硬策略;而你说你想去并且最好能去lisi同学在的班级,这就是软策略。软策略是不去也可以,硬策略则是不去就不行

3、键值运算关系

  • In:label 的值在某个列表中
  • NotIn:label 的值不在某个列表中
  • Gt:label 的值大于某个值
  • Lt:label 的值小于某个值
  • Exists:某个 label 存在
  • DoesNotExist:某个 label 不存在

4、亲和与反亲和

  • 从pod出发,可以分成亲和性和反亲和性,分别对应podAffinity和podAntiAffinity
  • 从node出发,也可以分成亲和性和反亲和性,分别对应nodeAffinity和nodeAntiAffinity
  • 从操作指令来讲,可以有ln、Notln、Exists、DoesNotExist等等

针对亲和性来讲,in代表我要调度到有这个标签的位置
针对反亲和性来讲,in代表我不要调度到有这个标签的位置

不管哪种方式,最终还是要依赖 label 标签

调度策略匹配标签操作符拓扑域支持调度目标
nodeAffinity主机In,NotIn,Exists,DoesNotExist, Gt, Lt指定主机
podAffinitypodIn,NotIn,Exists,DoesNotExistpod 与指定 pod同一拓扑域
podAntAffinitypodIn,NotIn,Exists,DoesNotExistpod 与指定 pod 不在同一拓扑域

5、硬策略示例

requiredDuringSchedulingIgnoredDuringExecution

vim pod1.yaml

apiVersion: v1
kind: Pod
metadata:
  name: affinity
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname    #指定node的标签
            operator: NotIn     #设置Pod安装到kubernetes.io/hostname的标签值不在values列表中的node上
            values:
            - node1
            
#也可指定标签 例:            
apiVersion: v1
kind: Pod
metadata:
  name: affinity
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: xtz
            operator: In     
            values:
            - q

image-20221011200953482

kubectl apply -f pod1.yaml

kubectl get pods -o wide

image-20221011200922881

kubectl delete pod --all && kubectl apply -f pod1.yaml && kubectl get pods -o wide

#如果硬策略不满足条件,Pod 状态一直会处于 Pending 状态

6、软策略示例

preferredDuringSchedulingIgnoredDuringExecution

vim pod2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: affinity
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1    注: #如果有多个软策略选项的话,权重越大,优先级越高
        preference:
          matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - node2

image-20221011201312336

kubectl apply -f pod2.yaml

kubectl get pods -o wide

#把values:的值改成node1,则会优先在node01上创建Pod 
kubectl delete pod --all && kubectl apply -f pod2.yaml && kubectl get pods -o wide

image-20221011202604343

image-20221011202649432

image-20221011202800391

7、亲和性与反亲和性示例

#创建一个标签为 app=myapp01 的 Pod
vim pod3.yaml

apiVersion: v1
kind: Pod
metadata:
 name: myapp01
 labels:
  app: myapp01
spec:
 containers:
 - name: with-node-affinity
   image: soscscs/myapp:v1
  
kubectl apply -f pod3.yaml
  
kubectl get pods --show-labels -o wide

image-20221011204615401

image-20221011204604338

使用 Pod 亲和性调度

vim pod4.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp02
  labels:
    app: myapp02
spec:
  containers:
  - name: myapp02
    image: soscscs/myapp:v1
  affinity:         #编写亲和度
    podAffinity:    #pod 与指定 pod同一拓扑域
      requiredDuringSchedulingIgnoredDuringExecution:   #制定硬策略
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - myapp01
        topologyKey: xtz

解释

仅当节点和至少一个已运行且有键为“app”且值为“myapp01”的标签 的 Pod 处于同一拓扑域时,才可以将该 Pod 调度到节点上。 (更确切的说,如果节点 N 具有带有键 xtz 和某个值 V 的标签,则 Pod 有资格在节点 N 上运行,以便集群中至少有一个具有键 xtz 和值为 V 的节点正在运行具有键“app”和值 “myapp01”的标签的 pod。)

#topologyKey 是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值,则调度器会将这两个节点视为处于同一拓扑域中。 调度器试图在每个拓扑域中放置数量均衡的 Pod。

#如果 xtz 对应的值不一样就是不同的拓扑域。比如 Pod1 在 xtz=a 的 Node 上,Pod2 在 xtz=b 的 Node 上,Pod3 在 xtz=a 的 Node 上,则 Pod2 和 Pod1、Pod3 不在同一个拓扑域,而Pod1 和 Pod3在同一个拓扑域

image-20221012163730667

kubectl apply -f pod4.yaml

kubectl get pods --show-labels -o wide

image-20221012163933800

使用 Pod 反亲和性调度

vim pod5.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp10
  labels:
    app: myapp10
spec:
  containers:
  - name: myapp10
    image: soscscs/myapp:v1
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - myapp01
          topologyKey: kubernetes.io/hostname

#如果节点处于 Pod 所在的同一拓扑域且具有键“app”和值“myapp01”的标签, 则该 pod 不应将其调度到该节点上。 (如果 topologyKey 为 kubernetes.io/hostname,则意味着当节点和具有键 “app”和值“myapp01”的 Pod 处于相同的拓扑域,Pod 不能被调度到该节点上。)

image-20221012170617869

kubectl apply -f pod5.yaml

kubectl get pods --show-labels -o wide

image-20221012170602220

示例2:

vim pod6.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp20
  labels:
    app: myapp20
spec:
  containers:
  - name: myapp20
    image: soscscs/myapp:v1
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - myapp01
        topologyKey: xtz

由于指定 Pod 所在的 node1 节点上具有带有键 xtz 和标签值 m 的标签,node2 也有这个xtz=m的标签,所以 node1 和 node2 是在一个拓扑域中,反亲和要求新 Pod 与指定 Pod 不在同一拓扑域,所以新 Pod 没有可用的 node 节点,即为 Pending 状态

image-20221012171338523

kubectl apply -f pod6.yaml

kubectl get pod --show-labels -owide

image-20221012171509170

更改个labels标签名字就可以了

 kubectl label nodes node2 xtz=j --overwrite

 kubectl get pod --show-labels -owide

image-20221012171646334

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐