Kik*_*sha 6 java jvm heap-dump kubernetes kubernetes-health-check
我遇到过这样一种情况,突然发生很长的 GC 暂停,我需要找出突然内存分配的根源是什么。长时间的 GC 暂停(大约 30 秒)会导致 pod 连续多次 K8s 健康检查失败,并且 pod 会重新启动,而实际上并没有发生 OOM。我想在 K8s 实际重新启动 pod 之前创建堆转储。我意识到应该对某些外部持久安装进行转储。
我对如何导致堆转储发生的唯一想法是使用 preStop 挂钩。问题是,pod因健康检查失败而重启时,preStop钩子是否会被触发?
也许有一个更优雅的解决方案?
问题是,pod因健康检查失败而重启时,preStop钩子是否会被触发?
是的。根据定义,PreStop钩子会在容器由于 API 请求或管理事件(例如活动探测失败、抢占、资源争用等)而终止之前立即运行。
我应该在 pod 终止之前使用 preStop 钩子捕获 Java 堆转储吗?
是的。但您需要小心,如果容器已处于终止或完成状态,则对 preStop 挂钩的调用将失败。当Pod 终止时,它会在发送 KILL 信号之前等待默认的 30 秒宽限期(如果 PerStop 挂钩未完成,则额外等待 2 秒)。如果 preStop 挂钩需要比默认宽限期允许的时间更长的时间才能完成,则必须进行修改terminationGracePeriodSeconds以适应这一点。
有更优雅的解决方案吗?
据我所知,没有。我想通过向 pod 添加一个空的目录卷,并配置 JVM 以将堆转储到该目录command: ["java", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/dumps/oom.bin", "-jar", "yourapp.jar"]应该可以工作。
为什么上述解决方案会起作用?
当 kubernetes 由于没有响应健康检查而杀死您的容器时,kubernetes 只会重新启动容器,但不会重新调度 pod,因此不会将其移动到另一个节点。因此,在 pod 移动到另一个节点之前,空的 dir 卷不会被删除。因此,当容器重新启动时,新容器将安装相同的空目录,其中将包含上次运行的堆转储。因此您可以kubectl cp在活动结束后随时查看这些文件。复制堆转储文件可能还存在其他挑战,但它们是可以解决的。检查此以获取更多信息。
| 归档时间: |
|
| 查看次数: |
6355 次 |
| 最近记录: |