簡體   English   中英

當 K8s 健康檢查重新啟動 pod 時創建 JVM heapdump - 不會發生 OOM

[英]Create JVM heapdump when K8s healthcheck restarts the pod - no OOM occur

我有一種情況,突然發生很長的 GC 暫停,我需要找出突然分配 memory 的原因是什么。 長時間的 GC 暫停(大約 30 秒)導致 pod 連續多次失敗 K8s 健康檢查,並且 pod 重新啟動,實際上沒有發生 OOM。 我想在 K8s 實際重新啟動 pod 之前創建一個堆轉儲。 我意識到應該對一些外部持久安裝進行轉儲。

我對如何導致堆轉儲發生的唯一想法是使用 preStop 掛鈎。 問題是,當 Pod 因健康檢查失敗而重新啟動時,是否會觸發 preStop 鈎子?

也許有一個更優雅的解決方案?

問題是,當 Pod 因健康檢查失敗而重新啟動時,是否會觸發 preStop 鈎子?

是的。 根據定義perStop鈎子在容器因 API 請求或管理事件(例如活動探測失敗、搶占、資源爭用等)而終止之前立即運行。


我應該在 Pod 終止之前使用 preStop 掛鈎來捕獲 Java 堆轉儲嗎?

是的。 但是您需要小心,如果容器已經終止或完成 state,則調用 preStop 鈎子會失敗。 Pod 終止時,它會等待默認的 30 秒寬限期(如果 PerStop 掛鈎未完成,則額外等待 2 秒),然后再發送 KILL 信號。 如果 preStop 掛鈎需要比默認寬限期允許的時間更長的時間來完成,則必須修改terminationGracePeriodSeconds以適應這種情況。


對此有更優雅的解決方案嗎?

我不知道。 我猜想通過向 pod 添加一個 空的 dir卷,並配置 JVM 以將堆轉儲到該目錄command: ["java", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/dumps/oom.bin", "-jar", "yourapp.jar"]應該可以工作。

為什么上述解決方案會起作用?

當 kubernetes 因為沒有響應健康檢查而殺死你的容器時,kubernetes 只會重啟容器,但不會重新調度 pod,因此不會將其移動到另一個節點。 因此,在將 pod 移動到另一個節點之前,不會刪除空的 dir 卷。 因此,當容器重新啟動時,新容器將掛載相同的空目錄,該目錄將包含上次運行的堆轉儲。 因此,您可以在事件發生后的任何時間對這些文件進行kubectl cp 復制堆轉儲文件可能還有其他挑戰,但它們是可以解決的。 檢查以獲取更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM