我有几个 Java 项目在使用 Kubernetes 管理的 Docker 容器中运行。我想启用基于 Kubernetes 提供的 CPU 的 Horizontal Pod Autoscaling(HPA),但我发现很难处理初始化容器时由 JVM 引起的初始 CPU 峰值。
我目前还没有在任何项目的 Kubernetes yaml 文件中设置 cpu 限制,这基本上意味着我让 pod 从环境中获取尽可能多的 CPU(我知道这是一个不好的做法,但它让我可以启动JVM Pod 在 30 秒内完成)。
这造成的问题是,在 pod 创建过程中的前 3-4 分钟内,CPU 使用率会急剧上升,如果我设置了自动缩放规则,它就会触发它。自动缩放的 Pod 将旋转并导致相同的峰值,并重新触发自动缩放,直到达到 Pod 的最大数量并且事情稳定下来。
我尝试在 kubernetes yaml 文件中设置 cpu 限制,但是如果我的项目需要的 cpu 数量不是那么大,因此通过将其设置为非过度杀伤量,会使我的 pod 在超过 5 分钟内旋转,这是不可接受的。
我还可以将自动缩放延迟增加到 10 分钟以上,但这是一个全局规则,也会影响我需要快速扩展的部署,因此这对我来说也不是一个可行的选择。
这是我的一个 Pod 的 CPU 和内存配置示例
env:
resources:
requests:
memory: "1300Mi"
cpu: "250m"
limits:
memory: "1536Mi"
我最近还迁移到了 Java 10,它应该针对容器化进行了优化。 任何建议或评论将不胜感激。 预先感谢。
编辑:
我还可以基于自定义的 prometheus 指标(如 http_requests)设置 hpa,但该选项将更难维护,因为有很多变量会影响 pod 可以处理的请求量。
取决于您的K8版本。
< 1.12
:--horizontal-pod-autoscaler-upscale-delay
标志或 HPAv2 中的自定义指标。 https://v1-11.docs.kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
=>1.12
:unReady
pod,从而减少自动更正。
https://github.com/kubernetes/kubernetes/pull/68068
更改 HPA 中的 CPU 样本清理。 如果出现以下情况,请忽略样本:
- Pod 正在初始化 - 距离由标志定义的开始 5 分钟
- Pod 尚未准备好
- Pod 已准备就绪,但自此以来尚未收集完整的指标窗口 过渡
- Pod 已初始化 - 由标志定义的开始后 5 分钟:
- Pod 在初始准备期后从未准备好。
这应该对你有帮助。
从 Kubernetes v1.27 开始,出现了一个新的 Alpha 功能,称为
InPlacePodVerticalScaling
。在此功能中,Pod 可以在创建 Pod 时请求更高的 CPU,然后可以将大小调整为正常。
您可以看一下:https://kubernetes.io/blog/2023/05/12/in-place-pod-resize-alpha/
要自动化此过程,您可以将其与 Kyverno 策略结合起来,如本文所示:https://piotrminkowski.com/2023/08/22/resize-cpu-limit-to-speed-up-java-startup-on- Kubernetes/