Ты открываешь облачный счёт после спокойного месяца. Всплесков не было, но ноды снова оплачены целиком. Хочется уменьшить requests у всех Deployment — и не получить серию OOMKilled ночью.
Масштаб запаса виден по отчёту Cast AI за 2025 год: средняя загрузка CPU в десятках тысяч кластеров AWS, Azure и GCP составила 8%, памяти — 20%, GPU — 5%. За год доля избыточно зарезервированного CPU выросла с 40% до 69%, памяти достигла 79%.
Эти числа помогают найти проблему, но не задают новые requests. Тебе нужен первый безопасный цикл rightsizing: выбрать один workload, уменьшить резерв и проверить результат на рабочей нагрузке.
Средняя загрузка кластера не определяет requests контейнера
У контейнера есть три разных значения: текущий расход, заданный request и пик нагрузки. Среднее по кластеру смешивает фоновые сервисы, пакетные задачи и приложения с короткими всплесками.

Если кластер использует 8% CPU, из этого не следует, что каждый CPU request можно сократить на 92%. Аналогично, средние 20% памяти не дают готового коэффициента для нового memory request. Отчёт показывает общий объём резерва — 69% по CPU и 79% по памяти, — но ничего не говорит о пиках твоего API или воркера.
Поэтому начни не с Namespace и не с нод. Найди один Deployment или StatefulSet, у которого разрыв между request и потреблением сохраняется на всей доступной истории.
Pod для такого сравнения — плохая единица: Pods эфемерны, а HPA меняет их количество по CPU, памяти или пользовательским метрикам. Смотри на workload целиком и отдельно проверяй каждый контейнер внутри него.
Сначала освободи ресурс, потом считай экономию на нодах
Уменьшенный request не гарантирует, что счёт сразу изменится. Cluster Autoscaler добавляет и удаляет ноды по загрузке кластера, поэтому несколько небольших правок могут лишь перераспределить свободное место внутри уже оплаченных машин.
Отдели две проверки:
- workload продолжает работать после изменения
requests; - кластер освободил достаточно ресурса, чтобы удалить ноду или перейти на меньшую конфигурацию.
Первая проверка относится к контейнеру. Вторая — к размещению Pods и работе Cluster Autoscaler. Если смешать их, безопасная настройка покажется бесполезной только потому, что одна нода пока не освободилась целиком.
Автоматический rightsizing без границ превращается в эксперимент на проде
Организации, которые применяли автоматический rightsizing, в среднем сокращали зарезервированный CPU примерно на 50%. Это не целевое значение для твоего кластера. Это сигнал, что ручной просмотр сотен Deployment оставляет много лишнего резерва.
Автоматике нужны три границы: какие workloads она меняет, насколько может уменьшить request за один цикл и сколько времени система наблюдает результат. Первый прогон лучше ограничить одним некритичным сервисом. Так проще связать изменение с пиками потребления, рестартами и ошибками приложения.
CPU и память проверяй отдельно. Сначала измени один request и дождись стабильного окна. Если одновременно сократить оба, при деградации придётся угадывать причину.
Для memory request отдельным критерием сделай отсутствие новых OOMKilled. В примере из отчёта кластер до оптимизации получал в среднем 40–50 OOM kills за интервал измерения. После автоматического rightsizing их число снизилось почти до нуля.
Этот пример ценен не обещанием повторить результат. Он задаёт критерий: оптимизация должна уменьшать резерв без роста OOM kills. Само по себе снижение requests ничего не доказывает.
Первый цикл rightsizing: один workload, один ресурс
Выбери некритичный Deployment или StatefulSet с постоянным разрывом между request и фактическим потреблением. Зафиксируй исходные значения, пики, рестарты и OOM kills. Затем уменьши только CPU request либо только memory request — не оба сразу.
После изменения выдержи окно, которое захватывает обычный пик этого workload. Сравни потребление, доступность приложения, рестарты и OOMKilled с исходным состоянием. Если поведение не изменилось, переходи к следующему ресурсу или workload. Если появились сбои, верни предыдущее значение и расширь окно наблюдения.
Правило первого прохода простое: 8% CPU и 20% памяти находят место для проверки, но не вычисляют новый request. Его определяет история конкретной нагрузки.