Менеджери ресурсів вузлів

Для підтримки критичних до затримки та високопродуктивних робочих навантажень Kubernetes пропонує набір менеджерів ресурсів. Менеджери прагнуть координувати та оптимізувати вирівнювання ресурсів вузла для Podʼів, налаштованих з конкретною вимогою до ресурсів процесорів, пристроїв та памʼяті (величезних сторінок).

Політики вирівнювання топології апаратного забезпечення

Topology Manager — це компонент kubelet, який прагне координувати набір компонентів, відповідальних за ці оптимізації. Загальний процес управління ресурсами регулюється за допомогою політики, яку ви вказуєте. Щоб дізнатися більше, прочитайте Контроль політик управління топологією на вузлі.

Політики призначення CPU для Podʼів

СТАН ФУНКЦІОНАЛУ: Kubernetes v1.26 [stable] (стандартно увімкнено: true)

Після привʼязки Podʼа до вузла, kubelet на цьому вузлі може або мультиплексувати наявне апаратне забезпечення (наприклад, розподіляти процесори між кількома Podʼами), або виділяти апаратне забезпечення, присвячуючи деякі ресурси (наприклад, призначаючи один або більше процесорів для виключного використання Pod).

Стандартно kubelet використовує CFS квоту для забезпечення обмежень на використання процесорів Podʼом. Коли вузол запускає багато Podʼів, що вимагають процесорних ресурсів, робоче навантаження може переміщатися на різні ядра процесора залежно від того, чи обмежено Pod і які ядра процесора доступні на момент планування. Багато робочих навантажень не чутливі до цієї міграції й тому працюють нормально без будь-якого втручання.

Однак у робочих навантаженнях, де спорідненість кешу процесора та затримка планування значно впливають на продуктивність, kubelet дозволяє використовувати альтернативні політики управління процесорами для визначення деяких переваг розміщення на вузлі. Це реалізовано за допомогою CPU Manager та його політики. Є дві доступні політики:

  • none: політика none явно включає стандартну наявну схему спорідненості процесорів, не надаючи додаткової спорідненості, крім того, що автоматично робить планувальник ОС. Обмеження на використання процесорів для Гарантованих Podʼів та Podʼів Burstable забезпечуються за допомогою CFS квоти.
  • static: політика static дозволяє контейнерам у Гарантованих Podʼах з цілими числами requests доступ до ексклюзивних процесорів на вузлі. Ця ексклюзивність забезпечується за допомогою контролера cpuset cgroup.

CPU Manager не підтримує відключення та включення процесорів під час виконання.

Статична політика

Статична політика дозволяє більш детальне управління процесорами та ексклюзивне призначення процесорів. Ця політика керує спільним пулом процесорів, який спочатку містить усі процесори на вузлі. Кількість ексклюзивно виділених процесорів дорівнює загальній кількості процесорів на вузлі мінус будь-які резерви процесорів, встановлені конфігурацією kubelet. Процесори, зарезервовані цими параметрами, беруться, у цілому числі, з початкового спільного пулу у висхідному порядку за фізичним ідентифікатором ядра. Цей спільний пул є набором процесорів, на яких працюють будь-які контейнери у BestEffort та Burstable Pod. Контейнери у Гарантованих Podʼах з дробовими requests також працюють на процесорах у спільному пулі. Лише контейнери, які є частиною Гарантованого Podʼа і мають цілі числа requests процесорів, призначаються ексклюзивні процесори.

Коли Гарантовані Podʼи, контейнери яких відповідають вимогам для статичного призначення, плануються на вузол, процесори видаляються зі спільного пулу та розміщуються у cpuset для контейнера. CFS квота не використовується для обмеження використання процесорів цими контейнерами, оскільки їх використання обмежується самим доменом планування. Іншими словами, кількість процесорів у cpuset контейнера дорівнює цілому числу limit процесорів, зазначеному у специфікації Pod. Це статичне призначення збільшує спорідненість процесорів та зменшує кількість перемикань контексту через обмеження для робочого навантаження, що вимагає процесорних ресурсів.

Розглянемо контейнери у наступних специфікаціях Pod:

spec:
  containers:
  - name: nginx
    image: nginx

Pod вище працює у класі QoS BestEffort, оскільки не вказано жодних requests або limits ресурсів. Він працює у спільному пулі.

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
      requests:
        memory: "100Mi"

Pod вище працює у класі QoS Burstable, оскільки requests ресурсів не дорівнюють limits і кількість cpu не вказана. Він працює у спільному пулі.

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "2"
      requests:
        memory: "100Mi"
        cpu: "1"

Pod вище працює у класі QoS Burstable, оскільки requests ресурсів не дорівнюють limits. Він працює у спільному пулі.

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "2"
      requests:
        memory: "200Mi"
        cpu: "2"

