基于JVM堆内存的Kubernetes HPA

o0lyfsai  于 2022-11-07  发布在  Kubernetes
关注(0)|答案(1)|浏览(160)

我在Kubernetes集群上运行了一个openjdk:8映像。我添加了内存HPA(Horizontal Pod Autoscaling),它可以很好地向上扩展,但由于JVM不会将内存从堆释放回操作系统,因此Pod不会向下扩展。

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: image-server
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: image-server
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 60
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 60

解决这个问题的一个方法是使用正确的GC并让它释放内存,但由于JVM被设计为出于性能原因而不频繁地从堆中释放内存,这样做并不是一个好主意。有没有办法从Kubernetes中处理这个问题?比如,我们可以不检查操作系统的内存使用情况,而只是检查堆中的内存使用情况并据此进行缩放吗?

6za6bjd0

6za6bjd01#

在Kubernetes中扩展Java应用程序有点棘手。HPA只查看系统内存,正如所指出的,JVM通常不释放已提交的堆空间(至少不会立即释放)。
有两种主要的方法可以用来解决这个问题

1.调整JVM参数,使提交的堆更接近使用的堆

根据所使用的JVM和GC,调整选项可能会略有不同,但最重要的选项是

  • MaxHeapFreeRatio-已提交的堆中允许未使用的部分
  • GCTimeRatio-允许运行GC的频率(影响性能)
  • AdaptiveSizePolicyWeight-在计算新堆时如何权衡旧的和新的GC运行

给出这些参数的精确值并不容易,这是快速释放内存和应用程序性能之间的折衷。最佳设置将取决于应用程序的负载特性。
帕特里克Dillon写了一篇文章,由RedHat发表,名为Scaling Java containers,深入探讨了这个主题。

2.自定义缩放逻辑

除了使用HPA,您还可以创建自己的扩展逻辑,并将其作为定期运行的作业部署到Kubernetes中,以执行以下操作:
1.检查所有单元中的堆使用情况(例如,通过在单元中运行jstat)
1.如果达到最大阈值,则横向扩展新单元
1.如果达到最小阈值,则在pod中进行缩放
这种方法的好处是可以查看实际的堆使用情况,但需要一个自定义组件。
这方面的一个示例可以在Powercloudup的文章基于Kubernetes中的CPU/内存的自动缩放-第II部分中找到

相关问题