亲和性与反亲和性学习

本文参考摘抄于kubernetes官方文档,参考地址:https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity

nodeSelector 提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。 亲和性和反亲和性扩展了你可以定义的约束类型。使用亲和性与反亲和性的一些好处有
1.亲和性、反亲和性语言的表达能力更强。nodeSelector 只能选择拥有所有指定标签的节点。 亲和性、反亲和性为你提供对选择逻辑的更强控制能力。
2.你可以标明某规则是“软需求”或者“偏好”,这样调度器在无法找到匹配节点时仍然调度该 Pod。
3.你可以使用节点上(或其他拓扑域中)运行的其他 Pod 的标签来实施调度约束, 而不是只能使用节点本身的标签。这个能力让你能够定义规则允许哪些 Pod 可以被放置在一起。

亲和性功能由两种类型的亲和性组成:
(1)节点亲和性功能类似于 nodeSelector 字段,但它的表达能力更强,并且允许你指定软规则。
(2)Pod 间亲和性/反亲和性允许你根据其他 Pod 的标签来约束 Pod

节点亲和性
节点亲和性概念上类似于 nodeSelector, 它使你可以根据节点上的标签来约束 Pod 可以调度到哪些节点上。 节点亲和性有两种:
requiredDuringSchedulingIgnoredDuringExecution: 调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector, 但其语法表达能力更强。
preferredDuringSchedulingIgnoredDuringExecution: 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。

可以使用 Pod 规约中的 .spec.affinity.nodeAffinity 字段来设置节点亲和性。 例如,考虑下面的 Pod 规约

#分别在k8s-master3,和k8s-node1 两个节点上分别加上app=host1标签
[root@k8s-master1 node]# kubectl label node k8s-node1 app=host1 --overwrite
node/k8s-node1 labeled
[root@k8s-master1 node]# kubectl label node k8s-master3 app=host1 --overwrite
node/k8s-master3 labeled
#单独在k8s-node上增加一个apps=host1的标签
[root@k8s-master1 node]# kubectl label node k8s-node1 apps=host1 --overwrite
node/k8s-node1 not labeled

创建node亲和性的pod的

[root@k8s-master1 node]# cat pod-with-node-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
  namespace: app
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:         #必须条件:app=host1标签的节点
        nodeSelectorTerms:
        - matchExpressions:
          - key: app
            operator: In
            values:
            - host1
      preferredDuringSchedulingIgnoredDuringExecution:        #非必要条件存在的优先apps=host1
      - weight: 50                                            #权重
        preference:
          matchExpressions:
          - key: apps
            operator: In
            values:
            - host1
  containers:
  - name: with-node-affinity
    image: nginx
由于咱们在k8s-node1节点上配置了app=host1和apps=host1两个标签,所以容器优先分配到k8s-node1节点
[root@k8s-master1 node]# kubectl get pods -n app -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP              NODE          NOMINATED NODE   READINESS GATES
nginx                1/1     Running   0          64m   10.10.135.202   k8s-master3   <none>           <none>
with-node-affinity   1/1     Running   0          49s   10.10.36.115    k8s-node1     <none>           <none>

节点亲和性权重
你可以为 preferredDuringSchedulingIgnoredDuringExecution 亲和性类型的每个实例设置 weight 字段,其取值范围是 1 到 100。 当调度器找到能够满足 Pod 的其他调度请求的节点时,调度器会遍历节点满足的所有的偏好性规则, 并将对应表达式的 weight 值加和。

最终的加和值会添加到该节点的其他优先级函数的评分之上。 在调度器为 Pod 作出调度决定时,总分最高的节点的优先级也最高。

[root@k8s-master1 node]# kubectl get nodes --show-labels |grep -E 'app|apps'
k8s-master3   Ready    <none>   35d   v1.22.1   app=host1,apps=host2,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,ingress=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master3,kubernetes.io/os=linux,topology.kubernetes.io/zone=antarctica-east1
k8s-node1     Ready    <none>   53d   v1.22.1   another-node-label-key=another-node-label-value,app.kubernetes.io/instance=tomcat,app.kubernetes.io/managed-by=Helm,app.kubernetes.io/name=tomcat,app.kubernetes.io/version=10.1.15,app=host1,apps=host1,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,helm.sh/chart=tomcat-10.11.0,ingress=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux,pod-template-hash=7b7447795c,topology.kubernetes.io/zone=antarctica-east1

