Создание дампа кучи JVM, когда проверка работоспособности K8s перезапускает модуль - OOM не происходит - PullRequest
1 голос
/ 02 августа 2020

У меня есть ситуация, когда внезапно возникает действительно длинная пауза G C, и мне нужно выяснить, что является источником внезапного выделения памяти. Длительная пауза G C (около 30 секунд) приводит к тому, что модуль не выполняет несколько проверок работоспособности K8s подряд, и модуль перезапускается без фактического выполнения OOM. Я хочу создать дамп кучи до того, как K8s действительно перезапустит модуль. Я понимаю, что дамп должен быть сделан для некоторого внешнего постоянного монтирования.

Единственная идея, которая у меня есть, как вызвать дамп кучи, - это использовать ловушку preStop. Вопрос в том, срабатывает ли ловушка preStop при перезапуске модуля из-за сбоя проверки работоспособности?

Может быть, есть более элегантное решение для этого?

1 Ответ

2 голосов
/ 02 августа 2020

Вопрос в том, срабатывает ли ловушка preStop при перезапуске модуля из-за сбоя проверки работоспособности?

Да. Согласно определению , perStop ловушка запускается непосредственно перед завершением работы контейнера из-за запроса API или события управления, такого как сбой проверки работоспособности, приоритетное прерывание, конфликт ресурсов и другие.

Следует ли использовать обработчик preStop для захвата Java дампа кучи перед завершением работы модуля?

Да. Но нужно быть осторожным, вызов ловушки preStop завершится ошибкой, если контейнер уже находится в состоянии завершения или завершения. Когда модуль завершает работу , он ожидает 30-секундного льготного периода по умолчанию (с дополнительными 2 секундами, если перехватчик PerStop не завершен) перед отправкой сигнала KILL. Если обработчику preStop требуется больше времени для завершения, чем позволяет льготный период по умолчанию, вы должны изменить terminationGracePeriodSeconds в соответствии с этим.

Есть ли более элегантное решение для этого?

Не знаю. Я предполагаю, добавив к модулю том пустой каталог и настроив JVM для создания дампа кучи в этот каталог, command: ["java", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/dumps/oom.bin", "-jar", "yourapp.jar"] должно работать.

Почему вышеуказанное решение будет работает?

Когда kubernetes убивает ваш контейнер, потому что он не отвечает на проверку работоспособности, kubernetes просто перезапускает контейнер, но не переносит перенос модуля, поэтому он не будет перемещать его в другой узел. Следовательно, пустой том каталога не удаляется, пока модуль не будет перемещен на другой узел. Следовательно, при перезапуске контейнера новый контейнер смонтирует тот же пустой каталог, который будет содержать дамп кучи из предыдущего запуска. Таким образом, вы можете kubectl cp этих файлов в любое время после события. Могут возникнуть и другие проблемы при копировании файлов дампа кучи, но они решаемы. Проверьте это для получения дополнительной информации.

...