Це багатосторінковий друкований вигляд цього розділу. Натисність щоб друкувати.

Повернутися до звичайного перегляду сторінки.

Керування ресурсами

Як Kubernetes представляє, запитує, виділяє та обмежує ресурси, які споживають робочі навантаження.

Цей розділ описує, як Kubernetes представляє, запитує, виділяє та обмежує ресурси, які споживають робочі навантаження, включно зі спеціалізованими апаратними пристроями.

1 - Менеджери ресурсів

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

Менеджер топології

This is a stable feature in Kubernetes, and has been since the 1.27 release. You can no longer toggle this feature (the associated feature gate has been removed).

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

Менеджер CPU

This is a stable feature in Kubernetes, and has been since the 1.26 release. You can no longer toggle this feature (the associated feature gate has been removed).

Менеджер CPU — це компонент kubelet, який забезпечує ексклюзивне виділення ресурсів CPU. Для прийняття рішень щодо призначення ресурсів він консультується з менеджером топології. Щоб дізнатися більше, прочитайте Налаштування політик керування CPU на вузлі.

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

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

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

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

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

Примітка:

Системні сервіси, такі як середовище виконання контейнерів і сам kubelet, можуть і надалі працювати на цих ексклюзивних CPU. Ексклюзивність поширюється лише на інші Podʼи.

Менеджер CPU не підтримує вимкнення та ввімкнення CPU під час роботи.

Політика static

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

Примітка:

kubelet вимагає резервування CPU більше за нуль, коли ввімкнено політику static. Це тому, що нульове резервування CPU дозволило б спільному пулу стати порожнім.

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

Розгляньмо контейнери в наведених нижче специфікаціях 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 Guaranteed, оскільки requests дорівнюють limits. І обмеження ресурсу CPU контейнера є цілим числом, більшим або рівним одиниці. Контейнер nginx отримує 2 ексклюзивні CPU.

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

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

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

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

Параметри політики static

Ось доступні параметри політики керування CPU static, перелічені в алфавітному порядку:

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

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

  • CPUManagerPolicyBetaOptions (стандартно увімкнено). Вимкніть, щоб приховати параметри рівня beta.
  • CPUManagerPolicyAlphaOptions (стандартно вимкнено). Увімкніть, щоб показати параметри рівня alpha.

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

Щоб дізнатися більше про окремі параметри, які можна налаштувати, читайте далі.

full-pcpus-only

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

distribute-cpus-across-numa

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

align-by-socket

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

distribute-cpus-across-cores

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

strict-cpu-reservation

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

prefer-align-cpus-by-uncorecache

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

Менеджер памʼяті

СТАН ФУНКЦІОНАЛУ: GA since Kubernetes v1.32; (стандартно увімкнено)
More information about this feature

This is a stable feature in Kubernetes, and has been since version 1.32. It was first available in the v1.21 release.

Менеджер памʼяті — це компонент kubelet, який забезпечує ексклюзивне виділення ресурсів памʼяті. Для прийняття рішень щодо призначення ресурсів він консультується з менеджером топології. Щоб дізнатися більше, прочитайте Керування політиками управління памʼяттю на вузлі.

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

Менеджер памʼяті Kubernetes виділяє ресурси оперативної памʼяті (памʼять і, за потреби, великі сторінки Linux) для Podʼів із класом QoS Guaranteed.

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

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

Щоб дізнатися більше, прочитайте Керування політиками управління памʼяттю на вузлі.

Менеджер пристроїв

СТАН ФУНКЦІОНАЛУ: GA since Kubernetes v1.26

Менеджер пристроїв — це компонент kubelet, який виділяє апаратні пристрої Podʼам за допомогою API втулків пристроїв. Для прийняття рішень щодо призначення ресурсів він консультується з менеджером топології, використовуючи інформацію про топологію, надану втулками пристроїв. Щоб дізнатися більше, прочитайте Інтеграція втулків пристроїв з менеджером топології.

Менеджери ресурсів на рівні Podʼів

СТАН ФУНКЦІОНАЛУ: Beta since Kubernetes v1.37; (стандартно вимкнено)
More information about this feature

To use this feature, you (or a cluster administrator) will need to enable the PodLevelResourceManagers feature gate for all relevant components in your cluster.

See Enable Or Disable Feature Gates for more information.

Підтримка ресурсів на рівні Podʼів для менеджерів ресурсів kubelet (топології, CPU та памʼяті) дозволяє менеджерам ресурсів використовувати .spec.resources безпосередньо для рішень щодо вирівнювання за NUMA та ексклюзивного виділення.

