Skip to content
4 / 15

Go в контейнере: лимиты процессора и памяти, OOMKilled

Контейнер ограничивает процесс двумя способами, и Go реагирует на них по-разному. Лимит памяти — жёсткий: превышение означает OOMKilled от ядра, без всяких сообщений от рантайма Go, поэтому в логах приложения будет пусто, а причину придётся искать в событиях пода. Защита — GOMEMLIMIT с запасом от лимита. Лимит процессора — это квота, а не число ядер: под с limits.cpu: 2 на 64-ядерной машине получает эквивалент двух ядер, но видит все 64. До Go 1.25 рантайм ставил GOMAXPROCS по числу видимых ядер, создавал 64 логических процессора и тратил время на переключения; начиная с 1.25 умолчание учитывает cgroup-квоту. Третья особенность — запросы против лимитов: под с запросом меньше лимита работает нестабильно, потому что при нехватке ресурсов на узле его придушат первым. Практический минимум для Go в Kubernetes: GOMEMLIMIT, актуальная версия Go и запрос памяти, равный лимиту.

Go в контейнере: лимиты процессора и памяти, OOMKilled | JScriptiser