一、亲和性简介

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 指定主机
podAffinity pod In,NotIn,Exists,DoesNotExist pod 与指定 pod同一拓扑域
podAntAffinity pod In,NotIn,Exists,DoesNotExist pod 与指定 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社区为您提供最前沿的新闻资讯和知识内容

更多推荐