Kubernetes v1.35: Представляємо планування з урахуванням навантаження

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

Існує багато спеціальних планувальників, пристосованих для ефективного планування робочих навантажень, але з огляду на те, наскільки поширеним і важливим є планування робочих навантажень для користувачів Kubernetes, особливо в епоху штучного інтелекту з дедалі більшою кількістю випадків використання, настав час зробити робочі навантаження першочерговим завданням для kube-scheduler і підтримувати їх нативно.

Планування з урахуванням навантаження

В останньому випуску Kubernetes 1.35 було представлено першу частину вдосконалень планування з урахуванням навантаження. Вони є частиною ширших зусиль, спрямованих на поліпшення планування та управління навантаженнями. Ці зусилля охоплюватимуть багато SIG та версій і мають поступово розширювати можливості системи для досягнення головної мети, якою є безперебійне планування та управління робочими навантаженнями в Kubernetes, включаючи, але не обмежуючись, випередженням та автоматичним масштабуванням.

Kubernetes v1.35 представляє Workload API, який можна використовувати для опису бажаного вигляду, а також вимог до планування робочого навантаження. Він постачається з початковою реалізацією планування груп, яка наказує kube-scheduler планувати групи Podʼів за принципом все або нічого. Нарешті, ми вдосконалили планування ідентичних Podʼів (які зазвичай утворюють групи) для прискорення процесу завдяки функції ситуативного пакетування.

Workload API

Новий ресурс Workload API є частиною scheduling.k8s.io/v1alpha1 API group. Цей ресурс діє як структуроване, машиночитане визначення вимог до планування застосунку з декількома Podʼами. У той час як робочі навантаження, орієнтовані на користувача, такі як Jobs, визначають, що потрібно запустити, ресурс Workload визначає, як слід планувати групу Podʼів і як слід керувати її розміщенням протягом усього життєвого циклу.

Workload дозволяє визначити групу Podʼів і застосувати до них політику планування. Ось як виглядає конфігурація планування групи. Ви можете визначити podGroup з назвою workers і застосувати політику gang з minCount, що дорівнює 4.

apiVersion: scheduling.k8s.io/v1alpha1
kind: Workload
metadata:
  name: training-job-workload
  namespace: some-ns
spec:
  podGroups:
  - name: workers
    policy:
      gang:
        # Група планується лише якщо одночасно можуть працювати 4 Podʼи
        minCount: 4

Коли ви створюєте свої Podʼи, ви повʼязуєте їх із цим робочим навантаженням за допомогою нового поля workloadRef:

apiVersion: v1
kind: Pod
metadata:
  name: worker-0
  namespace: some-ns
spec:
  workloadRef:
    name: training-job-workload
    podGroup: workers
  ...

Як працює групове планування

Політика gang забезпечує розміщення за принципом «все або нічого». Без групового планування завдання може бути заплановано частково, споживаючи ресурси без можливості виконання, що призводить до марнування ресурсів і потенційних тупикових ситуацій.

Коли ви створюєте Podʼи, які є частиною групи Podʼів із груповим плануванням, втулок GangScheduling планувальника управляє життєвим циклом незалежно для кожної групи Podʼів (або ключа репліки):

  1. Коли ви створюєте свої Podʼи (або контролер створює їх для вас), планувальник блокує їх планування, доки:

    • Не буде створено обʼєкт Workload, на який є посилання.
    • Посилання на групу Podʼів існує в Workload.
    • Кількість очікуючих Podʼів у цій групі відповідає вашому minCount.
  2. Коли зʼявляється достатня кількість Podʼів, планувальник намагається їх розмістити. Однак замість того, щоб відразу привʼязувати їх до вузлів, Podʼи чекають на воротах Permit.

  3. Планувальник перевіряє, чи знайшов він дійсні призначення для всієї групи (принаймні minCount).

    • Якщо для групи є місце, ворота відкриваються, і всі Podʼи привʼязуються до вузлів.
    • Якщо лише частина Podʼів групи була успішно запланована протягом часу очікування (встановленого на 5 хвилин), планувальник відхиляє всі Podʼи у групі. Вони повертаються до черги, звільняючи зарезервовані ресурси для інших робочих навантажень.

Хочемо зазначити, що хоча це перша реалізація, проєкт Kubernetes має твердий намір вдосконалити та розширити алгоритм групового планування в майбутніх версіях. Серед переваг, які ми сподіваємося досягти, — фаза планування за один цикл для всієї групи, витіснення на рівні робочого навантаження та інше, що наближає нас до нашої головної мети.

Ситуативна пакетна обробка

На додачу до явного групового планування, у версії 1.35 запроваджено ситуативну пакетну обробку. Це бета-функція, яка покращує затримку планування для ідентичних Podʼів.

На відміну від групового планування, ця функція не вимагає Workload API або явного погодження з боку користувача. Вона працює ситуативно в рамках планувальника, ідентифікуючи Podʼи, які мають однакові вимоги до планування (образи контейнерів, запити на ресурси, спорідненість тощо). Коли планувальник обробляє Pod, він може повторно використовувати розрахунки здійсненності для наступних однакових Podʼів у черзі, що значно прискорює процес.

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

Обмеження

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

Зверніть увагу, що вам може знадобитися переглянути конфігурацію kube-scheduler, щоб переконатися, що вона не вимикає пакетну обробку для ваших робочих навантажень.

Більш детальну інформацію про обмеження дивіться в документації.

Довготривалі перспективи

Проєкт має амбітну мету — забезпечити планування з урахуванням навантаження. Ці нові API та вдосконалення планування — лише перші кроки. У найближчому майбутньому планується вирішити такі завдання:

  • Впровадження фази планування навантаження
  • Покращення підтримки багатовузлового DRA та планування з урахуванням топології
  • Витіснення на рівні навантаження
  • Покращення інтеграції між плануванням і автомасштабуванням
  • Покращення взаємодії із зовнішніми планувальниками робочого навантаження
  • Управління розміщенням робочих навантажень протягом усього їхнього життєвого циклу
  • Моделювання планування багатозадачного робочого навантаження

І багато іншого. Пріоритетність і порядок реалізації цих пріоритетних напрямків можуть змінюватися. Слідкуйте за подальшими оновленнями.

Початок роботи

Щоб випробувати вдосконалення планування з урахуванням навантаження:

  • Workload API: увімкніть функцію GenericWorkload на kube-apiserver і kube-scheduler та переконайтеся, що scheduling.k8s.io/v1alpha1 API group увімкнено.
  • Групове планування: увімкніть функцію GangScheduling на kube-scheduler (потрібно увімкнути Workload API).
  • Ситуативне пакетування: як бета-функція, вона типово ввімкнена у v1.35. Ви можете вимкнути її за допомогою функціональної можливості OpportunisticBatching на kube-scheduler, якщо потрібно.

Ми рекомендуємо вам спробувати планування з урахуванням навантаження у ваших тестових кластерах і поділитися своїм досвідом, щоб допомогти сформувати майбутнє планування Kubernetes. Ви можете надіслати свої відгуки:

Дізнайтеся більше