首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当K8s健康检查重新启动pod时创建JVM堆转储-没有OOM发生。

当K8s健康检查重新启动pod时创建JVM堆转储-没有OOM发生。
EN

Stack Overflow用户
提问于 2020-08-02 10:04:31
回答 1查看 4.1K关注 0票数 5

当突然发生一个非常长的GC暂停时,我需要找出突然内存分配的来源。长时间的GC暂停(大约30秒)导致吊舱连续几次K8s健康检查失败,吊舱被重新启动,而OOM实际上没有发生。我想在K8s真正重新启动pod之前创建一个堆转储。我意识到转储应该做一些外部持久安装。

我对如何使堆转储发生的唯一想法是使用preStop钩子。问题是,当吊舱因健康检查失败而重新启动时,是否启动了preStop钩子?

也许有一个更优雅的解决方案?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-02 10:54:15

问题是,当吊舱因健康检查失败而重新启动时,是否启动了preStop钩子?

是。根据定义,由于PreStop请求或管理事件(如活动探测失败、抢占、资源争用等),在容器终止之前立即运行PreStop钩子。

在结束符终止之前,我应该使用preStop钩子来捕获Java转储吗?

是。但是您需要小心,如果容器已经处于终止状态或已完成状态,则调用preStop钩子将失败。当吊舱终止时,它在发送杀死信号之前等待默认的30秒宽限期(如果PerStop钩子未完成,则增加2秒)。如果preStop钩子需要比默认的宽限期更长的时间来完成,则必须修改terminationGracePeriodSeconds以适应这种情况。

对此还有更优雅的解决方案吗?

我不知道。我想,通过向pod添加一个空dir卷,并配置JVM将堆转储到command: ["java", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/dumps/oom.bin", "-jar", "yourapp.jar"]应该可以工作。

为什么上面的解决方案会起作用?

当kubernetes由于没有响应健康检查而杀死您的容器时,kubernetes只会重新启动容器,但是它不会重新安排容器的时间,因此不会将它移动到另一个节点。因此,在吊舱被移动到另一个节点之前,不会删除空的dir卷。因此,当容器重新启动时,新容器将挂载相同的空dir,其中将包含上次运行的堆转储。因此,您可以在事件发生后的任何时候对这些文件进行kubectl cp。复制堆转储文件可能还有其他挑战,但它们是可以解决的。有关更多信息,请访问

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63214691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档