# API модулів планування та бібліотека workloadbuilder

> Базові елементи API планування, що можуть використовуватися багаторазово, які вбудовані контролери робочих навантажень (як вбудовані, так і зовнішні) інтегрують у свої власні API, а також спільна бібліотека workloadbuilder, яка компілює їх у об’єкти Workload, PodGroup та CompositePodGroup.

---

LLMS index: [llms.txt](/llms.txt)

---

<!-- overview -->














            

            
              
            <div class="feature-state-notice feature-beta" title="Функціональна можливість: GenericWorkload">
              <span class="feature-state-name">Стан функціоналу:</span>
              <span class="feature-state-details">
               
                 <span class='feature-state-stage'>Beta</span> починаючи з Kubernetes v1.37; стандартно вимкнено
               </span>
            </div>

            
            <div class="feature-beta">
              
              
                <details>
                <summary>Докладніше про цей функціонал</summary>
                <p>Щоб скористатися цією функцією, вам (або адміністратору кластера) потрібно увімкнути функціональну можливість <a href="/uk/docs/reference/command-line-tools-reference/feature-gates/#GenericWorkload"><tt>GenericWorkload</tt></a> для всіх відповідних компонентів у вашому кластері.</p>
<p>Перегляньте <a href="/uk/docs/tasks/administer-cluster/configure-feature-gates/">Увімкнення або вимкнення функціональних можливостей</a> для отримання додаткової інформації.</p>

                </details>
                </div>


Workload-Aware Scheduling визначає набір багаторазово використовуваних *будівельних блоків* API у <a class='glossary-tooltip' title='Набір повʼязаних шляхів в API Kubernetes.' data-bs-toggle='tooltip' data-bs-placement='top' href='/uk/docs/concepts/overview/kubernetes-api/#api-groups-and-versioning' target='_blank' aria-label='групі API'>групі API</a> `scheduling.k8s.io`. Автори контролерів вбудовують ці примітиви у свої власні API, щоб користувачі виражали намір щодо планування (групове планування, топологія, поведінка розладу) з узгодженою схемою в усій екосистемі, а спільна бібліотека `workloadbuilder` компілює цей намір в орієнтовані на планувальник обʼєкти [Workload](/docs/concepts/workloads/workload-api/), [PodGroup](/docs/concepts/workloads/podgroup-api/) та [CompositePodGroup](/docs/concepts/workloads/workload-api/compositepodgroup-api/).

Вбудованим споживачем цих будівельних блоків сьогодні є контролер [Job](/docs/concepts/workloads/controllers/job/), який контролюється функціональною можливістю [`WorkloadWithJob`](/docs/reference/command-line-tools-reference/feature-gates/) .

<!-- body -->

## Будівельні блоки багаторазового використання {#reusable-building-blocks}

Будівельні блоки — це строго типізовані структури Go у групі API `scheduling.k8s.io/v1alpha3`. Вони призначені для *авторів контролерів*: контролер вбудовує ці структури у свій власний тип API як поля, а бібліотека `workloadbuilder` компілює їх. Назви типів слідують двом конвенціям: типи кінцевого рівня мають префікс `WorkloadPodGroup...` (наприклад, `WorkloadPodGroupSchedulingPolicy`), а багаторівневі варіанти — `WorkloadCompositePodGroup...`.

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

Щоб прийняти будівельні блоки, контролер додає ті з них, які хоче підтримувати, як поля у своїх власних типах. Наприклад, API [Job](/docs/concepts/workloads/controllers/job/) групує всі чотири з них в один тип, доступний за адресою `spec.scheduling`:

```go
type JobSchedulingConfiguration struct {
    SchedulingPolicy      *schedulingv1alpha3.WorkloadPodGroupSchedulingPolicy
    SchedulingConstraints *schedulingv1alpha3.WorkloadPodGroupSchedulingConstraints
    DisruptionMode        *schedulingv1alpha3.WorkloadPodGroupDisruptionMode
    ResourceClaims        []schedulingv1alpha3.WorkloadPodGroupResourceClaim
}
```

