Реклама

Контейнер вышел за лимит памяти и не умер. Лучше бы умер

#Контейнер #Лучше #OOMKilled #Сервис #Kubernetes
Контейнер вышел за лимит памяти и не умер. Лучше бы умер

Контейнер упёрся в лимит памяти, но OOMKilled так и не появился. Сервис продолжает работать, задержки растут, CPU почти простаивает, а привычные метрики не объясняют, что происходит. На примере экспериментов с cgroup v2 разберём, как memory.high заставляет процессы ждать освобождения памяти и почему в Kubernetes это может обернуться минутами деградации производительности перед рестартом. Разобрать эксперимент

Привет, Хабр!

С лимитом памяти в контейнере все привыкли обращаться одинаково. Процесс дорос до limits.memory, ядро его убило, в kubectl describe появился OOMKilled. Через пару секунд контейнер уже поднялся заново. Приятного мало, зато понятно, что случилось.

В Linux с cgroup v2 у памяти есть второй порог, memory.high, и на нём ядро никого не убивает. Процесс, который за него вышел, отправляют на принудительное освобождение памяти, а если освобождать нечего, усыпляют.

В systemd этот порог давно живёт под именем MemoryHigh=. А 26 августа вышел Kubernetes 1.37, в котором Memory QoS стал бетой и включён по умолчанию. Сам по себе memory.high он пока не ставит. Для этого хватает одной строки memoryThrottlingFactor: 0.9 в конфиге kubelet, и её приводят в примерах настройки.