saowu's Blog

关于Jvm对容器环境内资源感知的支持

关于Jvm对容器环境内资源感知的支持
2023-06-26 · 4 min read
Kubernetes Docker Java

早期时候,容器内运行Java应用程序时,Jvm无法感知容器环境存在,所以对容器资源的限制比如内存或者cpu等都无法生效。原因是容器的资源管理使用了操作系统cgroup机制,但是Jvm无法感知cgroup。所以可能需要在Jvm以及Pod、Docker中指定两次内存限制。

Java SE 8 对容器内CPU和内存限制的支持

  • Java SE support for Docker CPU and memory limits:Java SE 8u131和JDK 9就开始对容器(即 Docker)环境中的 cgroup 内存限制的实验性支持。
  • Java™ SE Development Kit 10:Java SE 10开始改进 docker 容器检测和资源配置使用。
  • Java™ SE Development Kit 8, Update 191 (JDK 8u191): 从 Java SE 8u191 开始,Java 10 的大部分 cgroup 支持工作已向后移植到 Java 8。进一步的改进可能不一定会向后移植到 8。
    • -XX:+UseContainerSupport:JVM 已被修改为知道它正在 Docker 容器中运行,并将提取容器特定的配置信息,而不是查询操作系统。提取的信息是已分配给容器的 CPU 数量和总内存。Java 进程可用的 CPU 总数是根据任何指定的 cpu 集、cpu 份额或 cpu 配额计算得出的。此支持仅在基于 Linux 的平台上可用。这个新的支持默认启用 。禁用:-XX:-UseContainerSupport
    • 新增-XX:ActiveProcessorCount=${cpu_num}:此计数会覆盖 JVM 中的任何其他自动 CPU 检测逻辑。
    • 新增-XX:InitialRAMPercentage-XX:MaxRAMPercentage-XX:MinRAMPercentage:允许 Docker 容器用户对将用于 Java 堆的系统内存量进行更细粒度的控制。
  • Java™ SE Development Kit 8, Update 361 (JDK 8u361):修复JVM 在某些 cgroups v1 系统上将无法初始化的问题。

以上是截止文章发布时对容器环境资源的相关更新,以下内容是基于Java SE 8u371进行开启容器环境感知测试:

  • 根据以上内容可知,应该是默认开启容器环境感知的,但是不好使,排查后发现是什么实验特性,需要手动开启
$java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal
#部分输出
bool UseCGroupMemoryLimitForHeap = false {experimental} {default}
  • 于是开启实验特性,不好使,找不到memory.limit_in_bytes文件
-XX:+UnlockExperimentalVMOptions  -XX:+UseCGroupMemoryLimitForHeap/
OracleJDK 64-Bit Server VM warning: Unable to open cgroup memory limit file /sys/fs/cgroup/memory/memory.limit_in_bytes (No such file or directory)
  • 查看自己容器的cgroup版本,是v2
$stat -fc %T /sys/fs/cgroup
cgroup2fs
  • 尝试一下命令指定memory.max,内存读取确实好了,但是cpu还是感知不到。
-XX:MaxRAM=`cat /sys/fs/cgroup/memory.max`
  • 抛开上面全部的尝试,强制指定cpu和内存,嗯,好使~!
-XX:ActiveProcessorCount=2 -Xmx4g

到这为止,Java SE 8开启容器特性支持失败,这方面有坑,建议直接上Java SE 11,用起来很香,不用额外配置,当然默认最大堆内存比例还是25%,需要改成100%,推荐改成75%。
下面是社区讨论:

Java SE 11 对容器内CPU 和内存限制的支持

Java 17: What’s new in OpenJDK's container awareness

Copyright © 2020 - 2024 saowu. All Right Reserved
Powered by Gridea