Kubernetes调度之亲和性和反亲和性

文章目录

[隐藏]

  • 背景
  • 使用场景
  • 使用示例
  • 总结
背景

Kubernetes中的调度策略可以大致分为两种,一种是全局的调度策略,要在启动调度器时配置,包括kubernetes调度器自带的各种predicates和priorities算法,具体可以参看文章《Kubernetes调度详解》;另一种是运行时调度策略,包括nodeAffinity(主机亲和性),podAffinity(POD亲和性)以及podAntiAffinity(POD反亲和性)。

nodeAffinity 主要解决POD要部署在哪些主机,以及POD不能部署在哪些主机上的问题,处理的是POD和主机之间的关系。

podAffinity 主要解决POD可以和哪些POD部署在同一个拓扑域中的问题(拓扑域用主机标签实现,可以是单个主机,也可以是多个主机组成的cluster、zone等。),podAntiAffinity主要解决POD不能和哪些POD部署在同一个拓扑域中的问题。它们处理的是Kubernetes集群内部POD和POD之间的关系。

三种亲和性和反亲和性策略的比较如下表所示:

本文主要介绍如何使用亲和性和反亲和性做资源调度。

使用场景

nodeAffinity使用场景 :

  • 将S1服务的所有Pod部署到指定的符合标签规则的主机上。
  • 将S1服务的所有Pod部署到除部分主机外的其他主机上。

podAffinity使用场景 :

  • 将某一特定服务的pod部署在同一拓扑域中,不用指定具体的拓扑域。
  • 如果S1服务使用S2服务,为了减少它们之间的网络延迟(或其它原因),把S1服务的POD和S2服务的pod部署在同一拓扑域中。

podAntiAffinity使用场 景:

  • 将一个服务的POD分散在不同的主机或者拓扑域中,提高服务本身的稳定性。
  • 给POD对于一个节点的独占访问权限来保证资源隔离,保证不会有其它pod来分享节点资源。
  • 把可能会相互影响的服务的POD分散在不同的主机上。

对于亲和性和反亲和性,每种都有三种规则可以设置:

RequiredDuringSchedulingRequiredDuringExecution :在调度期间要求满足亲和性或者反亲和性规则,如果不能满足规则,则POD不能被调度到对应的主机上。在之后的运行过程中,如果因为某些原因(比如修改label)导致规则不能满足,系统会尝试把POD从主机上删除(现在版本还不支持)。

RequiredDuringSchedulingIgnoredDuringExecution :在调度期间要求满足亲和性或者反亲和性规则,如果不能满足规则,则POD不能被调度到对应的主机上。在之后的运行过程中,系统不会再检查这些规则是否满足。

PreferredDuringSchedulingIgnoredDuringExecution :在调度期间尽量满足亲和性或者反亲和性规则,如果不能满足规则,POD也有可能被调度到对应的主机上。在之后的运行过程中,系统不会再检查这些规则是否满足。

使用示例

使用POD亲和性调度时要先开启Kubernetes调度器的MatchInterPodAffinity筛选功能,具体的操作方式是修改调度器的配置文件,在predicates中增加如下内容:

{"name": "MatchInterPodAffinity"}  

测试环境的主机信息如下:

其中每个主机上都有 beta.kubernetes.io/arch、beta.kubernetes.io/os、kubernetes.io/hostname这几个标签,在测试过程中把这些标签当做拓扑域使用。

nodeAffinity 使用示例:

使用nodeAffinity把POD部署到主机mesos-slave1和mesos-slave2上,yaml定义如下:

{    "nodeAffinity": {      "requiredDuringSchedulingIgnoredDuringExecution": {        "nodeSelectorTerms": [          {            "matchExpressions": [              {                "key": "kubernetes.io/hostname",                "operator": "In",                "values": [                  "mesos-slave1",                  "mesos-slave2"                ]              }            ]          }        ]      }    }  }  

创建一个有6个POD的RC,结果如下:

从结果可以看出POD被部署到了mesos-slave1和mesos-slave2上,mesos-slave3上没有部署POD。

podAffinity使用示例 :

使用kubernetes.io/hostname作为拓扑域,把pod创建在同一主机上。其中matchExpressions中填写内容对应到RC中POD自身的标签。可以通过修改需要匹配的标签内容来控制把一个服务中的POD和其它服务的POD部署在同一主机上。

yaml中的定义如下:

{    "podAffinity": {      "requiredDuringSchedulingIgnoredDuringExecution": [        {          "labelSelector": {            "matchExpressions": [              {                "key": "name",                "operator": "In",                "values": [                  "node-rc"                ]              }            ]          },          "topologyKey": "kubernetes.io/hostname"        }      ]    }  }  

创建一个有3个POD的RC,结果如下:

所有创建的POD集中在同一个主机上,具体的主机是哪个不需要指定。

podAntiAffinity 使用示例:

使用kubernetes.io/hostname作为拓扑域,把pod创建在不同主机上,每个主机上最多只有一个同类型的POD(同类型用标签区分)。其中matchExpressions中填写内容对应到RC中POD自身的标签。可以通过修改需要匹配的标签内容来控制把一个服务中的POD和其它服务的POD部署在不同主机上。

yaml中的定义如下:

{    "podAntiAffinity": {      "requiredDuringSchedulingIgnoredDuringExecution": [        {          "labelSelector": {            "matchExpressions": [              {                "key": "name",                "operator": "In",                "values": [                  "node-rc"                ]              }            ]          },          "topologyKey": "kubernetes.io/hostname"        }      ]    }  }  

创建一个有4个POD的RC,结果如下:

三个主机上都有一个POD运行,因为每个主机上最多只能运行一个这种类型的POD,所以有一个POD一直处于Pending状态,不能调度到任何节点。

上边的例子中可以通过修改topologyKey来限制拓扑域的范围,实现把相关服务部署在不同的容灾域等其它功能。

总结

Kubernetes提供了丰富的调度策略,包括静态的全局调度策略,以及动态的运行时调度策略,用户可以根据需要自由组合使用这些策略来实现自己的需求。在调度过程中,使用nodeAffnity决定资源可以部署在哪些主机上,使用podAffinity和podAntiAffinity决定哪些资源需要部署在同一主机(拓扑域)或者不能部署在同一主机。

原文出处:johng -> http://johng.cn/kubernetes-affinity-anti-affinity/

本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如果侵犯你的利益,请发送邮箱到 [email protected],我们会很快的为您处理。
超哥软件库 » Kubernetes调度之亲和性和反亲和性