亲和性调度

2022-09-27 21:31:10 浏览数 (1)

文章目录
  • 简介
  • nodeAffinity 节点亲和性
  • podAffinity
    • 亲和性调度实例
    • 互斥性调度实例

简介

前面的 nodeSelector 调度略显生硬,如果场景是:某个 Pod 最好调度到磁盘大的节点上,如果暂时没有,小点也行,比方说数据库; 如果场景是:某个 Pod,坚决不能调度到某类节点上,其余无所谓,比如说负载均衡不能调度到不对外开放端口的节点上; 诸如此类…

关于这些,nodeSelector 就不太行了。


nodeAffinity 节点亲和性

目前有两种亲和性表达:

  • RequiredDuringScheduleIgnoreDuringExecution:调度时要求,执行时忽略。
  • PreferedDuringScheduleIgnoreDuringExecution:调度时最好有,执行时忽略。

这什么意思呢,以第一个为例,就是调度的时候必须要有我需要的标签,调度完运行时有没有无所谓了。 第二个就是在调度的时候最好有我要的标签,没有那退而求其次吧。

动手验证:那么 nodeSelector 的 Pod 所在的 Node 在 pod 调度完成之后被删除了标签会怎么样呢?

代码语言:javascript复制
apiVersion: v1
kind: pod
metadate:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringScheduleIgnoreDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/arch
            operator: In
            values:
            - ["amd64","arm"]
      preferedDuringScheduleIgnoreDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: disk-type
            operator: In
            values:
            - ssd
  containers:
  - name: with-node-affinity
    image: mysql

operator 的可选操作:

代码语言:javascript复制
In: label的值在某个列表中
NotIn:label的值不在某个列表中
Exists:某个label存在
DoesNotExist:某个label不存在
Gt:label的值大于某个值(字符串比较)
Lt:label的值小于某个值(字符串比较)
equal:label存在且值等于指定的值

注意事项:

  • 如果同时定义了nodeSelector和nodeAffinity,name必须两个条件都得到满足,pod才能最终运行在指定的node上。
  • 如果nodeAffinity指定了多个nodeSelectorTerms,那么其中一个能够匹配成功即可。
  • 如果在nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有matchExpressions才能运行该pod。

此外,我还发现了一个有趣的现象(因为这里没有一套模板,那么什么情况下字段能重复出现,什么情况下字段只有一次出现呢?在数组里可以重复出现,在字典里就出现一次。)


podAffinity

Pod 的亲和与互斥调度策略,从 1.4 版本开始引入,目的在于相关联的两种或多种 Pod 是否可以在同一个 拓扑域中共存或互斥,前者被称为 podAffinity,后者被称为 podAntiAffinity。 一个拓扑域由一些 Node 节点组成,这些 Node 节点通常有相同的地理空间坐标,在极端情况下,我们也可以认为一个 node 就是一个拓扑域。

k8s 内置了以下一些常用的默认拓扑域:

  • kubernetes.io/hostname
  • topology.kubernetes.io/region
  • topology.kubernetes.io/zone

pod 亲和性的具体做法是通过在 Pod 上定义增加 topylogyKey 属性,来声明对应的目标拓扑域内几种相关联的 Pod 要在一起或不在一起。


亲和性调度实例

代码语言:javascript复制
apiVersion: v1
metadate:
  name: pod-flag
  labels:
    security: "s1"
    app: "nginx"
  spec:
    containers:
    - name: nginx
      image: nginx
代码语言:javascript复制
apiVersion: v1
metadate:
  name: pod-anffinity
  spec:
    affinity:
      podAnffinity:
        requiredDuringSchedulingIgnoreDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - s1
         topologyKey: kubernetes.io/hostname 
    containers:
    - name: nginx2
      image: nginx

创建 pod 之后,可以看到两个 pod 在同一个 Node 上运行。


互斥性调度实例

代码语言:javascript复制
apiVersion: v1
metadate:
  name: pod-flag
  labels:
    security: "s1"
    app: "nginx"
  spec:
    containers:
    - name: nginx
      image: nginx
代码语言:javascript复制
apiVersion: v1
metadate:
  name: pod-anffinity
  spec:
    affinity:
      podAnffinity:
        requiredDuringSchedulingIgnoreDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - s1
          topologyKey: topologyKey.kubernetes.io/zone
      podAntiAnffinity:
        requiredDuringSchedulingIgnoreDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - nginx
           topologyKey: kubernetes.io/hostname
    containers:
    - name: nginx3
      image: nginx

这里要求这个 pod 和 security=s1 的 pod 在同一个 zone,但是和 app 为 nginx 的 pod 不为同一个 node,然后就会发现它没地方去了,因为我就一个 node hhhhh。。

0 人点赞