логотип PurpleSchool
логотип PurpleSchool

Как управлять Resources и Requests в Kubernetes

Автор

Олег Марков

Введение

Понимание выделения и управления ресурсами — один из важнейших аспектов работы с Kubernetes. Если вы используете Kubernetes для развертывания своих приложений, вам точно нужно знать, как правильно указывать и ограничивать ресурсы — например, процессор и оперативную память — для ваших контейнеров. Благодаря грамотной настройке Resources (requests и limits) вы сможете избежать ситуаций, когда поды потребляют чрезмерно много ресурсов и мешают другим приложениям в кластере. Эта статья покажет, как устроено управление ресурсами, на что влияют настройки requests и limits, с какими граблями чаще всего сталкиваются разработчики, и какие практики позволяют держать всё под контролем.

Мы рассмотрим реальные YAML-фрагменты, объясним теорию и дадим комментарии для разных ситуаций. Если вы хотите, чтобы ваши приложения работали стабильно, а кластер не страдал от перегрузок, этот материал упростит вашу работу.

Что такое Requests и Limits в Kubernetes

Краткое определение

Перед тем как перейти к деталям, давайте определим, что означают ключевые параметры:

  • Requests (запрошенные ресурсы) — минимальное количество ресурсов (CPU, память), которое Kubernetes гарантированно выделит контейнеру.
  • Limits (лимиты) — верхний предел ресурсов для контейнера. Контейнер не сможет использовать больше этих значений.

Смотрите, что происходит: когда вы создаете под и указываете эти параметры, Kubernetes на их основе выполняет планирование и защиту кластера от чрезмерных нагрузок.

Для чего нужны Requests

Requests нужны для планирования размещения пода на правильном ноде. Если ваш контейнеру нужен хотя бы 1 vCPU и 512MiB памяти, Kubernetes будет искать такой нод, где эти ресурсы точно зарезервированы — меньше никак.

Для чего нужны Limits

Limits ограничивают аппетиты контейнера. Даже если на ноде свободно много памяти или CPU, контейнер никогда не получит больше, чем ему разрешено лимитом. Это особенно важно для защиты от утечек памяти или слишком жадных процессов.

Где и как указывать Requests и Limits

Основы декларации ресурсов

Вы прописываете requests и limits прямо внутри спецификации контейнера в манифестах Pod, Deployment, StatefulSet или других контроллеров.

Вот базовый пример для одного контейнера:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
    - name: myapp
      image: myapp:latest
      resources:
        requests:
          memory: "256Mi"        # Kubernetes постарается гарантировать минимум 256MiB памяти
          cpu: "500m"           # И минимум 0.5 vCPU (500 millicpu)
        limits:
          memory: "512Mi"        # Контейнер не сможет использовать больше 512MiB памяти
          cpu: "1000m"           # И больше 1 vCPU

Комментарии:

  • Значения указываются в resources: requests и resources: limits.
  • CPU измеряется в millicores (1000m = 1 CPU). Для requests и limits можно указывать разные значения.
  • Избыток ресурсов на ноде не даст контейнеру использовать больше, чем указано в limits.

Форматы ресурсов

CPU

  • 1 CPU = 1 vCPU/ядро. Можно задавать как 1, 0.5, 100m (милликоры).
  • Пример: "0.5" эквивалентно "500m".

Память

  • Память указывается в байтах (B), килобайтах (Ki), мегабайтах (Mi), гигабайтах (Gi).
  • Пример: "128Mi", "1Gi".

Как работает планирование и ограничения

Scheduling: как Kubernetes использует requests

Когда вы создаете под с requests, Kubernetes рассчитывает — хватит ли у ноды ресурсов, чтобы выделить requested значения для каждого контейнера. Пока не найдётся подходящий нод, под останется в статусе Pending.

Пример: если у ноды осталось только 300Mi памяти, а под просит 400Mi — Kubernetes даже не попробует туда его посадить.

Enforcement: что происходит при превышении limits

  • Ограничение по CPU: если контейнер попытается использовать больше CPU, чем указано в limits, Kubernetes throttle-ит (замедляет) выполнение процесса.
  • Ограничение по памяти: если контейнер превышает лимит по памяти, его процесс будет убит (OOMKilled). Перезапуск зависит от политики рестарта.

