Для забезпечення роботи робочих навантажень, для яких критично важлива низька затримка та висока пропускна здатність, Kubernetes пропонує набір менеджерів ресурсів. Ці менеджери призначені для координації та оптимізації розподілу ресурсів вузлів між подами, налаштованими з конкретними вимогами до ресурсів CPU, пристроїв та памʼяті (hugepages).
Це стабільна функція в Kubernetes, яка доступна починаючи з випуску 1.27. Ви більше не можете перемикати цю функцію (повʼязану функціональну можливість було вилучено).
Менеджер топології — це компонент kubelet, який координує набір компонентів, відповідальних за ці оптимізації. Щоб дізнатися більше, прочитайте Керування політиками топології на вузлі.
Це стабільна функція в Kubernetes, яка доступна починаючи з випуску 1.26. Ви більше не можете перемикати цю функцію (повʼязану функціональну можливість було вилучено).
Менеджер CPU — це компонент kubelet, який забезпечує ексклюзивне виділення ресурсів для CPU. Він консультується з Менеджером топології для прийняття рішень щодо призначення ресурсів. Щоб дізнатися більше, прочитайте Керування політиками управління CPU на вузлі.
Після привʼязки Podʼа до вузла kubelet на цьому вузлі може потребувати або мультиплексування наявного апаратного забезпечення (наприклад, спільного використання CPU між кількома Podʼами), або виділення апаратного забезпечення шляхом резервування певних ресурсів (наприклад, виділення одного або кількох CPU для виключного використання одним Podʼом).
Зазвичай kubelet використовує CFS quota для забезпечення обмежень на використання CPU подами. Коли на вузлі працює багато подів, що завантажують CPU, робоче навантаження може переміщуватися між різними ядрами CPU залежно від того, чи обмежується под, і які ядра CPU доступні на момент планування. Багато робочих навантажень не чутливі до цього переміщення і тому працюють нормально без будь-якого втручання.
Однак у робочих навантаженнях, де спорідненість кешу CPU та затримка планування значно впливають на продуктивність, kubelet дозволяє використовувати альтернативні політики управління CPU для визначення деяких переваг розміщення на вузлі. Це реалізовано за допомогою Менеджера CPU та його політики. Існують дві доступні політики:
none: політика none явно включає наявну стандартну схему спорідненості CPU, не забезпечуючи спорідненості понад те, що автоматично робить планувальник ОС. Обмеження на використання CPU для подів Guaranteed та подів Burstable забезпечуються за допомогою CFS quota.static: політика static дозволяє контейнерам у подах Guaranteed з цілими запитами CPU отримувати доступ до ексклюзивних CPU на вузлі. Ця ексклюзивність забезпечується за допомогою cpuset cgroup controller.Менеджер CPU не підтримує відключення та підключення CPU під час виконання.
Політика static дозволяє більш детально керувати CPU та забезпечує ексклюзивне призначення CPU. Ця політика керує спільним пулом CPU, який спочатку містить усі CPU на вузлі. Кількість CPU, доступних для ексклюзивного призначення, дорівнює загальній кількості CPU на вузлі за винятком будь-яких резервувань CPU, встановлених у конфігурації kubelet. CPU, зарезервовані цими параметрами, беруться цілими числами з початкового спільного пулу у порядку зростання за фізичним ідентифікатором ядра. Цей спільний пул є набором CPU, на яких працюють будь-які контейнери в подах BestEffort та Burstable. Контейнери в подах Guaranteed з дробовими запитами CPU також працюють на CPU зі спільного пулу. Лише контейнери, які є частиною пода Guaranteed і мають цілі запити CPU, отримують ексклюзивні CPU.
Коли поди Guaranteed, контейнери яких відповідають вимогам для статичного призначення, плануються на вузлі, CPU видаляються зі спільного пулу та розміщуються в cpuset для контейнера. CFS quota не використовується для обмеження використання CPU цими контейнерами, оскільки їхнє використання обмежується самим доменом планування. Іншими словами, кількість CPU в cpuset контейнера дорівнює цілому числу CPU limit, зазначеному в специфікації пода. Це статичне призначення підвищує спорідненість CPU та зменшує перемикання контексту через обмеження для навантаження, що залежить від CPU.
Розглянемо контейнери в наступних специфікаціях пода:
spec:
containers:
- name: nginx
image: nginx
Под вище працює в класі QoS BestEffort, оскільки не вказано жодних ресурсних requests або limits. Він працює в спільному пулі.
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
Под вище працює в класі QoS Burstable, оскільки ресурсні requests не дорівнюють limits, а кількість cpu не вказана. Він працює в спільному пулі.
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "100Mi"
cpu: "1"
Под вище працює в класі QoS Burstable, оскільки ресурсні requests не дорівнюють limits. Він працює в спільному пулі.
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "200Mi"
cpu: "2"
Под вище працює в класі 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"
Под вище працює в класі QoS Guaranteed, оскільки requests дорівнюють limits. Але обмеження ресурсу CPU для контейнера є дробовим числом. Він працює в спільному пулі.
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
Под вище працює в класі QoS Guaranteed, оскільки вказано лише limits, а requests прирівнюються до limits, коли їх не вказано явно. І обмеження ресурсу CPU для контейнера є цілим числом, більшим або рівним одиниці. Контейнер nginx отримує 2 ексклюзивні CPU.
Ось доступні параметри політики static управління CPU, перераховані в алфавітному порядку:
align-by-socket (alpha, зазвичай приховано)distribute-cpus-across-cores (alpha, зазвичай приховано)distribute-cpus-across-numa (beta, зазвичай видно)full-pcpus-only (GA, зазвичай видно)strict-cpu-reservation (GA, зазвичай видно)prefer-align-cpus-by-uncorecache (GA, зазвичай видно)Ви можете вмикати або вимикати групи параметрів залежно від їх рівня зрілості, використовуючи наступні функціональні ворота:
CPUManagerPolicyBetaOptions (стандартно увімкнено). Вимкніть, щоб приховати параметри рівня beta.CPUManagerPolicyAlphaOptions (стандартно вимкнено). Увімкніть, щоб показати параметри рівня alpha.Вам все одно доведеться увімкнути кожен параметр, використовуючи поле cpuManagerPolicyOptions у файлі конфігурації kubelet.
Щоб дізнатися більше про окремі параметри, які можна налаштувати, читайте далі.
full-pcpus-onlyЯкщо вказано параметр full-pcpus-only політики, політика static завжди виділятиме повні фізичні ядра. Зазвичай, без цього параметра, політика static виділяє CPU, використовуючи топологічно-орієнтоване найкраще підходяще розміщення. На системах з увімкненим SMT політика може виділяти окремі віртуальні ядра, які відповідають апаратним потокам. Це може призвести до того, що різні контейнери будуть використовувати одні й ті ж фізичні ядра; така поведінка, у свою чергу, сприяє проблемі шумних сусідів. З увімкненим параметром, под буде прийнято kubelet лише в тому випадку, якщо запит CPU всіх його контейнерів може бути виконаний шляхом виділення повних фізичних ядер. Якщо под не отримує допуск, він буде переведений у стан 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, що може призвести до зниження продуктивності, якщо для задоволення виділення потрібно більше одного 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, політика static забезпечує розподіл CPU на якомога більшій кількості фізичних ядер, зменшуючи конкуренцію на одному фізичному ядрі та покращуючи загальну продуктивність. Однак важливо зазначити, що ця стратегія може бути менш ефективною при високому навантаженні системи. У таких умовах користь від зменшення конкуренції зменшується. Навпаки, стандартна поведінка може допомогти зменшити накладні витрати на міжядерну комунікацію, потенційно забезпечуючи кращу продуктивність при високому навантаженні.
strict-cpu-reservationПараметр reservedSystemCPUs у KubeletConfiguration, або застаріла опція командного рядка kubelet --reserved-cpus, визначає явний набір CPU для системних демонів ОС та демонів Kubernetes. Більше деталей про цей параметр можна знайти на сторінці Явно зарезервований список CPU. Стандартно, ця ізоляція реалізується лише для гарантованих подів з цілими запитами CPU, а не для подів з можливістю перевантаження та подів з найкращим зусиллям (та гарантованих подів з дробовими запитами CPU). Допуск здійснюється лише шляхом порівняння запитів CPU з доступними CPU. Оскільки ліміт CPU вищий за запит, стандартна поведінка дозволяє подам з можливістю перевантаження та подам з найкращим зусиллям використовувати всю ємність reservedSystemCPUs і спричиняти нестачу ресурсів для служб ОС у реальних розгортаннях. Якщо параметр політики strict-cpu-reservation увімкнено, політика static не дозволить жодному робочому навантаженню використовувати ядра CPU, зазначені в reservedSystemCPUs.
prefer-align-cpus-by-uncorecacheЯкщо вказано параметр prefer-align-cpus-by-uncorecache, політика static виділятиме ресурси CPU для окремих контейнерів таким чином, щоб усі CPU, призначені контейнеру, використовували один і той же блок кешу uncore (також відомий як кеш останнього рівня або LLC). Зазвичай CPUManager щільно розподіляє призначення CPU, що може призвести до того, що контейнери отримують CPU з кількох кешів uncore. Ця опція дозволяє CPUManager виділяти CPU таким чином, щоб максимально ефективно використовувати кеш uncore. Виділення здійснюється на основі найкращих зусиль, намагаючись призначити якомога більше CPU в межах одного кешу uncore. Якщо вимога контейнера щодо CPU перевищує ємність одного кешу uncore, CPUManager мінімізує кількість використаних кешів uncore, щоб підтримувати оптимальне вирівнювання кешу uncore. Конкретні робочі навантаження можуть отримати вигоду у продуктивності від зменшення затримки між кешами та шумних сусідів на рівні кешу. Якщо CPUManager не може оптимально вирівняти CPU при наявності достатніх ресурсів на вузлі, контейнер все одно буде прийнято з використанням стандартного щільного розподілу.
Це стабільна функція в
Memory Manager є компонентом kubelet, який забезпечує ексклюзивне виділення ресурсів памʼяті. Він консультується з Topology Manager для прийняття рішень щодо призначення ресурсів. Щоб дізнатися більше, прочитайте Керування політиками управління памʼяттю на вузлі.
В Kubernetes Memory Manager виділяє ресурси оперативної памʼяті (RAM, а також за потреби великі сторінки Linux) для подів у QoS class Guaranteed .
Memory Manager використовує протокол генерації підказок для визначення найбільш підходящої NUMA-спорідненості для пода. Memory Manager передає ці підказки центральному менеджеру (Topology Manager). На основі як підказок, так і політики Topology Manager, под приймається або відхиляється на вузлі.
Більше того, Memory Manager забезпечує, щоб памʼять, яку запитує под, виділялася з мінімальної кількості NUMA-вузлів.
Щоб дізнатися більше, прочитайте Керування політиками управління памʼяттю на вузлі.
Device Manager є компонентом kubelet, який виділяє апаратні пристрої для подів за допомогою API втулків пристроїв. Він консультується з Topology Manager, використовуючи інформацію про топологію, надану втулками пристроїв, для прийняття рішень щодо призначення ресурсів. Щоб дізнатися більше, прочитайте Інтеграція втулків пристроїв з Topology Manager.
Щоб скористатися цією функцією, вам (або адміністратору кластера) потрібно увімкнути функціональну можливість PodLevelResourceManagers для всіх відповідних компонентів у вашому кластері.
Перегляньте Увімкнення або вимкнення функціональних можливостей для отримання додаткової інформації.
Підтримка ресурсів на рівні Podʼів для менеджерів ресурсів kubelet (Topology, CPU та Memory) дозволяє менеджерам ресурсів використовувати .spec.resources безпосередньо для рішень щодо вирівнювання за NUMA та ексклюзивного виділення.
Щоб дізнатися більше, перегляньте присвячену сторінку концепції Менеджери ресурсів на рівні Podʼів або прочитайте, як надавати ресурси CPU та памʼяті на рівні Podʼів.