Щоб дізнатися більше, перегляньте окрему сторінку концепції Менеджери ресурсів на рівні Podʼів або прочитайте, як призначати ресурси CPU та памʼяті на рівні Podʼів.

Що далі

2 - Менеджери ресурсів на рівні Podʼів

СТАН ФУНКЦІОНАЛУ: Beta since Kubernetes v1.37; (стандартно вимкнено)
More information about this feature

To use this feature, you (or a cluster administrator) will need to enable the PodLevelResourceManagers feature gate for all relevant components in your cluster.

See Enable Or Disable Feature Gates for more information.

Підтримка ресурсів на рівні Podʼів для наявних менеджерів ресурсів (топології, CPU та памʼяті) розширює їх для обробки специфікацій ресурсів на рівні Podʼів. Коли цю можливість увімкнено (через функціональні можливості PodLevelResources та PodLevelResourceManagers), менеджери ресурсів можуть використовувати .spec.resources безпосередньо як основу для своїх рішень щодо виділення, переходячи від суто поконтейнерної моделі виділення до моделі, орієнтованої на Pod. Ця схема розділення впроваджує гнучкішу й потужнішу модель керування ресурсами, особливо для чутливих до продуктивності робочих навантажень. Вона дозволяє визначати гібридні моделі виділення, у яких деякі контейнери в Podʼі отримують ексклюзивні, вирівняні за NUMA ресурси, тоді як інші спільно використовують решту ресурсів зі спільного пулу на рівні Podʼа.

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

Щоб зрозуміти менеджери ресурсів на рівні Podʼів, корисно порівняти їх із традиційною моделлю, орієнтованою на контейнери. Раніше виділення ресурсів kubelet працювало суто за принципом «все або нічого»: щоб отримати ексклюзивні, вирівняні за NUMA ресурси для вашого робочого навантаження, кожен контейнер у Podʼі мав бути Guaranteed (із запитами, що дорівнюють обмеженням і для CPU, і для памʼяті).

Менеджери ресурсів на рівні Podʼів використовують .spec.resources, щоб забезпечити гнучке розділення на основі налаштованої області дії менеджера топології:

  • Область дії pod: kubelet виділяє та вирівнює за NUMA єдину «бульбашку» Podʼа для всього Podʼа на основі .spec.resources. Контейнери, які запитують ексклюзивні виділення, вирізають окремі частки всередині цієї «бульбашки», тоді як усі інші контейнери спільно використовують решту місткості «бульбашки» у спільному пулі, ізольованому на рівні Podʼа.
  • Область дії container: Вмикає гібридну модель виділення. kubelet дозволяє окремим контейнерам отримувати ексклюзивні, вирівняні за NUMA ресурси безпосередньо з доступного для розподілу пулу вузла, водночас використовуючи верхню межу .spec.resources Podʼа для обмеження сукупного споживання. Це дозволяє sidecar-контейнерам працювати в загальному спільному пулі вузла, не вимагаючи, щоб кожен контейнер у Podʼі був Guaranteed.

Повністю підтримуються як стандартні init-контейнери, так і init-контейнери з можливістю перезапуску (sidecar-контейнери). Вони можуть отримувати ексклюзивні частки ресурсів або використовувати спільний пул Podʼа, а менеджери ресурсів на рівні Podʼів дотримуються їхніх правил життєвого циклу (наприклад, повторно використовувані ресурси для стандартних init-контейнерів і постійні резервування для sidecar-контейнерів).

Глосарій

Специфікація ресурсів на рівні Podʼа
Бюджет ресурсів, визначений на рівні Podʼа в .spec.resources, який задає сукупні запити та обмеження для всього Podʼа.
Контейнер Guaranteed
Контейнер, запити ресурсів якого дорівнюють його обмеженням і для CPU (ексклюзивне виділення CPU вимагає додатного цілого значення), і для памʼяті. Відповідно до наявної поведінки kubelet, це робить контейнер придатним для ексклюзивного виділення ресурсів менеджерами ресурсів.
Ексклюзивна частка
Виділена частина ресурсів (наприклад, конкретні CPU або сторінки памʼяті), призначена виключно одному контейнеру, що забезпечує ізоляцію від інших контейнерів.
Спільний пул Podʼа
Підмножина виділених ресурсів Podʼа, яка залишається після резервування всіх ексклюзивних часток. Ці ресурси спільно використовуються всіма контейнерами в Podʼі, які не отримують ексклюзивного виділення. Хоча контейнери в цьому пулі спільно використовують ресурси один з одним, вони суворо ізольовані від ексклюзивних часток і загального спільного пулу вузла.

Як працюють менеджери ресурсів на рівні Podʼів

