β

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 主机标签 In,NotIn,Exists,DoesNotExist,Gt,Lt 不支持 决定Pod可以部署在哪些主机上
podAffinity Pod标签 In,NotIn,Exists,DoesNotExist 支持 决定Pod可以和哪些Pod部署在同一拓扑域
PodAntiAffinity Pod标签 In,NotIn,Exists,DoesNotExist 支持 决定Pod不可以和哪些Pod部署在同一拓扑域

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

使用场景介绍

nodeAffinity使用场景

podAffinity使用场景

podAntiAffinity使用场 景:

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

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

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

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

使用示例

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

{“name” : “MatchInterPodAffinity”}

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

qinhe01

其中每个主机上都有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,结果如下:

qinhe02

从结果可以看出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,结果如下:

qinhe03

所有创建的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,结果如下:

qinhe04

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

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

总结

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

 
作者:天云软件_北京天云融创_云计算_云平台
北京天云融创软件技术有限公司_云系统专家
原文地址:Kubernetes调度之亲和性和反亲和性, 感谢原作者分享。

发表评论