为什么OpenJDK Docker容器会忽略Kubernetes中的内存限制?

问题描述

我正在Kubernetes 1.19.3上运行带有Docker映像jboss/wildfly:20.0.1.Final的多个Java应用程序。 Wildfly服务器在OpenJDK 11中运行,因此jvm支持容器内存限制(cgroups)。

如果我设置了内存限制,则在Kubernetes中运行时,容器将完全忽略此限制。但是当我在普通Docker中运行它时,它在同一台机器上受到尊重:

1。在内存限制为300M的Docker中运行Wildfly:

$ docker run -it --rm --name java-wildfly-test -p 8080:8080 -e JAVA_OPTS='-XX:MaxRAMPercentage=75.0' -m=300M jboss/wildfly:20.0.1.Final

验证内存使用情况:

$ docker stats
CONTAINER ID        NAME                 CPU %        MEM USAGE / LIMIT     MEM %       NET I/O       BLOCK I/O     PIDS
515e549bc01f        java-wildfly-test    0.14%        219MiB / 300MiB       73.00%      906B / 0B     0B / 0B       43

按预期,该容器不会超过300M的内存限制。

2。在Kubernetes中以300M的内存限制运行Wildfly:

现在,我在kubernetes中启动相同的容器。

$ kubectl run java-wildfly-test --image=jboss/wildfly:20.0.1.Final --limits='memory=300M' --env="JAVA_OPTS='-XX:MaxRAMPercentage=75.0'" 

验证内存使用情况:

$ kubectl top pod java-wildfly-test
NAME                CPU(cores)   MEMORY(bytes)   
java-wildfly-test   1089m        441Mi 

完全忽略并立即超过300M的内存限制。

为什么会这样?两种测试都可以在同一台机器上执行。

答案

高值的原因是从项目kube-prometheus接收到的度量标准数据输出不正确。卸载kube-projemet并安装metric-server后,使用kubctl top可以正确显示所有数据。现在显示的值与docker stats相同。我不知道为什么kube-prometheus会计算错误的数据。实际上,它为所有内存数据提供了双精度值。

解决方法

我将这个答案作为社区Wiki,因为这可能对社区有所帮助。 Kubectl top正在显示不正确的数据。 OP解决了卸载kube-prometheus堆栈并安装metric-server的问题。

高值的原因是度量标准的输出不正确 从kube-prometheus项目获得的数据。卸载后 kube-projemet并安装了metric-server所有数据 使用kubectl top正确显示。现在显示的值与 docker统计信息。我不知道为什么kube-prometheus计算错误 数据。实际上,它为所有内存数据提供了双精度值。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...