Я работаю над Java-сервисом, который в основном создает файлы в сетевой файловой системе для хранения данных.Он работает в кластере k8s в Ubuntu 18.04 LTS.Когда мы начали ограничивать память в kubernetes (пределы: memory: 3Gi), капсулы стали OOMKilled kubernetes.
Сначала мы думали, что это утечка памяти в процессе java, но анализируяглубже мы заметили, что проблема заключается в памяти ядра.Мы подтвердили, что, глядя на файл /sys/fs/cgroup/memory/memory.kmem.usage_in_bytes
Мы выделили случай создания файлов (без java) только с помощью команды DD, например:
for i in {1..50000}; do dd if=/dev/urandom bs=4096 count=1 of=file$i; done
И с помощью команды dd мы увидели, что произошло то же самое (память ядра росла до OOM).После того, как k8s перезапустил модуль, я получил описание модуля:
- Последнее состояние: прекращено
- Причина: OOMKilled
- Код выхода: 143
Создание файлов приводит к увеличению памяти ядра, удаление этих файлов приводит к уменьшению памяти.Но наши сервисы хранят данные, поэтому постоянно создают множество файлов, пока модуль не будет убит и перезапущен из-за OOMKilled.
Мы протестировали ограничение памяти ядра с помощью автономного докера с параметром --kernel-memoryи это сработало, как и ожидалось.Память ядра выросла до предела и больше не росла.Но мы не нашли никакого способа сделать это в кластере kubernetes.Есть ли способ ограничить память ядра в среде K8S?Почему создание файлов приводит к тому, что память ядра растет и она не освобождается?