gpt4 book ai didi

docker - Kubernetes pods 重启问题异常

转载 作者:行者123 更新时间:2023-12-01 15:05:50 24 4
gpt4 key购买 nike

我的 Java 微服务在 AWS EC2 实例上托管的 k8s 集群中运行。

我在 K8s 集群中运行了大约 30 个微服务(nodejs 和 Java 8 的良好组合)。我面临一个挑战,我的 Java 应用程序 pod 意外重启,这导致应用程序 5xx 计数增加。

为了调试这个,我在 pod 和应用程序中启动了一个 newrelic 代理,并找到了下图:

enter image description here

在我可以看到的地方,我的 Xmx 值为 6GB,我的用途是最大 5.2GB。

这清楚地表明 JVM 没有跨越 Xmx 值。

但是当我描述 pod 并寻找最后一个状态时,它会显示“原因:错误”和“退出代码:137”

enter image description here

然后在进一步调查中,我发现我的 Pod 平均内存使用一直接近其极限。(分配的 9Gib,使用 ~9Gib)。我无法理解为什么 Pod 中的内存使用率如此之高,尽管我只有一个进程在运行((JVM),而且这也受到 6Gib Xmx 的限制。

enter image description here

当我登录到我的工作节点并检查 docker 容器的状态时,我可以看到该应用程序的最后一个容器具有 Exited 状态并显示“容器以非零退出代码 137 退出”

我可以看到wokernode内核日志为:

enter image description here

这表明内核正在终止我在容器内运行的进程。

我可以看到我的工作节点中有很多可用内存。

enter image description here

我不确定为什么我的 pod 一次又一次地重新启动,这是 k8s 的行为还是我的基础设施中的一些欺骗性行为。这迫使我再次将我的应用程序从容器移动到虚拟机,因为这会导致 5xx 计数增加。

编辑:将内存增加到 12GB 后,我收到了 OOM。

enter image description here

我不确定为什么 POD 会因为 OOM 而被杀死
虽然 JVM xmx 只有 6 GB。

需要帮忙!

最佳答案

一些较旧的 Java 版本(Java 8 u131 版本之前)无法识别它们正在容器中运行。因此,即使您使用 -Xmx 为 JVM 指定最大堆大小,JVM 也会根据主机的总内存而不是容器可用的内存来设置最大堆大小,然后当进程尝试分配超过其限制的内存时(在 pod/部署规范中定义)您的容器正在被 OOMKilled。

在本地运行 K8 集群中的 Java 应用程序时,这些问题可能不会出现,因为 pod 内存限制和本地机器总内存之间的差异不大。但是,当您在具有更多可用内存的节点上在生产环境中运行它时,JVM 可能会超过您的容器内存限制并且会被 OOMKilled。

从 Java 8(u131 版本)开始,可以让 JVM 成为“容器感知”,以便识别由容器控制组 (cgroups) 设置的约束。

对于 Java 8 (来自 U131 版本)和 Java9 您可以将此实验标志设置为 JVM:

-XX:+UnlockExperimentalVMOptions 
-XX:+UseCGroupMemoryLimitForHeap

它将根据您的容器 cgroups 内存限制设置堆大小,该限制在 pod/deployment 规范的容器定义部分中定义为“资源:限制”。
在 Java 8 中仍然可能存在 JVM 的堆外内存增加的情况,因此您可能会监视它,但总体而言,这些实验标志也必须处理它。

来自 Java 10 这些实验性标志是新的默认值,可以使用此标志启用/禁用:
 -XX:+UseContainerSupport 
-XX:-UseContainerSupport

关于docker - Kubernetes pods 重启问题异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51474223/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com