Керування політиками управління памʼяттю на вузлі
Kubernetes v1.32 [stable](стандартно увімкнено)Менеджер памʼяті Kubernetes (Memory Manager) дозволяє функцію гарантованого виділення памʼяті (та великих сторінок) для Podʼів QoS класу Guaranteed.
Менеджер памʼяті використовує протокол генерації підказок для вибору найбільш відповідної спорідненості NUMA для точки доступу. Менеджер памʼяті передає ці підказки центральному менеджеру (Менеджеру топології). На основі як підказок, так і політики Менеджера топології, Pod відхиляється або допускається на вузол.
Крім того, Менеджер памʼяті забезпечує, що памʼять, яку запитує Pod, виділяється з мінімальної кількості NUMA-вузлів.
Для отримання додаткової інформації про ресурси памʼяті для Podʼів, прочитайте Призначення ресурсів памʼяті для контейнерів і Podʼів.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Версія вашого Kubernetes сервера має бути не старішою ніж v1.32.
Для перевірки версії введіть kubectl version.
Необхідні умови для вирівнювання ресурсів
Щоб вирівняти ресурси пам'яті з іншими запитуваними ресурсами в специфікації Podʼа:
- Менеджер CPU повинен бути увімкнений, і на вузлі повинна бути налаштована відповідна політика Менеджера CPU. Див. управління політиками керування CPU;
- Менеджер топології повинен бути увімкнений, і на вузлі повинна бути налаштована відповідна політика Менеджера топології. Див. управління політиками керування топологією.
Підтримка Windows
Kubernetes v1.32 [alpha](стандартно вимкнено)Підтримка Windows може бути увімкнена за допомогою функціональної можливості WindowsCPUAndMemoryAffinity, для чого необхідна підтримка в середовищі виконання контейнера. У Windows підтримуються лише політики None та BestEffort.
Як працює Менеджер памʼяті?
Для вузлів Linux Менеджер памʼяті пропонує виділення гарантованої памʼяті (та великих сторінок) для Podʼів у класі QoS Guaranteed. Щоб негайно ввести Менеджер памʼяті в роботу, слідкуйте вказівкам у розділі Налаштування Менеджера памʼяті, а потім підготуйте та розгорніть Pod Guaranteed, як показано в розділі Розміщення Podʼів класу QoS Guaranteed.
Менеджер памʼяті є постачальником підказок і надає підказки топології для Менеджера топології, який потім вирівнює запитані ресурси згідно з цими підказками топології. В Linux, він також застосовує cgroups (зокрема cpuset.mems) для Podʼів. Повна схематична діаграма щодо процесу допуску та розгортання Podʼа показано нижче:
Під час цього процесу Менеджер памʼяті оновлює свої внутрішні лічильники, що зберігаються в Node Map та Memory Maps, для управління гарантованим виділенням памʼяті.
Менеджер памʼяті активується під час запуску kubelet, якщо адміністратор вузла налаштовує reservedMemory для kubelet (розділ Налаштування зарезервованої памʼяті). У цьому випадку kubelet оновлює мапу вузлів, щоб показати це резервування.
Коли налаштована політика Static, ви повинні налаштувати зарезервовану памʼять для вузла (наприклад, за допомогою поля конфігурації reservedMemory у конфігурації kubelet).
Важливою темою в контексті роботи Менеджера памʼяті є управління групами NUMA. Кожного разу, коли запит на памʼять Podʼа перевищує ємність одного вузла NUMA, Менеджер памʼяті намагається створити групу, що складається з декількох вузлів NUMA і має розширену ємність памʼяті.
Налаштування Менеджера памʼяті
Інші Менеджери вже повинні бути налаштовані (див. передумови вирівнювання ресурсів. Встановіть поле конфігурації memoryManagerPolicy в конфігурації kubelet, відповідно до назви обраної вами політики.
За бажанням, можна зарезервувати певний обсяг памʼяті для системних процесів або процесів kubelet, щоб підвищити стабільність вузла (розділ Конфігурація зарезервованої памʼяті).
Політики
Менеджер памʼяті Kubernetes надає три політики. Ви можете вибрати політику за допомогою поля конфігурації memoryManagerPolicy у конфігурації kubelet; значення, доступні в Kubernetes 1.35, такі:
None(типово)Static(тільки Linux)BestEffort(тільки Windows)
Політика None
Це типова політика і вона не впливає на виділення памʼяті жодним чином. Вона працює так само як і коли Менеджер памʼяті взагалі відсутній.
Політика None повертає типову підказку топології. Ця спеціальна підказка позначає, що Hint Provider (в цьому випадку Менеджер памʼяті) не має переваги щодо спорідненості NUMA з будь-яким ресурсом.
Політика Static
Kubernetes v1.32 [stable](стандартно увімкнено)Ця політика підтримується тільки в Linux.
У випадку Guaranteed Podʼа політика Менеджера памʼяті Static повертає підказки топології, що стосуються набору NUMA-вузлів, де памʼять може бути гарантованою, та резервує памʼять, оновлюючи внутрішній обʼєкт NodeMap.
У випадку Podʼа BestEffort або Burstable політика Менеджера памʼяті Static повертає назад типову підказку топології, оскільки немає запиту на гарантовану памʼять, і не резервує памʼять внутрішнього обʼєкта NodeMap.
Ця політика підтримується тільки в Linux.
Політика BestEffort
Kubernetes v1.32 [alpha](стандартно вимкнено)Ця політика підтримується лише у Windows.
У Windows призначення вузлів NUMA працює інакше, ніж у Linux. Не існує механізму, який би гарантував, що доступ до памʼяті надається лише з певного вузла NUMA. Замість цього планувальник операційної системи Windows вибере найоптимальніший вузол NUMA на основі призначень процесора(ів). Можливо, Windows може використовувати інші вузли NUMA, якщо планувальник Windows вважатиме їх оптимальними.
Політика відстежує кількість доступної та запитуваної памʼяті за допомогою внутрішньої node map. Менеджер памʼяті докладе максимум зусиль для забезпечення достатнього обсягу памʼяті на вузлі NUMA перед тим, як призначити памʼять. Це означає, що у більшості випадків розподіл памʼяті має відбуватися як вказано.
Прапорець зарезервованої памʼяті
Як адміністратор, ви можете налаштувати загальний обсяг зарезервованої памʼяті для вузла. Це попередньо налаштоване значення згодом використовується для обчислення реального обсягу памʼяті node allocatable, доступної для подів.
Планувальник Kubernetes використовує інформацію про доступну памʼять для оптимізації планування подів. Механізм node allocatable зазвичай використовується адміністраторами вузлів для резервування системних ресурсів вузлів K8s для процесів kubelet або операційної системи, щоб забезпечити стабільність вузлів.
Відповідні налаштування kubelet включають kubeReserved, systemReserved та reservedMemory. Налаштування reservedMemory дозволяє розділити загальний обсяг зарезервованої памʼяті та розподілити його між багатьма вузлами NUMA.
Ви вказуєте список резервувань памʼяті, розділених комами, різних типів памʼяті для кожного вузла NUMA. Ви також можете вказати резервування, що охоплюють кілька вузлів NUMA, використовуючи крапку з комою як роздільник.
Менеджер памʼяті не використовуватиме цю зарезервовану памʼять для виконання робочих навантажень контейнерів.
Наприклад, якщо у вас є NUMA-вузол "NUMA0" з доступною памʼяттю 10GiB, і ви налаштовуєте reservedMemory для резервування 1Gi (памʼяті) для NUMA0, диспетчер памʼяті припускає, що для подів доступно лише 9GiB.
Ви можете пропустити цей параметр, однак слід памʼятати, що обсяг зарезервованої памʼяті з усіх вузлів NUMA повинен дорівнювати обсягу пам'яті, яку можна розподілити між вузлами.
Якщо хоча б один параметр, що можна розподілити між вузлами, має значення, відмінне від нуля, вам потрібно буде вказати reservedMemory хоча б для одного вузла NUMA. Фактично, порогове значення evictionHard стандартно дорівнює 100Mi, тому якщо ви використовуєте політику Static, то вказати reservedMemory треба обовʼязково.
Синтаксис зарезервованої памʼяті менеджера памʼяті
Ось декілька прикладів того, як налаштувати конфігурацію reservedMemory для kubelet.
# Приклад 1
reservedMemory:
- numaNode: 0 # Індекс вузла NUMA
limits:
memory: "1Gi" # Кількість байтів
- numaNode: 1
limits:
memory: "2Gi" # Кількість байтів
# Приклад 2
reservedMemory:
- numaNode: 0
limits:
"memory": "512Gi"
- numaNode: 1
limits:
"memory": "512Gi"
"hugepages-1Gi": "2Gi" # актуально тільки для Linux
Обмеження на резервування памʼяті NUMA
Коли ви вказуєте значення для reservedMemory, вони повинні бути сумісними з чинними значеннями kubeReserved та systemReserved, а також з будь-якими налаштуваннями memory.available, які ви вказуєте в рамках evictionHard.
Якщо ви не дотримуєтесь вищезазначеної формули, Менеджер памʼяті покаже помилку при запуску.
Іншими словами, у вищезазначеному прикладі 1 (вище) показано, що для звичайної памʼяті (type=memory) Kubernetes резервує загалом 3GiB, а саме:
Деякі приклади налаштувань конфігурації kubelet, що стосуються конфігурації, яку можна розподілити між вузлами:
kubeReserved: { cpu: "500m", memory: "50Mi" } # половина CPU, 50MiB памʼяті
systemReserved: { cpu: "500m", memory: "256Mi" } # половина CPU, 256MiB памʼяті
Примітка:
Типове значення для жорсткого порога виселення становить 100MiB, а не нуль. Не забудьте збільшити кількість памʼяті, яку ви резервуєте, встановивши reservedMemory на величину цього жорсткого порога виселення. В іншому випадку kubelet не запустить Менеджер памʼяті та покаже помилку.
Ось приклад правильної конфігурації, яка використовує reservedMemory:
# цей фрагмент коду використовує стандартне значення evictionHard
memoryManagerPolicy: Static
kubeReserved: { cpu: "4", memory: "4Gi" }
systemReserved: { cpu: "1", memory: "1Gi" }
reservedMemory:
- numaNode: 0
limits:
memory: "3Gi"
- numaNode: 1
limits:
memory: "2148Mi" # 3GiB мінус 100MiB
Конфігурації, яких слід уникати
Уникайте таких конфігурацій:
- дублікати: той самий вузол NUMA або тип памʼяті, але з іншим значенням;
- встановлення нульового обмеження для будь-якого типу памʼяті;
- ідентифікатори вузлів NUMA, які не існують в апаратному забезпеченні машини;
- назви типів памʼяті, відмінні від
memoryабоhugepages-<size>(також повинні існувати великі сторінки певного<size>).
Розміщення Podʼа в класі QoS Guaranteed
Якщо вибрана політика відрізняється від None, Менеджер памʼяті ідентифікує Podʼи, які належать до класу обслуговування Guaranteed. Менеджер памʼяті надає конкретні підказки топології Менеджеру топології для кожного Podʼа з класом обслуговування Guaranteed. Для Podʼів, які належать до класу обслуговування відмінного від Guaranteed, Менеджер памʼяті надає Менеджеру топології типові підказки топології.
Наведені нижче уривки з маніфестів Podʼа призначають Pod до класу обслуговування Guaranteed.
Pod з цілим значенням CPU працює в класі обслуговування Guaranteed, коли requests дорівнюють limits:
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
requests:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
Також Pod, який спільно використовує CPU, працює в класі обслуговування Guaranteed, коли requests дорівнюють limits.
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "300m"
example.com/device: "1"
requests:
memory: "200Mi"
cpu: "300m"
example.com/device: "1"
Зверніть увагу, що для Podʼа потрібно вказати як запити CPU, так і памʼяті, щоб він належав до класу обслуговування Guaranteed.
Що далі
- Прочитайте Усунення несправностей в управлінні топологією
- Прочитайте KEP (пропозиція щодо вдосконалення Kubernetes) для менеджера памʼяті