以下是我正在处理的内容。我在GKE 上有3个节点池
- n1s1(3.75GB)
- n1s2(7.5GB)
- n14(15GB)
我的pod将需要以下任何内存请求。假设限制非常接近请求。
1GB, 2GB, 4GB, 6GB, 8GB, 10GB, 12GB, 14GB
如何最好地将pod与节点池关联以实现最大效率?
到目前为止,我有三个策略。
对于每个pod配置,确定"合法节点池">。这是在理想情况下可以容纳pod配置的最小节点池。因此,对于2GB的pod,它是n1S,但对于4GB的pod则是n1s2。
- 仅在其合法节点池上调度pod
- 仅在其合法节点池或高于该节点池的一个节点池上调度pod
- 仅在当前可以访问的任何节点池上调度pod
这些或任何其他策略中的哪一个将最大限度地减少资源浪费?
=======
为什么首先要有3个这样的池?您通常希望使用最大的实例类型,使每个节点的pods数低于110(这是默认的硬上限)。调度器的工作是为您优化打包,使用默认设置,它在这方面做得很好。
我将混合使用Taint和Tolerations以及Node亲和性。
Taint和Tolerance协同工作,以确保pod不会被调度到不合适的节点上。一个或多个污点被应用于一个节点;这标志着节点不应该接受任何不允许污点的pod。容差应用于pod,并允许(但不要求)pod调度到具有匹配污点的节点上。
您可以在节点kubectl taint nodes node1 key=value:NoSchedule
上设置污点
污点具有关键字
key
、值value
和污点效果NoSchedule
。这意味着没有吊舱能够调度到node1
上,除非它具有匹配的容忍度。
在编写pod
yaml时,您可以指定PodSpec
并添加容差,该容差将与在node1
上创建的污点相匹配,这将允许具有任一容差的pod
被调度到node1
上
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
或
tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"
Taints和Tolerance是一种灵活的方式,可以引导pods远离节点或驱逐不应该运行的pods。一些用例是
专用节点:如果您想将一组节点专用于特定用户集,您可以向这些节点添加污点(例如
kubectl taint nodes nodename dedicated=groupName:NoSchedule
),然后向它们的pod添加相应的容忍度(这可以通过编写自定义准入控制器来最容易地完成)。然后,具有容忍度的pod将被允许使用受污染的(专用)节点以及集群中的任何其他节点。如果您想将节点专用于和,并确保它们仅使用专用节点,那么您应该向同一组节点(例如dedicated=groupName
)添加一个类似于污点的标签,并且准入控制器应该额外添加一个节点亲和性,以要求pod只能调度到标有dedicated=groupName
的节点上。具有专用硬件的节点:在一个节点子集具有专用硬件(例如GPU)的集群中,最好将不需要专用硬件的pod从这些节点中移除,从而为稍后到达的确实需要专用硬件。这可以通过污染具有专用硬件(例如
kubectl taint nodes nodename special=true:NoSchedule
或kubectl taint nodes nodename special=true:PreferNoSchedule
)的节点并向使用专用硬件的pod添加相应的容忍度来实现。与专用节点的使用情况一样,使用自定义准入控制器应用容忍度可能是最简单的。例如,建议使用扩展资源来表示特殊硬件,用扩展资源名称污染特殊硬件节点,并运行ExtendedResourceToleration准入控制器。现在,由于节点受到污染,没有容忍度的pod将不会在它们上进行调度。但是,当您提交请求扩展资源的pod时,ExtendedResourceToleration
准入控制器将自动向pod添加正确的容忍度,并且该pod将在特殊硬件节点上进行调度。这将确保这些特殊的硬件节点专门用于请求此类硬件的pod,并且您不必手动为您的pod添加容忍度。基于污点的驱逐:当存在节点问题时,每个pod可配置的驱逐行为,下一节将对此进行描述。
对于node affinity
:
在概念上类似于
nodeSelector
–它允许您根据节点上的标签来约束pod有资格在哪些节点上进行调度。目前有两种类型的节点亲和性,称为
requiredDuringSchedulingIgnoredDuringExecution
和preferredDuringSchedulingIgnoredDuringExecution
。您可以将它们分别视为"硬"one_answers"软",因为前者指定了必须满足的规则,以便将pod调度到节点上(就像nodeSelector
一样,但使用了更具表达性的语法),而后者指定了调度器将尝试强制执行但不会保证的首选项。名称中的"IgnoredDuringExecution"部分意味着,与nodeSelector
的工作方式类似,如果节点上的标签在运行时发生变化,使得pod上的关联规则不再满足,则pod仍将继续在节点上运行。在未来,我们计划提供requiredDuringSchedulingRequiredDuringExecution
,它将与requiredDuringSchedulingIgnoredDuringExecution
一样,只是它将从不再满足pod的节点亲和性要求的节点中驱逐pod。因此,
requiredDuringSchedulingIgnoredDuringExecution
的一个示例是"仅在具有Intel CPU的节点上运行pod",preferredDuringSchedulingIgnoredDuringExecution
的一个实例是"尝试在故障区域XYZ中运行这组pod,但如果不可能,则允许一些pod在其他地方运行"。节点亲和性被指定为PodSpec中字段
affinity
的字段nodeAffinity
。新的节点仿射语法支持以下运算符:
In
、NotIn
、Exists
、DoesNotExist
、Gt
、Lt
。可以使用NotIn
和DoesNotExist
来实现节点反亲和行为,也可以使用节点污点来排斥特定节点的pod。如果同时指定
nodeSelector
和nodeAffinity
,则必须满足两者才能将pod调度到候选节点上。如果指定多个与
nodeAffinity
类型相关联的nodeSelectorTerms
,则只有在满足所有nodeSelectorTerms
的情况下,才能将pod调度到节点上。如果指定多个与
nodeSelectorTerms
关联的matchExpressions
,则如果满足matchExpressions
中的一个,则可以将pod调度到节点上。