Менеджери ресурсів CPU та Memory працюють по-різному залежно від налаштованої області дії менеджера топології.

Область дії pod менеджера топології та ресурси на рівні Podʼів

Коли область дії менеджера топології встановлено в pod, kubelet виконує єдине вирівнювання за NUMA для всього Podʼа на основі бюджету ресурсів, визначеного в .spec.resources.

Отриманий вирівняний за NUMA пул ресурсів потім розділяється:

  1. Ексклюзивні частки: Контейнери, які визначають ресурси Guaranteed (запити дорівнюють обмеженням і для CPU, і для памʼяті, а запит CPU є додатним цілим числом), отримують ексклюзивні частки із загального виділення Podʼа.
  2. Спільний пул Podʼа: Решта ресурсів утворює спільний пул для всіх інших контейнерів у Podʼі, які не отримують ексклюзивного виділення. Хоча контейнери в цьому пулі спільно використовують ресурси один з одним, вони суворо ізольовані від ексклюзивних часток і загального спільного пулу вузла.

Зверніть увагу, що коли стандартні init-контейнери завершують виконання, їхні ресурси переходять у повторно використовуваний набір для Podʼа, а не повертаються до пулу ресурсів вузла. Оскільки вони виконуються послідовно, наступні контейнери застосунку можуть повторно використовувати ці ресурси (або для власних ексклюзивних часток, або для спільного пулу).

Це дозволяє розміщувати разом контейнери, які потребують ексклюзивних ресурсів (наприклад, високопродуктивний основний застосунок), з тими, які цього не потребують (наприклад, sidecar-контейнери для логування або моніторингу), і все це в межах одного вирівняного за NUMA Podʼа.

Розгляньмо контейнери в наведеній нижче специфікації Podʼа, де область дії менеджера топології — pod, а Pod має загальний бюджет у 4 CPU. main-app запитує ексклюзивну частку у 2 CPU, тоді як sidecar-контейнери спільно використовують решту 2 CPU у спільному пулі Podʼа:

apiVersion: v1
kind: Pod
metadata:
  name: pod-scope-mixed
  annotations:
    kubernetes.io/description: "A pod demonstrating pod-level scope where one container gets exclusive resources and others share the remaining pod resources in a shared pool."
spec:
  # At Pod level, the Pod has CPU request equal to limits and memory request
  # also equal to memory limits. The main-app container meets the requirements
  # for the Guaranteed QoS class at container level, and the sidecar containers
  # don't specify any resource request. Under pod scope, this means that the
  # kubelet could statically assign 4 CPUs to the overall Pod, of which 2 are
  # assigned exclusively to the main-app container, and the remaining 2 are
  # shared by the sidecars in the pod's shared pool.
  resources:
    requests:
      cpu: "4"
      memory: "4Gi"
    limits:
      cpu: "4"
      memory: "4Gi"
  initContainers:
  - name: metrics-sidecar
    # Note: This is a placeholder image for demonstration purposes, not an
    #actual metrics helper.
    image: registry.k8s.io/pause:3.9
    restartPolicy: Always
  - name: logging-sidecar
    # Note: This is a placeholder image for demonstration purposes, not an
    # actual logging agent.
    image: registry.k8s.io/pause:3.9
    restartPolicy: Always
  containers:
  - name: main-app
    # Note: This is a placeholder image for demonstration purposes.
    image: registry.k8s.io/pause:3.9
    resources:
      requests:
        cpu: "2"
        memory: "2Gi"
      limits:
        cpu: "2"
        memory: "2Gi"

Важливі міркування:

