У меня проблема с ОС, оптимизированной для контейнеров, на GKE. Если я запустил эту простую команду https://pastebin.com/raw/0WPAnAzn чтобы израсходовать всю оперативную память, в какой-то момент хост зависает и ни на что не отвечает. Ожидаемое поведение: процесс должен быть остановлен убийцей OOM. Я пробовал это на стандартных образах Ubuntu и CentOS, и они работают отлично: процесс завершается без зависания.
В последовательной консоли есть три возможных выхода kmsg:
Зависание сопровождается почти 100% загрузкой процессора.
Так это ожидаемое поведение или что-то не так?
После некоторых экспериментов я обнаружил, что это не связано с GKE или GCP. И это даже не связано с имиджем COS.
Собственно, так ядро Linux обрабатывает OOM. Убийца OOM запускается слишком поздно и действует в среде с ограниченным объемом памяти. Он решает, какой процесс убить, используя процессы ' oom_score
.
При запуске Kubernetes на хосте есть много процессов с высоким oom_score_adjust
значение (это стручки без ограничений памяти в их спецификации). Если для вашего модуля пожирателя RAM установлены ограничения, в результате oom_score
вероятно будет ниже, чем у многих других процессов.
В этом случае убийца OOM сначала убьет те многие процессы с наивысшим oom_score
до того, как у него появится шанс убить действительно жадный процесс. Не знаю почему, но в этой ситуации Linux полностью зависает.
В качестве обходного пути я нашел этот инструмент. Установка его как DaemonSet решает проблему. Он безжалостно убивает жадные процессы.
Такое поведение ожидается и не вызвано COS изображение как таковой. Вместо этого он связан с тем, как Kubernetes обрабатывает Узел OOM. В этом случае сценарий выполняется в узле, а не в POD. Убиваются контейнеры, но не главный процесс, истощающий память.
Есть некоторые предложения и реализации, чтобы помочь зарезервировать ресурсы для узла Демоны ОС.
Начиная с узлов, содержащих версию 1.7.6, Google Container Engine резервирует часть вычислительных ресурсов каждого узла для накладных расходов системы с использованием Kubernetes. Функция Node Allocatable. Это повысит надежность компонентов системы и не приведет к увеличению накладных расходов системы. Это изменение явно резервирует вычислительные ресурсы, которые уже могут потреблять системные компоненты.