Kubernetes和JVM内存设置

huangapple go评论86阅读模式
英文:

Kubernetes and JVM memory settings

问题

在具有众多微服务的 Kubernetes 集群中,其中之一专门用于运行 Java Virtual Machine (JVM),该 JVM 运行着一个 Java 1.8 数据处理应用。

直到最近,运行在该 JVM Pod 中的作业消耗的内存不到 1GB,因此该 Pod 被设置为最大内存为 4GB,JVM 没有任何显式的堆大小设置。

现在一些新的数据需要大约 2.5GB 的内存,包括 JVM 在内的整个 Pod(根据 kubernetes top 命令报告,在增加到 8GB 的内存限制后启动),但是在将内存限制设置为 4GB 后,Pod 在启动后不久就崩溃了。

使用类似于 -Xms256m -Xmx3072m 这样的堆大小范围,限制为 4GB,并没有解决问题。实际上,现在 Pod 甚至无法启动。

有没有办法调整 JVM 的参数以适应所需的 2.5GB 内存,而不增加 Pod 的最大内存限制 4GB 呢?

英文:

In a Kubernetes cluster with numerous microservices, one of them is used exclusively for a Java Virtual Machine (JVM) that runs a Java 1.8 data processing application.

Up to recently, jobs running in that JVM pod consumed less than 1 GB of RAM, so the pod has been setup with 4 GB of maximum memory, without any explicit heap size settings for the JVM.

Some new data now require about 2.5 GB for the entire pod, including the JVM (as reported by the kubernetes top command, after launching with an increased memory limit of 8 GB), but the pod crashes soon after starting with a limit of 4 GB.

Using a head size range like -Xms256m -Xmx3072m with a limit of 4 GB does not solve the problem. In fact, now the pod does not even start.

Is there any way to parameterize the JVM for accommodating the 2.5 GB needed, without increasing the 4 GB maximum memory for the pod?

答案1

得分: 26

默认情况下,如果不指定 -Xmx,"最大堆" 大小为主机 RAM 的 1/4(25%)。
JDK 10 在容器支持方面进行了改进,它使用容器的 RAM 限制,而不是底层主机。正如 @David Maze 指出的那样,这已经被反向移植到 JDK 8。

假设您有一个足够新版本的 JDK 8,您可以使用 -XX:MaxRAMPercentage 来修改用于最大堆的默认总 RAM 百分比。因此,您可以使用 -XX:MaxRAMPercentage=75.0 来替代 -Xmx 的设置。也可参阅 https://blog.arkey.fr/2020/10/27/maxrampercentage-is-not-what-i-wished-for/

这是一个使用 Alpine JDK Docker 镜像的示例:https://hub.docker.com/_/openjdk(特别参见 "使 JVM 遵循 CPU 和 RAM 限制" 部分)。

# 此示例在具有 2GB RAM 的主机上运行
docker run --mount type=bind,source="$(pwd)",target=/pwd -it openjdk:8

# 使用 MaxRAMPercentage=50 运行 => 使用可用 RAM 的一半作为 "最大堆" 大小
root@c9b0b4d9e85b:/# java -XX:+PrintFlagsFinal -XX:MaxRAMPercentage=50.0 -version | grep -i maxheap
    uintx MaxHeapFreeRatio                          = 100                                 {manageable}
    uintx MaxHeapSize                              := 1044381696                          {product}
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)

# 在没有指定 MaxRAMPercentage 的情况下运行 => 默认使用 RAM 的 25%
root@c9b0b4d9e85b:/# java -XX:+PrintFlagsFinal -version | grep -i maxheap
    uintx MaxHeapFreeRatio                          = 100                                 {manageable}
    uintx MaxHeapSize                              := 522190848                           {product}
openjdk version "1.8.0_265"
英文:

The default "max heap" if you don't specify -Xmx is 1/4 (25%) of the host RAM.
JDK 10 improved support for containers in that it uses container's RAM limits instead of underlying host. As pointed by @David Maze this has been backported to JDK 8.

Assuming you have a sufficiently recent version of JDK 8, you can use -XX:MaxRAMPercentage to modify the default percentage of total RAM used for Max heap. So instead of specifying -Xmx you can tell, e.g. -XX:MaxRAMPercentage=75.0. See also https://blog.arkey.fr/2020/10/27/maxrampercentage-is-not-what-i-wished-for/

Here's an example using alpine JDK docker image: https://hub.docker.com/_/openjdk (see section "Make JVM respect CPU and RAM limits" in particular).

# this is running on the host with 2 GB RAM
docker run --mount type=bind,source="$(pwd)",target=/pwd -it openjdk:8

# running with MaxRAMPercentage=50 => half of the available RAM is used as "max heap"
root@c9b0b4d9e85b:/# java -XX:+PrintFlagsFinal -XX:MaxRAMPercentage=50.0 -version | grep -i maxheap
    uintx MaxHeapFreeRatio                          = 100                                 {manageable}
    uintx MaxHeapSize                              := 1044381696                          {product}
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)

# running without MaxRAMPercentage => default 25% of RAM is used
root@c9b0b4d9e85b:/# java -XX:+PrintFlagsFinal -version | grep -i maxheap
    uintx MaxHeapFreeRatio                          = 100                                 {manageable}
    uintx MaxHeapSize                              := 522190848                           {product}
openjdk version "1.8.0_265"

答案2

得分: 0

在我的K8s设置中,我正在使用Consul来管理Pod配置。以下是一个用于实时覆盖JVM设置的命令。这与项目相关,但如果您正在使用Consul进行配置,它可能会给您一些提示。

kubectl -n <namespace> exec -it consul-server -- bash -c "export CONSUL_HTTP_ADDR=https://localhost:8500 && /opt/../home/bin/bootstrap-config --token-file /opt/../config/etc/SecurityCertificateFramework/tokens/consul/default/management.token kv write config/processFlow/jvm/java_option_xmx -Xmx8192m"
英文:

In my K8s setup, I am using consul to manage the pod configuration. Here is a command to override the jvm setting on the fly. It is a pretty much project specific but it might give you a hint if you are using consul for configuration.

kubectl -n &lt;namespace&gt; exec -it consul-server -- bash -c &quot;export CONSUL_HTTP_ADDR=https://localhost:8500 &amp;&amp; /opt/../home/bin/bootstrap-config --token-file /opt/../config/etc/SecurityCertificateFramework/tokens/consul/default/management.token kv write config/processFlow/jvm/java_option_xmx -Xmx8192m&quot;

huangapple
  • 本文由 发表于 2020年10月18日 07:15:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/64408245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定