Під час використання ресурсів на рівні Podʼів з областю дії pod менеджера топології є кілька важливих міркувань:

  • Обмеження порожнього спільного пулу: Ця конфігурація не дозволяє специфікації Podʼа, які призвели б до порожнього спільного пулу Podʼа, якщо є контейнери, які потребують такого пулу. Якщо сума запитів ресурсів усіх контейнерів, які є Guaranteed, точно дорівнює загальному бюджету ресурсів, і є принаймні один інший контейнер, який потребує спільного пулу, kubelet відхиляє Pod під час допуску.

    Наприклад, наведений нижче Pod запитує бюджет на рівні Podʼа у 4 CPU. main-app потребує ексклюзивних 3 CPU, а metrics-sidecar — ексклюзивного 1 CPU. Оскільки у спільному пулі для logging-sidecar залишається 0 CPU, kubelet відхиляє цей Pod (та сама перевірка застосовується до памʼяті):

    apiVersion: v1
      kind: Pod
      metadata:
        name: empty-shared-pool
        annotations:
          kubernetes.io/description: "A pod demonstrating a configuration that is rejected because exclusive containers consume the entire pod resource budget, leaving no resources for the remaining container in the shared pool."
      spec:
        # At Pod level, the Pod has CPU request equal to limits and memory request
        # also equal to memory limits. The main-app and metrics-sidecar containers
        # meet the requirements for the Guaranteed QoS class at container level, and
        # the logging-sidecar container doesn't specify any resource request. Because
        # the Guaranteed containers consume the entire pod resource budget,
        # leaving 0 CPUs for the shared pool required by logging-sidecar, this pod
        # will be rejected at admission.
        resources:
          requests:
            cpu: "4"
            memory: "4Gi"
          limits:
            cpu: "4"
            memory: "4Gi"
        initContainers:
        - name: metrics-sidecar
          # Note: This is a placeholder image for demonstration purposes, not an
          # actual metrics helper.
          image: registry.k8s.io/pause:3.9
          restartPolicy: Always
          resources:
            requests:
              cpu: "1"
              memory: "1Gi"
            limits:
              cpu: "1"
              memory: "1Gi"
        - name: logging-sidecar
          # Note: This is a placeholder image for demonstration purposes, not an
          # actual logging agent.
          image: registry.k8s.io/pause:3.9
          restartPolicy: Always
        containers:
        - name: main-app
          # Note: This is a placeholder image for demonstration purposes.
          image: registry.k8s.io/pause:3.9
          resources:
            requests:
              cpu: "3"
              memory: "3Gi"
            limits:
              cpu: "3"
              memory: "3Gi"
      
  • Втрачені ресурси: Будь-які ресурси, надмірно виділені під час використання області дії pod (сума запитів контейнерів менша за бюджет на рівні Podʼа, і немає контейнерів спільного пулу, або контейнери спільного пулу не повністю використовують решту), залишаються призначеними та зарезервованими для Podʼа, фактично марнуючись протягом усього виконання Podʼа.

  • Постійний пул: Загальний пул ресурсів Podʼа (вирівнювання за NUMA та загальна зарезервована місткість) є постійним. Якщо контейнер спільного пулу аварійно завершується та перезапускається, загальне резервування ресурсів Podʼа залишається надійно закріпленим на вузлі. Вузол повертає ресурси до свого загального пулу лише тоді, коли завершується весь Pod.

Область дії container менеджера топології та ресурси на рівні Podʼів

Коли область дії менеджера топології встановлено в container, kubelet оцінює кожен контейнер окремо для ексклюзивного виділення.

Якщо весь Pod досягає класу QoS Guaranteed (завдяки відповідним значенням у .spec.resources на рівні Podʼа), ви можете поєднувати контейнери:

  • Контейнери з власними запитами Guaranteed отримують ексклюзивні, вирівняні за NUMA ресурси.
  • Інші контейнери в Podʼі, які не визначають запити Guaranteed, працюють у спільному пулі вузла.
  • На сукупне споживання ресурсів усіма контейнерами все одно діють обмеження .spec.resources Podʼа.

Ця область дії корисна, коли у вас є інфраструктурний sidecar-контейнер, який має бути вирівняний за конкретним вузлом NUMA для доступу до пристроїв, тоді як основне робоче навантаження може працювати в загальному спільному пулі вузла.

Розгляньмо контейнери в наведеній нижче специфікації Podʼа, де область дії менеджера топології — container, а Pod представляє робоче навантаження з інфраструктурним sidecar-контейнером і двома робочими процесами застосунку із загальним бюджетом у 4 CPU. infrastructure-sidecar отримує ексклюзивну, вирівняну за NUMA частку у 2 CPU. Два робочі процеси застосунку (worker-1 та worker-2) працюють у загальному спільному пулі вузла:

apiVersion: v1
kind: Pod
metadata:
  name: container-scope-mixed
  annotations:
    kubernetes.io/description: "A pod demonstrating container-level scope where one container gets exclusive resources and others run in the node's shared pool."
