介绍PodTopologySpread
作者: 黄炜(IBM),奥尔多·卡尔奎孔多(Google)
在整个集群中管理Pod分发非常困难。著名的Kubernetes Pod亲和力和反亲和力功能,可对Pod放置进行一些控制 在不同的拓扑中。但是,这些功能只能解决部分Pod 分发用例:将无限Pod放置到单个拓扑中,或 不允许两个Pod共同位于同一拓扑中。在这两者之间 在极端情况下,通常需要将Pod在整个 拓扑,以实现更好的群集利用率和高可用性 applications.
PodTopologySpread调度插件(最初建议为EvenPodsSpread) 旨在填补这一空白。我们在1.18中将其提升为Beta。
API 变更
A new field topologySpreadConstraints
is introduced in the Pod's spec API :
spec:
topologySpreadConstraints:
- maxSkew: <integer>
topologyKey: <string>
当不满意: <string>
labelSelector: <object>
由于此API已嵌入Pod的规范中,因此您可以在所有 高级工作负载API,例如Deployment,DaemonSet,StatefulSet等。
让我们看一个集群示例,以了解此API。
- labelSelector 用于查找匹配的Pod。对于每种拓扑,我们计算 与此标签选择器匹配的Pod数。在上面的例子中,给出 labelSelector为“ app:foo”,“ zone1”中的匹配数为2;而 “ zone2”中的数字为0。
- topologyKey 是在“节点”标签中定义拓扑的键。在 在上面的示例中,如果某些节点具有标签,则将它们分组为“ zone1” “ zone = zone1”标签;而其他的则分组为“ zone2”。
- maxSkew 描述Pod可以最大程度地达到不均匀的程度
分散式。在上面的示例中:
- 如果我们将传入的Pod放入“ zone1”,则“ zone1”上的时滞将变为3(3 与“ zone1”匹配的广告连播;在“ zone2”上匹配的0个Pod的全局最小值), 违反了“ maxSkew:1”约束。
- 如果将传入Pod放置到“ zone2”,则“ zone2”上的时滞为0(1 Pod 在“ zone2”中匹配; 1个Pod的全局最小值与“ zone2”本身匹配), 满足“ maxSkew:1”约束。请注意,偏斜为 计算每个合格节点,而不是全局偏斜。
- 当不满意 指定当不能满足“ maxSkew”时,什么
应该采取的行动:
DoNotSchedule
(默认值)告诉调度程序不要调度它。它是 hard constraint.ScheduleAnyway
告诉调度程序在优先级排序时仍然调度它 减少偏斜的节点。这是一个软约束。
高级用法
正如功能名称“ PodTopologySpread”所暗示的,此功能的基本用法 是以绝对平均的方式(maxSkew = 1)或相对 even manner (maxSkew>=2). See the 官方 document更多细节。
除了这种基本用法之外,还有一些高级用法示例 使您的工作负载受益于高可用性和群集利用率。
与NodeSelector / NodeAffinity一起使用
您可能发现我们没有“ topologyValues”字段来限制 Pod将要安排的拓扑。默认情况下, 搜索所有节点并按“ topologyKey”将其分组。有时这可能不是 理想情况。例如,假设有一个集群,其节点标记为 “ env = prod”,“ env = staging”和“ env = qa”,现在您想将Pod均匀地放置到 跨区域的“ qa”环境,是否可能?
答案是肯定的。您可以利用NodeSelector或NodeAffinity API 规范。 在后台,PodTopologySpread功能将 荣誉 并计算 满足选择器的节点之间的传播约束。
As illustrated above, you can specify spec.affinity.nodeAffinity
to limit the
将“搜索范围”设置为“ qa”环境,在该范围内,
调度到一个满足topologySpreadConstraints的区域。在这个
case, it's "zone2".
多个拓扑扩展约束
了解一个拓扑拓朴约束的工作原理很直观。 多个TopologySpreadConstraints是什么情况?在内部,每个 TopologySpreadConstraint是独立计算的,结果集将 合并以生成最终结果集-即合适的节点。
在下面的示例中,我们想将Pod调度到具有2的集群 同时要求:
- 将Pod与Pod跨区域均匀放置
- 跨节点将Pod和Pod均匀放置
对于第一个约束,zone1中有3个Pod,zone2中有2个Pod,因此 只能将传入的Pod放入zone2以满足“ maxSkew = 1”的约束。在 换句话说,结果集是nodeX和nodeY。
对于第二个约束,nodeB和nodeX中的Pod太多,因此 传入的Pod只能放入nodeA和nodeY。
现在我们可以得出结论,唯一合格的节点是nodeY-从 {nodeX,nodeY}(来自第一个约束)和{nodeA,nodeY}(来自 second constraint).
多个TopologySpreadConstraints功能强大,但请务必了解 与前面的“ NodeSelector / NodeAffinity”示例的区别:一个是 独立计算结果集,然后相互关联;而另一个是 根据节点的过滤结果计算topologySpreadConstraints constraints.
您可以在所有topologySpreadConstraints中使用“硬”约束,而不必 还结合使用“硬”约束和“软”约束来遵守更多 不同的集群情况。
注意: 如果将两个TopologySpreadConstraints应用于同一{topologyKey, 当不满意}元组时,Pod的创建将被阻止,返回一个 validation error.
PodTopologySpread默认值
PodTopologySpread是Pod级别的API。因此,要使用功能,工作量
作者需要了解集群的基础拓扑,然后
specify proper topologySpreadConstraints
in the Pod spec for every workload.
虽然Pod级API提供了最大的灵活性,但也有可能
指定集群级别的默认值。
默认的PodTopologySpread约束允许您为所有对象指定传播 为集群量身定制的拓扑结构。约束可以是 由操作员/管理员在PodTopologySpread插件参数中指定 计划配置文件配置 API 启动时 kube-scheduler.
配置示例如下所示:
apiVersion: kubescheduler.config.k8s.io/v1alpha2
kind: KubeSchedulerConfiguration
profiles:
pluginConfig:
- name: PodTopologySpread
args:
defaultConstraints:
- maxSkew: 1
topologyKey: example.com/rack
当不满意: ScheduleAnyway
配置默认约束时,标签选择器必须保留为空。 kube-scheduler将从Pod的成员推断标签选择器 服务,ReplicationControllers,副本集或StatefulSet。豆荚可以 始终通过提供自己的默认约束来覆盖默认约束 PodSpec.
注意: 使用默认的PodTopologySpread约束时,建议禁用 旧的DefaultTopologySpread插件。
包起来
PodTopologySpread允许您为工作负载定义扩展约束 具有灵活且富有表现力的Pod级API。过去,工作量作者使用 Pod AntiAffinity规则强制或提示调度程序每个运行一个Pod 拓扑域。相反,新的PodTopologySpread约束允许Pod 指定可能需要(硬)或需要(软)的偏斜级别。的 功能可以与节点选择器和节点相似性配对以限制 传播到特定领域。可以为 不同的拓扑,例如主机名,区域,区域,机架等。
最后,集群运营商可以定义默认约束以应用于所有 豆荚。这样,Pods无需知道其基础拓扑 cluster.