• Русский
  • Оптимизация производительности Pod с помощью политик менеджера

    Это руководство предоставляет администраторам Kubernetes кластера практическое, готовое к применению руководство по включению и проверке CPU ManagerPolicy, Memory ManagerPolicy и Topology ManagerPolicy. Согласовывая закрепление CPU, NUMA-аффинность и выравнивание топологии, вы можете обеспечить стабильную задержку и улучшенную производительность для критически важных нагрузок.

    Область применения и предварительные требования

    Роли и права

    • Требуется доступ в окно обслуживания, административные права kubectl и SSH-доступ к узлам.

    Требования к нагрузке

    • Для достижения выделенного CPU и NUMA-аффинности Pods должны работать в классе Guaranteed QoS: requests = limits и CPU указаны целыми ядрами (например, 2, 4).

    Не рассматривается

    • HugePages не рассматриваются. Если вам нужна поддержка HugePages, обратитесь в службу поддержки.

    Быстрый старт: пример конфигурации Kubelet

    Добавьте следующий фрагмент в /var/lib/kubelet/config.yaml, подстроив значения под вашу среду:

    # —— CPU ManagerPolicy ——
    cpuManagerPolicy: "static"              # Опции: none | static
    cpuManagerPolicyOptions:
      full-pcpus-only: "true"               # Рекомендуется: выделять только целые ядра
    cpuManagerReconcilePeriod: "5s"
    reservedSystemCPUs: ""                  # например, "0-1" для резервирования конкретных CPU для системы
    
    # —— Memory ManagerPolicy ——
    memoryManagerPolicy: "Static"           # Опции: none | Static 
    reservedMemory:
      - numaNode: 0
        limits:
          memory: "2048Mi"
      - numaNode: 1
        limits:
          memory: "2048Mi"
    
    # —— Topology ManagerPolicy ——
    topologyManagerPolicy: "single-numa-node"     # Опции: none | best-effort | restricted | single-numa-node
    topologyManagerScope: "pod"                   # Опции: container | pod

    Примечания:

    • full-pcpus-only: "true" улучшает согласованность задержек.
    • topologyManagerScope: pod гарантирует, что контейнеры внутри одного Pod выравниваются по общей NUMA-топологии.
    • reservedMemory должен рассчитываться на основе конфигурации kubelet и порогов эвакуации (см. следующий раздел).

    Как рассчитать reservedMemory

    Формула:

    R_total = kubeReserved(memory) + systemReserved(memory) + evictionHard(memory.available)

    Сумма reservedMemory по всем NUMA-узлам должна равняться R_total.

    Шаги (для N NUMA-узлов):

    1. Рассчитать R_total (в Mi).

    2. Вычислить деление и остаток:

      • base = floor(R_total / N)
      • rem = R_total − base × N
    3. Назначить значения:

      • NUMA-узел 0 = base + rem
      • Остальные NUMA-узлы = base

    Пример (2 NUMA-узла):

    • kubeReserved=512Mi, systemReserved=512Mi, evictionHard=100Mi → R_total = 1124Mi
    • base = 562, rem = 0
      reservedMemory:
      - numaNode: 0
        limits:
          memory: "562Mi"
      - numaNode: 1
        limits:
          memory: "562Mi"

    Применение конфигурации

    Для каждого узла:

    1. Отключение и эвакуация

      kubectl cordon <node>
      kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
    2. Остановка Kubelet и очистка состояния

      sudo systemctl stop kubelet
      sudo rm -f /var/lib/kubelet/cpu_manager_state
      sudo rm -f /var/lib/kubelet/memory_manager_state
    3. Перезапуск Kubelet

      sudo systemctl daemon-reload
      sudo systemctl start kubelet
    4. Повторное включение узла

      kubectl uncordon <node>
    • Для DaemonSets и системных Pod перезапустите или удалите Pod явно.
    1. Проверка восстановления

      kubectl get nodes
      kubectl get pods -A -o wide | grep <node>

    Проверка

    Состояние CPU ManagerPolicy

    sudo cat /var/lib/kubelet/cpu_manager_state | jq .

    Проверьте:

    • .policyName = "static"
    • .defaultCpuSet содержит невыделенные CPU
    • .entries показывают назначение контейнеров на CPU

    Состояние Memory ManagerPolicy

    sudo cat /var/lib/kubelet/memory_manager_state | jq .

    Проверьте:

    • .policyName = "Static"
    • Сумма зарезервированной памяти соответствует R_total
    • Pods с Guaranteed назначены на NUMA-узлы согласно политике single-numa-node

    Основные политики и поведение

    CPU ManagerPolicy

    • Цель: выделять эксклюзивные физические CPU для Pods с Guaranteed QoS
    • Конфигурация: cpuManagerPolicy: static, full-pcpus-only: "true"
    • Поведение: применяется только к Pods с Guaranteed; Burstable/BestEffort не затрагиваются

    Memory ManagerPolicy

    • Цель: резервировать и выравнивать память на уровне NUMA-узлов
    • Конфигурация: memoryManagerPolicy: "Static", reservedMemory
    • Поведение: лучше всего работает совместно с Topology ManagerPolicy для выравнивания

    Topology ManagerPolicy

    • Цель: выравнивать CPU, память и устройства на одном NUMA-узле
    • Конфигурация: topologyManagerPolicy: single-numa-node, topologyManagerScope: pod
    • Режимы: best-effort, restricted, single-numa-node (строгий)

    Терминология

    • NUMA node: домен с неоднородным доступом к памяти (Non-Uniform Memory Access)
    • CPU pinning: привязка контейнеров к выделенным CPU
    • NUMA affinity: предпочтение памяти из того же NUMA-узла, что и CPU
    • Topology alignment: совместное размещение CPU, памяти и устройств на одном NUMA-узле
    • Guaranteed Pod: requests = limits; CPU указаны целыми ядрами