kubernetes 调度器是否支持反亲和性?

Does the kubernetes scheduler support anti-affinity?

我正在考虑在 CoreOS 集群上部署 Kubernetes,但我认为我 运行 陷入了某种交易破坏者的境地。

如果我只使用 CoreOS 和 fleet,我可以在单元文件中指定我希望某些服务不与其他服务 运行 在同一台物理机器上(反亲和性)。这对于高可用性来说是必不可少的。但是好像kubernetes还没有这个功能

在我的特定用例中,我将需要 运行 一些需要始终可用的 elasticsearch 机器集群。如果出于任何原因,kubernetes 决定在一台机器上为给定的 ES 集群安排我所有的 elasticsearch 节点容器(或者甚至是在一台机器上的大部分),并且那台机器挂掉了,那么我的 elasticsearch 集群也会随之挂掉.不能允许这种情况发生。

似乎有变通办法。我可以设置资源需求和机器规格,以便每台机器上只能容纳一个 elasticsearch 实例。或者我可能会以某种方式使用标签来指定某些 elasticsearch 容器应该在某些机器上运行。我也可以提供比必要更多的机器,以及比必要更多的 ES 节点,并假设 kubernetes 会将它们分散到足以合理确定高可用性的程度。

但这一切似乎都很尴尬。从资源管理的角度来看,仅指定所需的硬件和反关联性并让调度程序从那里进行优化要优雅得多。

那么 Kubernetes 是否以某种我找不到的方式支持反亲和性?或者有人知道它是否会很快出现吗?

或者我应该换个方式考虑这个问题吗?我必须编写自己的调度程序吗?

看起来 kubernetes 决定如何传播容器有几种方法,这些方法正在积极开发中。

首先,当然,任何机器上都必须有必要的资源,调度程序才能考虑在那里启动一个 pod。

之后,kubernetes 通过复制控制器传播 pods,试图将给定复制控制器创建的不同实例保存在不同的节点上。

似乎最近实现了一种考虑服务和各种其他参数的调度方法。 https://github.com/GoogleCloudPlatform/kubernetes/pull/2906 Though I'm not completely clear on exactly how to use it. Perhaps in coordination with this scheduler config? https://github.com/GoogleCloudPlatform/kubernetes/pull/4674

对我来说最有趣的问题可能是这些调度优先级中的 none 在缩小期间被考虑,只有扩大。 https://github.com/GoogleCloudPlatform/kubernetes/issues/4301 这有点大不了,随着时间的推移,你可能会发现 pods 的分布很奇怪,因为它们会保留在最初放置的位置。


总的来说,我认为目前我的问题的答案是,这是一个不断变化的 kubernetes 领域(正如 v1 之前的版本所预期的那样)。但是,看起来我需要的大部分内容都可以通过足够的节点自动完成,并正确使用复制控制器和服务。

Anti-Affinity 是指您不希望某些节点上的某些 pods 到 运行。对于目前的情况,我认为 TAINTS AND TOLERATIONS 可以派上用场。您可以使用污点标记节点,然后,只有那些明确容忍该污点的 pods 将被允许在该特定节点上 运行。

下面我将描述如何实现反亲和性概念:

  1. 污染任何节点。

    kubectl 污染节点 gke-cluster1-default-pool-4db7fabf-726z env=dev:NoSchedule

这里,env=dev 是 key:value 对或者这个节点的标签, NoSchedule 是描述不在此节点上调度任何 pod 的效果,除非具有特定的容忍度。

  1. 创建部署

    kubectl 运行 newdep1 --image=nginx

  2. 将与标签相同的标签添加到此部署的节点,以便此部署的所有 pods 都托管在此节点上,并且此节点不会托管任何其他 pod匹配标签。

    kubectl 标签deployments/newdep1env=dev

    kubectl scale deployments/newdep1 --replicas=5

    kubectl get pods -o wide

运行你会看到 newdep1 的所有 pods 都将 运行 在你的受感染节点上。