在 Kubernetes 中,如何在空闲时将 Deployment 缩放为零

In Kubernetes, how can I scale a Deployment to zero when idle

我是 运行 Kubernetes 集群上的一个资源密集型服务,用于支持 CI 活动。只需要一个副本,但它会占用大量资源 (16 cpu),并且通常只在工作时间(工作日,大约上午 8 点至下午 6 点)需要。我的集群在云中运行并设置了实例自动缩放,因此如果此服务缩放为零,则可以终止该实例。

该服务是无法修改的第三方代码(嗯,不容易)。这是一个相当典型的 HTTP 服务,除了它的工作相当 CPU 密集。

有哪些选项可以在空闲时自动将此 Deployment 缩减为零?

我宁愿不设置在工作时间内扩展它的时间表 up/down,因为偶尔 CI 活动是在正常时间之外进行的。我希望缩放是动态的(例如,闲置超过 30 分钟时缩放为零,或传入连接到达时缩放为一)。

有几种方法可以实现这一点,可能最 "native" 的方法是将 Knative 与 Istio 结合使用。默认情况下,Kubernetes 允许您扩展到零,但是您需要一些可以根据 "input event" 处理扩展事件的东西,本质上是支持事件驱动架构的东西。

你可以在这里查看官方文档:https://knative.dev/docs/serving/configuring-autoscaling/

根据文档,目前它不支持 minReplicas=0。阅读此线程:-https://github.com/kubernetes/kubernetes/issues/69687。并正确设置 HPA,您可以使用此公式设置所需的 pod :-

desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]

您还可以根据 prometheus 指标设置 HPA link:-

https://itnext.io/horizontal-pod-autoscale-with-custom-metrics-8cb13e9d475

水平 pod 自动缩放器当前不允许将 minReplicas 字段设置为 0,因此自动缩放器永远不会缩小到零,即使 pods 没有做任何事情。允许 pods 的数量减少到零可以显着提高硬件的利用率。

当您 运行 服务每隔几个小时甚至几天才收到一次请求时,让它们一直 运行 是没有意义的,消耗资源可能是被其他 pods 使用。

但您仍然希望在收到客户请求时立即提供这些服务。

这就是所谓的空转和非空转。它允许 pods 提供某种服务的规模缩减为零。当有新的请求进来时,请求会被阻塞,直到pod被拉起,然后请求才最终转发给pod。

Kubernetes 目前还没有提供这个功能,但最终会提供。

实际上 Kubernetes 仅支持通过 API 调用缩放至零,因为 Horizo​​ntal Pod Autoscaler 仅支持缩减至 1 个副本。

无论如何,有一些 Operator 允许您通过拦截到达您的 pods 的请求或通过检查一些指标来超越该限制。

你可以看看Knative or Keda。 它们使您的应用程序成为无服务器的,并且它们以不同的方式实现。

Knative,通过 Istio 拦截请求,如果有一个活动的 pod 为它们服务,它会将传入的请求重定向到那个请求,否则它会触发缩放。

相比之下,Keda 最适合事件驱动架构,因为它能够检查预定义指标,例如延迟、队列长度或自定义指标(从 Prometheus 收集,用于示例)并触发缩放。

如果在同样预定义的 window 中满足预定义条件,两者都支持缩放到零。

希望对您有所帮助。

我最终实施了一个自定义解决方案:https://github.com/greenkeytech/zero-pod-autoscaler

与Knative相比,它更像是一个“玩具”项目,相当小,并且不依赖istio。它在我的用例中运行良好,但我不建议其他人在不愿意采用代码作为自己的代码的情况下使用它。