Gymterview
middle

Что такое Requests и Limits для ресурсов?

Requests — минимальное количество ресурсов, гарантированное контейнеру (используется Scheduler’ом для выбора ноды). Limits — максимальное количество ресурсов, которое контейнер может потребить.

Поведение при превышении

Ресурс При превышении Limit
CPU Контейнер троттлится (throttling), но не убивается
Memory Контейнер убивается (OOMKilled) и перезапускается

Единицы измерения

Ресурс Единицы Примеры
CPU Ядра или millicores 1 = 1 ядро, 500m = 0.5 ядра, 250m = 0.25 ядра
Memory Байты с суффиксами 128Mi = 128 мебибайт, 1Gi = 1 гибибайт

Пример

Пример
spec:
  containers:
    - name: app
      image: my-registry/my-java-app:1.0.0
      resources:
        requests:
          memory: "512Mi"
          cpu: "250m"
        limits:
          memory: "1Gi"
          cpu: "1000m"

QoS-классы (Quality of Service)

Kubernetes назначает Pod’у QoS-класс на основе Requests и Limits:

QoS-класс Условие Приоритет при вытеснении
Guaranteed Requests == Limits для всех контейнеров Последний (самый защищённый)
Burstable Requests < Limits хотя бы у одного контейнера Средний
BestEffort Нет ни Requests, ни Limits Первый (вытесняется первым)

Рекомендации для Java-приложений

  • Всегда устанавливайте и Requests, и Limits для памяти
  • Memory Limit должен учитывать: heap (-Xmx) + metaspace + thread stacks + native memory + буфер (~20-30%)
  • Пример: если -Xmx512m, то Memory Limit рекомендуется ставить 768Mi-1Gi
  • Используйте JVM-флаги для корректной работы в контейнере:
Пример
env:
  - name: JAVA_OPTS
    value: >-
      -XX:MaxRAMPercentage=75.0
      -XX:+UseContainerSupport

Флаг -XX:+UseContainerSupport (включён по умолчанию с JDK 10+) позволяет JVM корректно определять память и CPU, доступные контейнеру, а не всей ноде.

На собеседовании: нужно знать разницу Requests vs Limits, три QoS-класса и формулу для Memory Limit Java-приложения. Частая ошибка — ставить -Xmx равным Memory Limit, забывая про metaspace и native memory, что приводит к OOMKilled.