如何在 Kubernetes 中对大量非活动 Pod 有效地使用 CPU?

问题描述

我有很多服务。一天中,少数服务忙了大约十个小时,而其他大部分服务都处于空闲状态或使用少量cpu

以前我把所有的服务都放在一个虚拟机里,有两个cpu,按cpu使用情况进行缩放,最忙的时候有两个虚拟机,但大多数时候只有一个

服务 实例 一天的忙碌时间 cpu 忙时
(核心/服务)
空闲时的cpu
(核心/服务)
繁忙的服务 2 8~12 小时 0.5~1 0.1~0.5
繁忙的服务 2 8~12 小时 0.3~0.8 0.1~0.3
非活动服务 30 0~1 小时 0.1~0.3

现在我想把它们放到kubernetes中,每个节点有两个cpu,并使用节点自动伸缩和HPA,为了使节点自动伸缩,我必须为所有服务设置requests cpu,这正是我遇到的困难.

这是我的设置。

服务 实例 忙的时候 请求 cpu
cpu/服务)
总请求cpu
繁忙的服务 2 8~12 小时 300m 600m
繁忙的服务 2 8~12 小时 300m 600m
非活动服务 30 0~1 小时 100m 3000 米

注意:inactive service requests cpu设置为100m,因为忙的时候小于100m就不好用了。

这样设置,节点数总是大于三个,成本太高。我觉得问题是这些服务虽然需要100m的cpu才能正常工作,但大部分都是闲置的。

我真的希望所有的服务都可以自动伸缩,我认为这是kubernetes的好处,它可以帮助我更灵活地分配pod。我的想法错了吗?我不应该为不活动的服务设置请求 cpu 吗?

即使我忽略不活动的服务。我发现 kubernetes 经常有两个以上的节点。如果我有更多的活跃服务,即使在非高峰时段,请求 cpu 也会超过 2000m。有什么解决办法吗?

解决方法

我把所有的服务都放在一个有两个cpu的虚拟机里,按cpu的使用情况进行缩放,最忙的时候有两个虚拟机,但大多数时候只有一个。

首先,如果您有任何可用性要求,我建议您始终至少拥有两个节点。如果您只有一个节点并且发生了一次崩溃(例如硬件故障或内核崩溃),则需要几分钟的时间才能检测到这一点,而新节点则需要几分钟的时间才能启动。

inactive service requests cpu设置为100m,因为忙的时候小于100m就不好用了。

我觉得问题是这些服务虽然需要100m的cpu才能正常工作,但大多都是闲置的。

CPU 请求是保证的预留资源量。在这里,您为几乎空闲的服务预留了太多资源。将 CPU 请求设置得更低,可能低至 20m 甚至 5m?但是由于这些服务在繁忙时段需要更多资源,因此请设置更高的限制,以便容器可以“爆裂”并使用 Horizontal Pod Autoscaler。使用 Horizo​​ntal Pod Autoscaler 时,将创建更多副本,并且流量将在所有副本之间进行负载平衡。另见Managing Resources for Containers

这对于你的“繁忙的服务”也是如此,保留更少的 CPU 资源并更积极地使用 Horizo​​ntal Pod Autoscaling,以便在高负载时将流量分散到更多节点,但在流量低时可以缩减并节省成本.

我真的希望所有的服务都可以自动伸缩,我认为这是kubernetes的好处,它可以帮助我更灵活地分配pod。我的想法错了吗?

是的,我同意你的看法。

我不应该为不活动的服务设置请求 CPU 吗?

总是为 requestlimit 设置一些值是一个好习惯,至少对于生产环境是这样。如果没有资源请求,调度和自动缩放将无法正常工作。

如果我有更多的活跃服务,即使在非高峰时段,请求cpu也会超过2000m。有什么解决办法吗?

一般来说,尝试使用较低的资源请求,并更积极地使用 Horizo​​ntal Pod Autoscaling。对于您的“繁忙服务”和“非活动服务”都是如此。

我发现 kubernetes 经常有两个以上的节点。

是的,这有两个方面。

如果您只使用两个节点,那么您的环境可能很小,Kubernetes 控制平面可能包含更多节点,并且是成本的主要部分。对于非常小的环境,Kubernetes 可能很昂贵,而且使用它会更有吸引力,例如无服务器替代方案,如 Google Cloud Run

第二,可用性。在突然崩溃的情况下,至少有两个节点是很好的,例如硬件故障或内核崩溃,以便您的“服务”仍然可用,同时节点自动缩放器扩展新节点。对于 Deployment副本 数量也是如此,如果可用性很重要,请至少使用两个副本。当你例如drain a node 用于维护或节点升级,Pod 将被驱逐 - 但不会首先在不同的节点上创建。控制平面将检测到 Deployment(技术上为 ReplicaSet)的副本数少于所需数量并创建一个新的 pod。但是当在新节点上创建新的 Pod 时,容器镜像会在 Pod 运行之前先被拉取。为避免在这些事件期间停机,请至少为您的 DeploymentPod Topology Spread Constraints 使用两个副本,以确保这两个副本在不同节点上运行。


注意:您可能会遇到与 How to use K8S HPA and autoscaler when Pods normally need low CPU but periodically scale 相同的问题,并且应该通过即将推出的 Kubernetes 功能来缓解:KEP - Trimaran: Real Load Aware Scheduling