При описании манифеста pod в kubernetes в секции spec есть раздел: resources. В нем описываются требуемые для pod ресурсы: память и процессор. Как лучше описать эти ресурсы? Может запросить сразу побольше памяти или наоборот отдать распределение ресурсов на откуп системе? Давайте разбираться.
Управлять мы можем двумя вещами: использования CPU и использования памяти для pod. Каждый pod это по сути контейнер, который исполняется на машине называемой node. Естественно, node имеет свои процессор и память и pod использует эти ресурсы. Наша задача подсказать системе сколько ресурсов нужно pod'у и ограничить их максимальное использование. Исходя из этих ограничений kubernetes сможет спланировать на каком ноде запустить pod и сколько зарезервировать памяти для его максимально быстрого старта.
Лимиты cpu задаются в cpu. Cpu это один виртуальный процессор в Google Cloud, aws или Azure или один гипертред в "железном процессоре". Можно задавать в дробных числах "0.5" процессора. Минимальная единица разделения cpu это: millicpu то есть 1/1000 процессора (500m=0.5 cpu).
Лимиты памяти задаются в байтах. Возможны модификаторы К - килобайты, M - мегабайты, P - петабайты, G - Гигабайты. Для любителей точности Ki, Mi, Gi и Pi тоже самое, но по степеням двойки.
У нас есть pod в секции spec которого мы видим такое:
Контейнер запустится с минимальной памятью 64 мегабайта и потребуется 0,25 cpu (то есть на одном виртуальном процессоре можно запустить 4 pod'а). Если во время работы pod потребует больше cpu или больше памяти система будет давать ему ресурсы до 0,5 процессора и 250 мегабайт памяти.
А если pod превысит эти ресурсы? С памятью все просто: процесс OOM(Out of memory) Killer остановит контейнер и pod завершится. Дальнейшая его судьба описана в манифесте, и он может завершиться или рестартовать. В случае нехватки процессора контейнер будет остановлен и будет ждать, когда освободится "его" часть процессора.
Предположим, pod хочет стартовать, а в наличие нет достаточной памяти или процессора? В этом случае Kubernetes попробует запустить pod на другом узле. Если свободного node нет попробует его запустить (если разрешает манифест). Если и в этом случае неудача, pod работать не будет и будет находится в состоянии ожидания ресурса.
А если у нас не заполнен раздел resources ? Что произойдет в этом случае? В Kubernetes есть значения по умолчанию для начального значения и лимиты по памяти и процессору для верхнего. Значения по умолчанию могут быть недостаточными для старта контейнера и системе придется аллоцировать память кусочками замедляя старт контейнера. Резкий рост потребления памяти и cpu может вызвать перемещение podа по нодам и замедление, а то и прерывание его работы.
Итак, можно дать следующие рекомендации: Начальные значения (requests) должны быть такие чтобы контейнер мог запуститься максимально быстро и не требовал для старта дополнительных выделений памяти. Максимальные значения должны целиком покрывать потребность контейнера в памяти. Определить максимальное значение часто бывает сложно. Тут нам поможет мониторинг памяти и лимиты ограничения памяти в системах (Например, в java машине есть ограничение верхнего лимита памяти).