Інший контролер може вкладати ті самі блоки для кожного компонента багаточастинного робочого навантаження або підтримувати лише їх підмножину.

### Політика планування {#scheduling-policy}

Блок політики планування несе ті самі політики `basic` та `gang`, що й `spec.schedulingPolicy` PodGroup. Див. [політики планування PodGroup](/docs/concepts/workloads/workload-api/policies/) для пояснення, що означає кожна політика та як планувальник її застосовує.

Єдина відмінність полягає в тому, що мінімальна кількість `gang` у блоці є необовʼязковою. Користувачі можуть залишити `minCount` невстановленим, і в цьому випадку контролер надає стандартне значення, яке має сенс для його власної області; контролер Job, наприклад, використовує паралелізм Job.

### Обмеження планування {#scheduling-constraints}

Блок обмежень планування несе топологічні обмеження, задокументовані в [топологічно-орієнтованому плануванні робочих навантажень](/docs/concepts/workloads/workload-api/topology-aware-scheduling/): ключ мітки вузла, що називає домен (наприклад, стійку або зону), який повинен бути спільним для кожного Podʼа в групі, з не більш ніж одним топологічним обмеженням на групу. Контролери повинні заморозити поле після створення, оскільки обмеження є незмінними в скомпільованому Workload.

### Режим розладу {#disruption-mode}

Блок режиму розладу визначає, чи можуть Podʼи групи отримати розлад індивідуально (`single`) або лише як єдине ціле (`all`), що відповідає режимам розладу `Pod` та `PodGroup`, задокументованим у [розладі та пріоритеті групи Pod](/docs/concepts/workloads/workload-api/disruption-and-priority/).

Бібліотека відхиляє комбінації, які не мають сенсу. Наприклад, забороняє режим розладу `all` для PodGroups з BasicSchedulingPolicy, оскільки одиниця витіснення не повинна бути більшою за одиницю планування — група, запланована под за подом, не має одиниці на рівні групи для витіснення або розладу.

### Заявки на ресурси {#resource-claims}

Блок заявок на ресурси виражає, які заявки [динамічного виділення ресурсів](/docs/concepts/scheduling-eviction/dynamic-resource-allocation/) є спільними для кожного Podʼа в групі, а не виділяються на кожен Pod окремо. Кожен запис називає заявку в межах групи та вказує або на наявний <a class='glossary-tooltip' title='Описує ресурси, які потрібні робочому навантаженню, наприклад, пристрої. ResourceClaims можуть запитувати пристрої з DeviceClasses.' data-bs-toggle='tooltip' data-bs-placement='top' href='/uk/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#resourceclaims-templates' target='_blank' aria-label='ResourceClaim'>ResourceClaim</a>, або на <a class='glossary-tooltip' title='Визначає шаблон для Kubernetes для створення ResourceClaims. Використовується для забезпечення доступу до окремих схожих ресурсів на кожному Podʼі або PodGroup.' data-bs-toggle='tooltip' data-bs-placement='top' href='/uk/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#resourceclaims-templates' target='_blank' aria-label='ResourceClaimTemplate'>ResourceClaimTemplate</a>, з якого вона генерується. Група може оголосити не більше чотирьох заявок.

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

### Композитні будівельні блоки {#composite-building-blocks}

Багаторівневі контролери, які оркеструють інші контролери (наприклад, JobSet, що створює Jobs), координують *групу груп*. Для цього рівня API надає аналогічний набір примітивів з префіксом `WorkloadCompositePodGroup...` (наприклад, `WorkloadCompositePodGroupSchedulingPolicy`). Вони слідують тим самим формам, що й блоки кінцевого рівня, за винятком того, що композитна політика gang використовує `minGroupCount` (мінімальну кількість дочірніх груп, які повинні бути заплановані разом) замість `minCount` кінцевого рівня. Збереження окремих типів кінцевого та композитного рівнів дозволяє кожному рівню ієрархії розвиватися незалежно.