Pod вище працює у класі QoS Гарантований, оскільки requests дорівнюють limits. І обмеження ресурсу контейнера для процесора є цілим числом, більшим або дорівнює одному. Контейнер nginx отримує 2 ексклюзивні процесори.

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "1.5"
      requests:
        memory: "200Mi"
        cpu: "1.5"

Pod вище працює у класі QoS Гарантований, оскільки requests дорівнюють limits. Але обмеження ресурсу контейнера для процесора є дробовим числом. Він працює у спільному пулі.

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "2"

Pod вище працює у класі QoS Гарантований, оскільки вказані лише limits і requests встановлюються рівними limits, коли не вказані явно. І обмеження ресурсу контейнера для процесора є цілим числом, більшим або дорівнює одному. Контейнер nginx отримує 2 ексклюзивні процесори.

Опції статичної політики

Поведінку статичної політики можна налаштувати за допомогою опцій політики CPU Manager. Наступні опції політики існують для статичної політики управління процесорами: {{/* опції в алфавітному порядку */}}

align-by-socket (alpha, стандартно приховано)
Вирівнювання процесорів за фізичним пакетом / межами сокета, а не за логічними межами NUMA (доступно з Kubernetes v1.25) distribute-cpus-across-cores (alpha, стандартно приховано)
Розподіл віртуальних ядер, іноді званих апаратними потоками, між різними фізичними ядрами (доступно з Kubernetes v1.31) distribute-cpus-across-numa (alpha, стандартно приховано)
Розподіл процесорів між різними доменами NUMA, прагнучи до рівномірного балансу між вибраними доменами (доступно з Kubernetes v1.23) full-pcpus-only (beta, стандартно видно)
Завжди виділяти повні фізичні ядра (доступно з Kubernetes v1.22) strict-cpu-reservation (alpha, стандартно приховано)
Запобігання всім Pod, незалежно від їх класу якості обслуговування, працювати на зарезервованих процесорах (доступно з Kubernetes v1.32) prefer-align-cpus-by-uncorecache (alpha, стандартно приховано)
Вирівнювання процесорів за межами кешу uncore (останнього рівня) на основі найкращих зусиль (доступно з Kubernetes v1.32)

Ви можете вмикати та вимикати групи опцій на основі їх рівня зрілості за допомогою наступних воріт функцій:

  • CPUManagerPolicyBetaOptions (стандартно увімкнено). Вимкніть, щоб приховати опції рівня бета.
  • CPUManagerPolicyAlphaOptions (стандартно вимкнено). Увімкніть, щоб показати опції рівня альфа. Ви все одно повинні увімкнути кожну опцію за допомогою поля cpuManagerPolicyOptions у файлі конфігурації kubelet.

Для отримання більш детальної інформації про окремі опції, які ви можете налаштувати, читайте далі.

full-pcpus-only

Якщо вказано опцію політики full-pcpus-only, статична політика завжди виділятиме повні фізичні ядра. Стандартно, без цієї опції, статична політика виділяє процесори, використовуючи топологічно обізнане найкраще підходяще розміщення. На системах з увімкненим SMT політика може виділяти окремі віртуальні ядра, які відповідають апаратним потокам. Це може призвести до того, що різні контейнери будуть ділити одні й ті ж фізичні ядра; ця поведінка, своєю чергою, сприяє проблемі шумних сусідів. З увімкненою опцією kubelet прийме Pod лише якщо запит на процесори всіх його контейнерів може бути виконаний шляхом виділення повних фізичних ядер. Якщо Pod не пройде допуску, він буде переведений у стан Failed з повідомленням SMTAlignmentError.

distribute-cpus-across-numa

Якщо вказано опцію політики distribute-cpus-across-numa, статична політика рівномірно розподілятиме процесори між вузлами NUMA у випадках, коли більше ніж один вузол NUMA потрібен для задоволення виділення. Стандартно, CPUManager буде пакувати процесори на один вузол NUMA, поки він не буде заповнений, з будь-якими залишковими процесорами, що просто переходять на наступний вузол NUMA. Це може спричинити небажані вузькі місця у паралельному коді, що покладається на барʼєри (та подібні примітиви синхронізації), оскільки цей тип коду зазвичай працює лише так швидко, як його найповільніший робітник (який сповільнюється через те, що на принаймні одному вузлі NUMA доступно менше процесорів). Розподіляючи процесори рівномірно між вузлами NUMA, розробники застосунків можуть легше забезпечити, що жоден робітник не страждає від ефектів NUMA більше, ніж будь-який інший, покращуючи загальну продуктивність таких типів застосунків.

align-by-socket

