Kubernetes Node Affinity
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes Node Affinity相关的知识,希望对你有一定的参考价值。
参考技术A可以限制Pods在特定节点上运行,也可以优先调度到特定节点。有几种方式可以实现这个功能,它们都使用选择标签的方式完成。通常情况下这些限制是没必要的,k8s会自动实现合理的调度(例如,pods在集群中调度时,不会被调度到资源不足的节点上)。但是,有些场景下,希望对运行pod的节点进行限制,如需要将pod调度到磁盘为SSD的节点上,或将两个不同的服务但需要经常通信的pod调度到同一个zone。
nodeSelector 是最简单的一种实现方式,是podSpec的一个字段,它指定了一个key-value的键值对。为了使pods能够在该节点上运行,该节点必须有所有需要的键值对作为标签(节点也可以有其它的标签)。
第一步:节点打标签
第二步:配置文件中添加nodeSelector 字段
第三步:验证
nodeSelector 提供了一种简单的方式将pods调度到具有特定标签的节点上。
Affinity and anti-affinity 现在是beta版,大大拓展了可以表达的约束类型。相对于nodeSelector主要有以下几个优点:
Affinity特征有两种类型,“node affinit” 和 “inter-pod affinity/anti-affinity”。 Node affinity跟nodeSelector很像,但有以上两个优点。inter-pod affinity/anti-affinity是对pod的标签进行限制,具有以上三条特性。
nodeSelector 可以正常工作,最终将会被弃用,因为node affinity可以表示它可以表示的所有内容。
Kubernetes 1.2中,node affinity是alpha版。 Node affinity概念上与nodeSelector相似,通过选择标签的方式,可以限制pod被调度到特定的节点上。
目前支持两种类型的node affinity, requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution ,可以他们看作“hard(强制)”和“soft(非强制)”。某种意义上,前者指定了要将pod调度到节点上必须满足的规则(像nodeSelector,但使用了更具表现力的语法),而后者试图调度到特定的节点但不能保证一定会调度到该节点。其中,“IgnoredDuringExecution”表示如果在pod运行时节点的标签发生改变导致无法满足pods创建时使用的调度规则,pod会继续在该节点上运行,这点与nodeSelector相似。将来会提供 requiredDuringSchedulingRequiredDuringExecution ,与 requiredDuringSchedulingIgnoredDuringExecution 一样,但是会迁移节点上的pod以满足其node affinity 的规则。
下面有一个使用node affinity的例子:
这条规则表示,pod可以被调度到key为“kubernetes.io/e2e-az-name”,值为“e2e-az1”或“e2e-az2”的节点。另外,在满足该条件的节点中,优先使用具有“another-node-label-key”标签,且至为“another-node-label-value”的节点。
上面的例子使用了“In”操作符,node affinity语法支持以下集中操作符:In, NotIn, Exists, DoesNotExist,Gt,Lt。没有明确的“node anti-affinity”概念,但是NotIn和DoesNotExist可以表示该含义。
如果同时指定了 nodeSelector 和 nodeAffinity ,要调度的节点必须同时满足这两点规则。
如果指定了与多条与nodeSelector相关的表达式,pod将会被调度到同时满足这几条表达式的节点。
Kubernetes 1.4中提出了inter-pod和anti-affinity的概念。inter-pod affinity和anti-affinity允许根据已在节点上运行的pod上的标签来限制pod可以调度到哪些节点,而不是基于节点上的标签。
规则的形式是,pod应该(anti-affinity表示不应该)运行在X中,如果X已经运行了一个或多个满足规则Y的pod。Y表示为LabelSelector具有相关namespace的列表(或所有namespace)。与节点不同,pod是属于不同namespace的(因此pod上的标签是隐含的namespace),pod 标签上的label selector必须制定该selector应用到哪个namespace。从概念上来说,X是一个拓扑域,如节点,机架,云提供商域等。
如node affinity,目前支持两种类型的pod affinity和anti-affinity: requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution , requiredDuringSchedulingIgnoredDuringExecution 会将service A和service B的pod调度到同一个zone,因为他们彼此通信很多; preferredDuringSchedulingIgnoredDuringExecution ,anti-affinity会把同一个service的pods调度到不同的zone(强制要求是没有意义的,因为pod的数量要大于zone)。
下面有一个使用pod affinity的例子:
这个例子中定义了affinity和anti-affinity规则。podAffinity是 requiredDuringSchedulingIgnoredDuringExecution ,podAntiaffinity是 preferredDuringSchedulingIgnoredDuringExecution 。pod affinity 规则表示,该pod只能运行在集群中的特定节点上,这些节点已经至少运行一个具有”security=S1“标签的pod,并且和这些节点在同一个zone(更确切的说,这个pod可以运行在节点N上,如果节点N有key为 failure-domain.beta.kubernetes.io/zone 和值为V的标签,同时该节点上运行着一个具有“security=S1”标签的pod)。pod anti-affinity规则表示,如果该节点已经运行着具有“security=S2”标签的pod,将不会优先调度到该节点。(如果 topologyKey 是 failure-domain.beta.kubernetes.io/zone ,该pod也不会被优先调度到具有“security=S2”标签的节点所在的zone)。
和node affinity 一样,pod affinity 合法的操作符有In, NotIn, Exists, DoesNotExist, Gt, Lt。
原则上, topologyKey 可以是任意标签,为了性能考虑只允许一些有限的topologyKey,默认情况下,有以下几个:
除了 labelSelector 和 topologyKey ,也可以选择性的指定一些labelSelector需要匹配的namespace。如果忽略namespace,默认匹配affinity/anti-affinity定义的规则指定的namespace。如果定义了namespace,意味着所有namespace都可以。
必须满足所有与 requiredDuringSchedulingIgnoredDuringExecution 相关的表达式才能将pod调度到某个节点。
node affinity/anti-affinity 设计文档
inter-pod affinity/anti-affinity设计文档
kubernetes---affinity--traint---tr
pod的affinity , 硬亲和性 , 软亲和性
preferredDuringSchedulingIgnoredDuringExecution 软亲和性表示期望值
preferredDuringSchedulingIgnoredDuringExecution 硬亲和性表示必须在一起,必须满足要求
labelSelector
namespaces
topologyKey: 位置拓扑键,用键来判定位置
以上是关于Kubernetes Node Affinity的主要内容,如果未能解决你的问题,请参考以下文章
Kubernetes命令kubectl 在Node节点上的使用
Node.js & Kubernetes Graceful Shutdown