### Приклад: інтеграція з Job {#example-the-job-integration}

Контролер Job є вбудованим прикладом використання цих блоків. Користувач заповнює `spec.scheduling` Job, а контролер компілює його в Workload та PodGroup. Див. [інтеграцію з Workload API](/docs/concepts/workloads/controllers/job/#integrate-with-workload-apis) для повного маніфесту Job, стандартних значень, які застосовуються, коли `spec.scheduling` пропущено, та які поля ви можете змінювати після створення.

## Бібліотека workloadbuilder {#the-workloadbuilder-library}

`workloadbuilder` — це спільна бібліотека Go, яка перетворює намір контролера щодо планування в орієнтовані на планувальник Workload та його обʼєкти PodGroup/CompositePodGroup під час виконання, тому кожен контролер не реалізовує повторно стандартні значення, перевірку та компіляцію шаблонів. Вона розроблена як для вбудованих контролерів (таких як контролер Job), так і для сторонніх контролерів (таких як JobSet або Kubeflow TrainJob), які вбудовують її як будь-яку іншу залежність Go. Вона постачається з `k8s.io/component-helpers/scheduling/schedulingv1/workloadbuilder`.

Бібліотека споживає будівельні блоки `scheduling.k8s.io/v1alpha3` та компілює їх в обʼєкти Workload та PodGroup `scheduling.k8s.io/v1beta1`, тоді як обʼєкти CompositePodGroup залишаються `scheduling.k8s.io/v1alpha3`.

### Як контролер її використовує {#how-a-controller-uses-it}

Контролер описує своє робоче навантаження як дерево вузлів `WorkloadItem`, по одному на кожен логічний компонент. Вузол без дочірніх елементів стає одним `PodGroupTemplate`, тоді як вузол з дочірніми елементами стає `CompositePodGroupTemplate` над ними — саме так багаторівневий контролер представляє групу груп. Кожен вузол несе:

* *стандартну конфігурацію* — власні стандартні значення контролера для всього, що користувач залишає невстановленим. Саме тут контролер вирішує, наприклад, що неналаштований Job залишається на плануванні `basic`.
* *вхідні дані* — намір користувача, взятий з API контролера. Контролер записує кожен будівельний блок разом із шляхом до поля, на якому він розташований, щоб помилки перевірки вказували на точне поле, яке встановив користувач.
* необовʼязкові *зворотні виклики*, які коригують обʼєднану конфігурацію. Саме так контролер надає контекстно-залежне стандартне значення, наприклад, заповнює невстановлену мінімальну кількість gang з паралелізму Job.

Потім контролер передає це дерево `Builder` і проходить через чотири виклики:

1. `NewBuilder` створює будівельник з дерева, а також імʼя, простір імен та посилання на власника для обʼєкта, який буде створено. Власник стає посиланням на контролер Workload, яке використовується для виявлення та прибирання сміття.
1. `Validate` розвʼязує дерево та повідомляє про будь-які проблеми як список помилок полів, які контролер повертає з власної перевірки API.
1. `BuildWorkload` компілює дерево в Workload. Результат кешується, тому з одного скомпільованого результату можна створити кілька PodGroups.
1. `NewPodGroup` створює PodGroup під час виконання з одного зі скомпільованих шаблонів, називаючи шаблон, з якого він повинен бути створений.

```go
builder := workloadbuilder.NewBuilder(item, opts)
if errs := builder.Validate(ctx, workloadbuilder.ValidationInput{}); len(errs) > 0 {
    // reject the request
}
workload, err := builder.BuildWorkload()
podGroup, err := builder.NewPodGroup("trainer-pg", item.Name)
```

Для повних, робочих версій цього потоку, включаючи те, як контролер Job його підключає, див. приклади в [довіднику пакунка](https://pkg.go.dev/k8s.io/component-helpers/scheduling/schedulingv1/workloadbuilder).

### Перевірка конфігурації планування {#validating-a-scheduling-configuration}

`Validate` перевіряє конфігурацію на двох рівнях:

* **Структурна перевірка** самих будівельних блоків: обовʼязкові поля, діапазони значень, правило, що рівно один член обʼєднання встановлений, та незмінність. Ці перевірки походять з правил [декларативної перевірки](/docs/reference/using-api/declarative-validation/), згенерованих з типів API.
* **Перевірки політики контролера**, які декларативна перевірка не може виразити: списки дозволених значень, описані нижче, та міжпольові правила, такі як відхилення режиму розладу `all` разом з політикою `basic`.

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

#### Відмова від декларативної перевірки {#opting-out-of-declarative-validation}

Чи потрібен вам перший рівень, залежить від того, де працює ваш контролер, і одна опція керує ним:

* **Сторонні контролери** залишають декларативну перевірку увімкненою, що є стандартним значенням. Ніщо інше не застосовує ці структурні правила до власного ресурсу, тому один виклик `Validate` покриває обидва рівні.
* **Вбудовані контролери** встановлюють `DisableDeclarativeValidation`, оскільки сервер API вже виконує декларативну перевірку вбудованих блоків під час перевірки батьківського обʼєкта. Пропуск першого рівня дозволяє уникнути перевірки тих самих полів двічі, залишаючи `Validate` виконувати лише перевірки політики контролера.

#### Вибір опцій планування {#opting-in-to-scheduling-options}

Оскільки типи будівельних блоків є спільними для контролерів, майбутні випуски можуть додавати опції планування, які не мають сенсу для кожного контролера. Щоб нові опції не просочувалися непомітно, `workloadbuilder` використовує модель списку дозволених значень: контролер оголошує політики та режими розладу, які він підтримує, а `Validate` відхиляє все, що виходить за межі цього набору, повідомляючи про помилку за шляхом до поля блоку, що порушує правила.

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

```go
builder := workloadbuilder.NewBuilder(item, workloadbuilder.BuildOptions{
    Owner:                  owner,
    AllowedPolicies:        []workloadbuilder.SchedulingPolicyOption{workloadbuilder.BasicPolicy, workloadbuilder.GangPolicy},
    AllowedDisruptionModes: []workloadbuilder.DisruptionModeOption{workloadbuilder.SingleMode, workloadbuilder.AllMode},
})
allErrs := builder.Validate(ctx, workloadbuilder.ValidationInput{})
```

### Створення PodGroups з наявного Workload {#generating-podgroups-from-an-existing-workload}

Коли Workload вже існує, незалежно від того, чи він скомпільований батьківським контролером, чи створений вручну, дочірній контролер, який керує лише PodGroup під час виконання, використовує натомість `NewBuilderFromExistingWorkload`. Цей будівельник створює обʼєкти PodGroup з наданого Workload, використовуючи власне посилання на власника. Він нічого не перевіряє та не компілює, тому наявний Workload ніколи не перекомпілюється.

```go
builder := workloadbuilder.NewBuilderFromExistingWorkload(parentWorkload, workloadbuilder.BuildOptions{Owner: owner})
podGroup, err := builder.NewPodGroup("trainer-pg", "trainer-pgt-0")
```

## Що далі

* Дізнайтеся про [політики планування PodGroup](/docs/concepts/workloads/workload-api/policies/).
* Дізнайтеся про [розлад та пріоритет групи Pod](/docs/concepts/workloads/workload-api/disruption-and-priority/).
* Дізнайтеся про [топологічно-орієнтоване планування робочих навантажень](/docs/concepts/workloads/workload-api/topology-aware-scheduling/).
* Перегляньте огляд [Workload API](/docs/concepts/workloads/workload-api/).
* Подивіться, як контролер Job [інтегрується з Workload API](/docs/concepts/workloads/controllers/job/#integrate-with-workload-apis).
* Прочитайте [довідник пакета `workloadbuilder`](https://pkg.go.dev/k8s.io/component-helpers/scheduling/schedulingv1/workloadbuilder).