Якщо вказано опцію політики align-by-socket, процесори будуть вважатися вирівняними на межі сокета при вирішенні, як виділяти процесори для контейнера. Стандартно, CPUManager вирівнює виділення процесорів на межі NUMA, що може призвести до зниження продуктивності, якщо процесори потрібно буде взяти з більш ніж одного вузла NUMA для задоволення виділення. Хоча він намагається забезпечити, щоб усі процесори були виділені з мінімальної кількості вузлів NUMA, немає гарантії, що ці вузли NUMA будуть на одному сокеті. Спрямовуючи CPUManager явно вирівнювати процесори на межі сокета замість межі NUMA, ми можемо уникнути таких проблем. Зверніть увагу, що ця опція політики не сумісна з політикою TopologyManager single-numa-node і не застосовується до апаратного забезпечення, де кількість сокетів більша ніж кількість вузлів NUMA.

distribute-cpus-across-cores

Якщо вказано опцію політики distribute-cpus-across-cores, статична політика спробує виділити віртуальні ядра (апаратні потоки) між різними фізичними ядрами. Стандартно, CPUManager має тенденцію пакувати процесори на якомога меншу кількість фізичних ядер, що може призвести до конфліктів між процесорами на одному фізичному ядрі та спричинити вузькі місця продуктивності. Увімкнувши опцію політики distribute-cpus-across-cores, статична політика забезпечує, що процесори розподіляються між якомога більшою кількістю фізичних ядер, зменшуючи конфлікти на одному фізичному ядрі та тим самим покращуючи загальну продуктивність. Однак важливо зазначити, що ця стратегія може бути менш ефективною, коли система сильно завантажена. За таких умов користь від зменшення конфліктів зменшується. Навпаки, стандартна поведінка може допомогти зменшити накладні витрати на міжядерну комунікацію, потенційно забезпечуючи кращу продуктивність за умов високого навантаження.

strict-cpu-reservation

Параметр reservedSystemCPUs у KubeletConfiguration, або застарілий параметр командного рядка kubelet --reserved-cpus, визначає явний набір процесорів для системних демонів ОС та системних демонів kubernetes. Більш детальну інформацію про цей параметр можна знайти на сторінці Явно зарезервований список процесорів. Стандартно ця ізоляція реалізована лише для гарантованих podʼів з цілочисельними запитами на процесор, але не для podʼів burstable та best-effort (а також гарантованих podʼів з дробовими запитами на процесор). Допуск полягає лише у порівнянні запитів на процесор з виділеним процесором. Оскільки ліміт процесорів вищий за кількість запитів, стандартна поведінка дозволяє podʼам burstable та best-effort використати весь потенціал зарезервованих системних процесорів reservedSystemCPUs, що призводить до «голодування» служб ОС у реальних умовах розгортання. Якщо увімкнено параметр політики strict-cpu-reservation, статична політика не дозволить будь-якому робочому навантаженню використовувати ядра процесора, вказані у reservedSystemCPUs.

prefer-align-cpus-by-uncorecache

Якщо вказано політику prefer-align-cpus-by-uncorecache, статична політика розподілятиме ресурси процесора для окремих контейнерів таким чином, щоб усі процесори, призначені для контейнера, використовували один і той самий блок кешу ядра (також відомий як кеш останнього рівня або LLC). Стандартно CPUManager щільно пакує призначення CPU, що може призвести до того, що контейнерам буде призначено процесори з декількох кешів основного ядра. Цей параметр дозволяє CPUManager розподіляти процесори таким чином, щоб максимально ефективно використовувати кеш-памʼять ядра. Розподіл виконується за принципом best-effort, з метою привʼязки якомога більшої кількості процесорів до одного і того ж кешу. Якщо потреба контейнера у процесорах перевищує потужність одного кешу, CPUManager мінімізує кількість використовуваних кешів, щоб підтримувати оптимальне вирівнювання кешів. Конкретні робочі навантаження можуть виграти у продуктивності завдяки зменшенню міжкешових затримок та шумних сусідів на рівні кешу. Якщо CPUManager не може вирівняти оптимально, хоча вузол має достатньо ресурсів, контейнер все одно буде прийнято з використанням стандартної поведінки пакування.

Політики керування памʼяттю

СТАН ФУНКЦІОНАЛУ: Kubernetes v1.32 [stable] (стандартно увімкнено: true)

Менеджер памʼяті Kubernetes Memory Manager уможливлює функцію гарантованого виділення памʼяті (та hugepages) для podʼів у класі Guaranteed QoS class.

Диспетчер памʼяті використовує протокол генерації підказок, щоб отримати найбільш відповідну спорідненість NUMA для кожного з podʼів. Менеджер памʼяті передає ці підказки центральному менеджеру (Topology Manager). На основі підказок і політики менеджера топології, pod відхиляється або приймається до вузла.

Крім того, менеджер пам'яті гарантує, що пам'ять, яку запитує вузол виділяється з мінімальної кількості вузлів NUMA.

Інші менеджери ресурсів

Налаштування окремих менеджерів описано у окремих документах:

Змінено December 17, 2024 at 11:53 AM PST: Sync upstream after v1.32 release (d7b08bbf8e)