spec:
  # At Pod level, the Pod has CPU request equal to limits and memory request
  # also equal to memory limits. The infrastructure-sidecar container meets the
  # requirements for the Guaranteed QoS class at container level, and the worker
  # containers don't specify any resource request. Under container scope, the
  # kubelet evaluates containers individually for exclusive allocation. This
  # means the infrastructure-sidecar gets an exclusive 2 CPU slice, while the
  # worker containers run in the node's general shared pool, all while bounded
  # by the overall pod limits.
  resources:
    requests:
      cpu: "4"
      memory: "4Gi"
    limits:
      cpu: "4"
      memory: "4Gi"
  initContainers:
  - name: infrastructure-sidecar
    # Note: This is a placeholder image for demonstration purposes, not an
    # actual infrastructure helper.
    image: registry.k8s.io/pause:3.9
    restartPolicy: Always
    resources:
      requests:
        cpu: "2"
        memory: "2Gi"
      limits:
        cpu: "2"
        memory: "2Gi"
  containers:
  - name: worker-1
    # Note: This is a placeholder image for demonstration purposes.
    image: registry.k8s.io/pause:3.9
  - name: worker-2
    # Note: This is a placeholder image for demonstration purposes.
    image: registry.k8s.io/pause:3.9

Квота CPU (CFS)

Під час виконання змішаних робочих навантажень у межах Podʼа kubelet забезпечує ізоляцію по-різному залежно від виділення:

  • Ексклюзивні контейнери: Для контейнерів з ексклюзивними частками CPU застосування квоти CPU CFS вимкнено, що дозволяє їм працювати без тротлінгу планувальником Linux.
  • Контейнери спільного пулу Podʼа: Для контейнерів у спільному пулі Podʼа квоти CPU CFS увімкнено, що гарантує, що вони не споживають більше за залишковий бюджет Podʼа, і не дає їм заважати ексклюзивним контейнерам.

Постійний пул і перезапуски

Загальний пул ресурсів Podʼа (вирівнювання за NUMA та загальна зарезервована місткість) є постійним. Якщо контейнер у спільному пулі Podʼа аварійно завершується та перезапускається, загальне резервування ресурсів Podʼа залишається надійно закріпленим на вузлі. Вузол повертає ресурси до свого загального пулу лише тоді, коли завершується весь Pod.

Пониження версії kubelet та контрольні точки стану

У Kubernetes 1.36 увімкнення PodLevelResourceManagers оновило внутрішні файли контрольних точок стану kubelet (cpu_manager_state та memory_manager_state) до формату, який старіші версії kubelet не можуть завантажити. Якщо ви понизите версію kubelet 1.36 після активного використання, старіший kubelet не зможе запуститися; ви маєте виконати drain вузла, видалити ці файли контрольних точок і перезапустити kubelet.

У Kubernetes 1.37 файли контрольних точок використовують формат, сумісний із майбутніми версіями, щоб запобігти збоям запуску під час пониження версії, хоча версії kubelet 1.36 не відновлюють активні призначення ресурсів на рівні Podʼів. Докладні відомості про формати контрольних точок і відновлення дивіться в довіднику менеджерів ресурсів на рівні Podʼів.

Спостережуваність і метрики

Ви можете контролювати поведінку та справність менеджерів ресурсів як для виділень на рівні контейнерів, так і на рівні Podʼів за допомогою таких метрик kubelet (увімкнених через функціональну можливість PodLevelResourceManagers):

  • resource_manager_allocations_total: підраховує загальну кількість ексклюзивних виділень ресурсів, виконаних менеджером. Мітка source ("pod" або "node") розрізняє виділення з пулу на рівні вузла та попередньо виділеного пулу на рівні Podʼа.
  • resource_manager_allocation_errors_total: підраховує помилки, що виникають під час ексклюзивного виділення ресурсів, розрізняючи їх за передбачуваним джерелом source виділення ("pod" або "node").
  • resource_manager_container_assignments: відстежує сукупну кількість контейнерів, яким буде надано конкретний тип призначення ресурсів. Мітка assignment_type ("node_exclusive", "pod_exclusive", "pod_shared") забезпечує видимість того, скільки контейнерів працюють з ексклюзивними ресурсами (з пулу вузла або Podʼа) порівняно зі спільним пулом на рівні Podʼа.

PodResources API

У Kubernetes 1.37 локальний для вузла gRPC API PodResources kubelet включає виділення ресурсів на рівні Podʼів, коли увімкнено PodLevelResourceManagers. Локальні для вузла агенти моніторингу та втулки пристроїв можуть запитувати призначення верхнього рівня для Podʼів (cpu_ids та memory), уникаючи подвійного підрахунку виділень на рівні контейнерів.

Повні схеми API, маски полів і таблиці звітування за областями дії дивіться в довіднику менеджерів ресурсів на рівні Podʼів.

Обмеження та застереження

  • Функціональність реалізована лише для політики static менеджера CPU та політики Static менеджера памʼяті. Зверніть увагу, що політика BestEffort не підтримується для менеджера памʼяті.
  • Ця можливість підтримується лише на вузлах Linux. На вузлах Windows менеджери ресурсів для виділень на рівні Podʼів нічого не робитимуть (no-op).

Що далі