Типичные сценарии и фрагменты YAML

Один контейнер — разные Requests и Limits

resources:
  requests:
    cpu: "250m"
    memory: "128Mi"
  limits:
    cpu: "500m"
    memory: "256Mi"
  • Здесь контейнеру гарантируют минимум 0.25 CPU и 128 MiB памяти, но он не сможет съесть больше 0.5 CPU и 256 MiB.

Несколько контейнеров внутри пода

В каждом контейнере свои ресурсы:

apiVersion: v1
kind: Pod
metadata:
  name: multi-container
spec:
  containers:
    - name: frontend
      image: frontend-img
      resources:
        requests:
          cpu: "100m"
          memory: "64Mi"
        limits:
          cpu: "200m"
          memory: "128Mi"
    - name: backend
      image: backend-img
      resources:
        requests:
          cpu: "500m"
          memory: "256Mi"
        limits:
          cpu: "1000m"
          memory: "512Mi"

Использование в Deployments

Так же указываются в шаблонах подов:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: sample-container
          image: sample-img
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "300m"
              memory: "256Mi"
  • То, что указано в манифесте шаблона, будет применяться к каждому поду.

NS-контролирование: ResourceQuotas и LimitRanges

Ограничение ресурсов на Namespace

Иногда вы хотите застраховаться от случайного создания сотни подов, каждый из которых потребляет бесконечно много ресурсов. Для этого служат объекты типа ResourceQuota и LimitRange.

ResourceQuota

Позволяет лимитировать общее использование ресурсов в Namespace:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "2"     # Всего можно запрашивать максимум 2 CPU
    requests.memory: "1Gi"
    limits.cpu: "4"
    limits.memory: "2Gi"
    pods: "10"            # Не более 10 подов в namespace

Если кто-то попробует создать еще под или запросить больше ресурсов, чем указано, Kubernetes не разрешит это сделать.

LimitRange

Назначает минимальные и максимальные requests/limits для подов или контейнеров в Namespace:

apiVersion: v1
kind: LimitRange
metadata:
  name: container-limits
  namespace: dev
spec:
  limits:
    - type: Container
      defaultRequest:
        cpu: 100m
        memory: 128Mi
      default:
        cpu: 500m
        memory: 256Mi
      max:
        cpu: 1
        memory: 512Mi

Если разработчик не указал requests или limits — будут применяться defaultRequest и default. Значения max запрещают указание большего лимита.

Практические советы по управлению ресурсами

Как подобрать значения requests и limits

  • Анализируйте историю использования ресурсов. Если приложение уже крутится, смотрите на среднее и пиковое потребление с помощью метрик (например, Prometheus, Grafana, kubectl top).
  • Requests = минимально необходимое. Может быть чуть больше среднего, чтобы не было частых тормозов при пиковой нагрузке.
  • Limits = максимально допускаемое. Пусть будет с запасом, но не слишком большим. Например, limit не должен превышать request более чем в 2-3 раза.

Как увидеть, сколько ресурсов потребляет ваш под

Используйте команду:

kubectl top pod <pod-name>

Это покажет реальное потребление CPU/Memory каждым подом.

Что делать, если не указали requests и limits

Если значения не установлены и в Namespace нет LimitRange с default, контейнеры могут потреблять любые ресурсы, пока не исчерпают лимиты ноды. Это опасно, особенно для памяти — приложение может слопать всю память хоста и вызвать OOM на всех подах ноды.

Рекомендации по CPU

  • Планируйте requests примерно по среднему потреблению, но не близко к нулю.
  • Для коротких всплесков CPU можно поставить limit выше, чем request.
  • Если приложение чувствительно к задержкам (например, веб-серверы), лимит не должен сильно ограничивать производительность.

Рекомендации по памяти

  • Память не масштабируется эластично, как CPU. Приложение может упасть (OOMKilled), если не рассчитать limit.
  • Не ставьте limit слишком близко к request — может привести к неожиданным рестартам из-за ООМ.

Примеры ошибок и как их избегать

Пример ошибки: только limits без requests

resources:
  limits:
    cpu: "2"
    memory: "4Gi"