|节点| 标签 |
|--|--|
|  k8s-node1| app=host1,apps=host1 |
|  k8s-master3| app=host1,apps=host2 |


[root@k8s-master1 node]# cat pod-with-node-anti-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: with-affinity-anti-affinity
  namespace: app
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: app
            operator: In
            values:
            - host1
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: apps
            operator: In
            values:
            - host1
      - weight: 50
        preference:
          matchExpressions:
          - key: apps
            operator: In
            values:
            - host2
  containers:
  - name: with-node-affinity
    image: nginx
因为apps=host2的权重比较高,所以容器落在了k8s-master3的宿主机上
[root@k8s-master1 node]# kubectl get pods -n app -o wide
NAME                          READY   STATUS    RESTARTS   AGE     IP              NODE          NOMINATED NODE   READINESS GATES
nginx                         1/1     Running   0          88m     10.10.135.202   k8s-master3   <none>           <none>
with-affinity-anti-affinity   1/1     Running   0          2m46s   10.10.135.205   k8s-master3   <none>           <none>

如果存在两个候选节点,都满足 preferredDuringSchedulingIgnoredDuringExecution 规则, 其中一个节点具有标签 label-1:key-1,另一个节点具有标签 label-2:key-2, 调度器会考察各个节点的 weight 取值,并将该权重值添加到节点的其他得分值之上。

Pod 间亲和性与反亲和性
Pod 间亲和性与反亲和性的类型
与节点亲和性类似,Pod 的亲和性与反亲和性也有两种类型:
1.requiredDuringSchedulingIgnoredDuringExecution
2.preferredDuringSchedulingIgnoredDuringExecution

例如,你可以使用 requiredDuringSchedulingIgnoredDuringExecution 亲和性来告诉调度器, 将两个服务的 Pod 放到同一个云提供商可用区内,因为它们彼此之间通信非常频繁。 类似地,你可以使用 preferredDuringSchedulingIgnoredDuringExecution 反亲和性来将同一服务的多个 Pod 分布到多个云提供商可用区中。

要使用 Pod 间亲和性,可以使用 Pod 规约中的 .affinity.podAffinity 字段。 对于 Pod 间反亲和性,可以使用 Pod 规约中的.affinity.podAntiAffinity 字段。

Pod 亲和性示例

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: topology.kubernetes.io/zone
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: topology.kubernetes.io/zone
  containers:
  - name: with-pod-affinity
    image: registry.k8s.io/pause:2.0

本示例定义了一条 Pod 亲和性规则和一条 Pod 反亲和性规则。Pod 亲和性规则配置为 requiredDuringSchedulingIgnoredDuringExecution,而 Pod 反亲和性配置为 preferredDuringSchedulingIgnoredDuringExecution。

亲和性规则规定,只有节点属于特定的 区域 且该区域中的其他 Pod 已打上 security=S1 标签时,调度器才可以将示例 Pod 调度到此节点上。 例如,如果我们有一个具有指定区域(称之为 “Zone V”)的集群,此区域由带有 topology.kubernetes.io/zone=V 标签的节点组成,那么只要 Zone V 内已经至少有一个 Pod 打了 security=S1 标签, 调度器就可以将此 Pod 调度到 Zone V 内的任何节点。相反,如果 Zone V 中没有带有 security=S1 标签的 Pod, 则调度器不会将示例 Pod 调度给该区域中的任何节点。

反亲和性规则规定,如果节点属于特定的 区域 且该区域中的其他 Pod 已打上 security=S2 标签,则调度器应尝试避免将 Pod 调度到此节点上。 例如,如果我们有一个具有指定区域(我们称之为 “Zone R”)的集群,此区域由带有 topology.kubernetes.io/zone=R 标签的节点组成,只要 Zone R 内已经至少有一个 Pod 打了 security=S2 标签, 调度器应避免将 Pod 分配给 Zone R 内的任何节点。相反,如果 Zone R 中没有带有 security=S2 标签的 Pod, 则反亲和性规则不会影响将 Pod 调度到 Zone R。

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值