В этом случае, если в Namespace нет LimitRange, Kubernetes считает, что pod не требует никаких ресурсов для планирования (requests=0). Под будет запущен даже на ноде с малым количеством ресурсов, но после запуска может перегружать хост и конкурировать на равных со всеми.

Совет: Всегда указывайте requests, даже если они совпадают с limits.

Пример ошибки: слишком высокие requests

Если каждое приложение просит слишком много ресурсов через requests, планировщик не сможет распределять поды эффективно — часть ресурсов может простаивать, многие поды будут висеть в Pending.

Совет: Регулярно пересматривайте usage и requests, не завышайте_defaults.

Особенности с autoscaling (HPA и VPA)

Horizontal Pod Autoscaler (HPA)

HPA (kubectl autoscale) масштабирует количество подов на основе метрик, обычно CPU и/или памяти. Для HPA крайне важно указывать requests, потому что он на них ориентируется при расчете процента загрузки.

Vertical Pod Autoscaler (VPA)

VPA может автоматически корректировать requests и limits для подов. Перед использованием — убедитесь, что ваши приложения выдерживают перезапуски, потому что масштабирование VPA вызывает рестарт.

Инструменты для мониторинга ресурсов

  • kubectl top
  • Prometheus + kube-state-metrics
  • Grafana дашборды
  • Kubernetes Metrics Server

Их использование помогает находить неэффективно настроенные requests и limits, а также своевременно обнаруживать утечки или завышенное потребление.

Как трактовать события и статус подов

При превышении лимита по памяти — обычно видим событие OOMKilled (список событий — kubectl describe pod <pod>).

Если не хватает лимитов в Namespace, возникает ошибка при создании (Status Reason: FailedScheduling). В описании пода подскажет причину.


Правильное управление ресурсами — фундамент для стабильной и эффективной работы кластера Kubernetes. Requests и limits позволяют находить баланс между необходимой гарантией доступности приложений и справедливым использованием инфраструктуры. Тестируйте и мониторьте выбранные значения: идеально подобранные настройки удерживают систему в оптимальной форме.

Частозадаваемые технические вопросы по теме

1. Как изменить ресурсы для уже запущенного Deployment?

Измените манифест Deployment (requests/limits) и примените его снова командой:

kubectl apply -f deployment.yaml

Kubernetes плавно перезапустит поды с новыми настройками.

2. Как узнать, какой нод занял контейнер и какие на нем есть ресурсы?

Получить имя ноды, где работает под:

kubectl get pod <pod-name> -o wide

Посмотреть ресурсы ноды:

kubectl describe node <node-name>

или

kubectl top node

3. Как увидеть причину сбоя (например, почему под OOMKilled)?

Проверьте события через:

kubectl describe pod <pod-name>

Или посмотрите статус последнего контейнера:

kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}'

4. Могут ли requests превышать limits?

Нет, requests всегда должны быть меньше или равны limits. Если попытаться указать requests больше limits, манифест не пройдет валидацию.

5. Как задать разные ресурсы для dev и prod окружений?

Используйте разные YAML-манифесты или шаблонизаторы (например, Helm), указывая нужные values для разных окружений. Например, для production — более высокие значения requests/limits, для dev — ниже, чтобы не тратить ресурсы впустую.

Стрелочка влевоРабота с secrets в KubernetesНастройка и работа с Proxy в KubernetesСтрелочка вправо

Постройте личный план изучения Kubernetes до уровня Middle — бесплатно!

Kubernetes — часть карты развития DevOps

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Kubernetes

Terraform и Kubernetes инфраструктура как кодНастройка и использование Runners в KubernetesНастройка и деплой PostgreSQL в KubernetesСравнение и интеграция Openshift и KubernetesПримеры интеграции GitHub Actions и KubernetesDeploy приложений в Kubernetes - пошаговое руководство для начинающих и не толькоКак настроить CD в KubernetesИнтеграция Ansible в KubernetesИнтеграция CI/CD с Jenkins и KubernetesИнтеграция Kubernetes с GitLab - Автоматизация CI CD в облачной инфраструктуреГайд по DevOps инструментам в KubernetesОсобенности платформы Deckhouse в Kubernetes
Открыть базу знаний

Лучшие курсы по теме

изображение курса

Kubernetes и Helm

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Docker и Ansible

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Микросервисы

Антон Ларичев
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий