1 - Власні ресурси
Власні ресурси — це екземпляри типів ресурсів, доданих до Kubernetes через розширення API. На цій сторінці розглядається, коли додавати власний ресурс до вашого кластера Kubernetes, а коли використовувати окремий сервіс. На ній описано два методи додавання власних ресурсів і те, як вибрати між ними.
Власні ресурси
Ресурс — це точка доступу в API Kubernetes, яка зберігає колекцію обʼєктів API певного виду; наприклад, вбудований ресурс pods містить колекцію обʼєктів Pod.
Власний ресурс — це розширення API Kubernetes, яке не обовʼязково доступне в стандартній інсталяції Kubernetes. Він є налаштуванням конкретної інсталяції Kubernetes. Однак багато основних функцій Kubernetes тепер побудовані з використанням власних ресурсів, що робить Kubernetes більш модульним.
Власні ресурси можуть зʼявлятися та зникати в запущеному кластері через динамічну реєстрацію, і адміністратори кластера можуть оновлювати власні ресурси незалежно від самого кластера. Щойно власний ресурс встановлено, користувачі можуть створювати його обʼєкти та отримувати до них доступ за допомогою kubectl, так само як для вбудованих ресурсів, таких як Pods.
Власні контролери
Самі по собі власні ресурси дозволяють зберігати та отримувати структуровані дані. Коли ви поєднуєте власний ресурс з власним контролером, власні ресурси надають справжній декларативний API.
Декларативний API Kubernetes забезпечує розділення обовʼязків. Ви оголошуєте бажаний стан вашого ресурсу. Контролер Kubernetes підтримує поточний стан обʼєктів Kubernetes відповідно до оголошеного вами бажаного стану. Це відрізняється від імперативного API, де ви вказуєте серверу, що робити.
Ви можете розгортати та оновлювати власний контролер на запущеному кластері, незалежно від життєвого циклу кластера. Власні контролери можуть працювати з будь-яким видом ресурсів, але вони особливо ефективні в поєднанні з власними ресурсами. Шаблон Operator поєднує власні ресурси та власні контролери. Ви можете використовувати власні контролери, щоб закодувати доменні знання про конкретні застосунки в розширення API Kubernetes.
Чи слід додавати власний ресурс до мого кластера Kubernetes?
Під час створення нового API подумайте, чи агрегувати ваш API з API кластера Kubernetes, чи залишити ваш API незалежним.
| Розгляньте агрегацію API, якщо: | Віддайте перевагу незалежному API, якщо: |
|---|
| Ваш API є Декларативним. | Ваш API не відповідає моделі Декларативного API. |
Ви хочете, щоб ваші нові типи були доступні для читання та запису за допомогою kubectl. | Підтримка kubectl не є необхідною. |
| Ви хочете бачити свої нові типи в UI Kubernetes, такому як dashboard, поряд із вбудованими типами. | Підтримка UI Kubernetes не є необхідною. |
| Ви розробляєте новий API. | Ви вже маєте програму, яка обслуговує ваш API та працює добре. |
| Ви готові прийняти обмеження формату, які Kubernetes накладає на шляхи ресурсів REST, такі як групи API та простори імен. (Дивіться Огляд API.) | Вам потрібні специфічні шляхи REST для сумісності з уже визначеним REST API. |
| Ваші ресурси природно обмежені кластером або просторами імен кластера. | Ресурси, обмежені кластером або простором імен, погано підходять; вам потрібен контроль над специфікою шляхів ресурсів. |
| Ви хочете повторно використовувати можливості підтримки API Kubernetes. | Вам не потрібні ці можливості. |
Декларативні API
У декларативному API зазвичай:
- Ваш API складається з відносно невеликої кількості відносно невеликих обʼєктів (ресурсів).
- Обʼєкти визначають конфігурацію застосунків або інфраструктури.
- Обʼєкти оновлюються відносно рідко.
- Люди часто мають читати та записувати обʼєкти.
- Основні операції з обʼєктами — це CRUD (створення, читання, оновлення та видалення).
- Транзакції між обʼєктами не потрібні: API представляє бажаний стан, а не точний стан.
Імперативні API не є декларативними. Ознаки того, що ваш API може не бути декларативним:
- Клієнт каже «зробіть це», а потім отримує синхронну відповідь, коли це виконано.
- Клієнт каже «зробіть це», потім отримує ідентифікатор операції й повинен перевіряти окремий обʼєкт Operation, щоб визначити завершення запиту.
- Ви говорите про віддалені виклики процедур (RPC).
- Пряме зберігання великих обсягів даних; наприклад, понад кілька kB на обʼєкт або понад тисячі обʼєктів.
- Потрібен доступ із високою пропускною здатністю (стабільно десятки запитів на секунду).
- Зберігання даних кінцевих користувачів (наприклад, зображень, PII тощо) або інших великомасштабних даних, які обробляють застосунки.
- Природні операції з обʼєктами не є CRUD-подібними.
- API нелегко змоделювати як обʼєкти.
- Ви вирішили подавати операції в очікуванні за допомогою ідентифікатора операції або обʼєкта операції.
Чи слід використовувати ConfigMap або власний ресурс?
Використовуйте ConfigMap, якщо виконується будь-яка з таких умов:
- Існує наявний, добре задокументований формат файлу конфігурації, такий як
mysql.cnf або pom.xml. - Ви хочете помістити всю конфігурацію в один ключ ConfigMap.
- Файл конфігурації використовується насамперед програмою, що працює в Podʼі вашого кластера, для її самоналаштування.
- Споживачі файлу воліють отримувати його через файл у Podʼі або змінну середовища в Podʼі, а не через API Kubernetes.
- Ви хочете виконувати поетапні оновлення за допомогою Deployment тощо, коли файл оновлюється.
Примітка:
Використовуйте
Secret для конфіденційних даних, який є схожим на ConfigMap, але безпечнішим.
Використовуйте власний ресурс (CRD або агрегований API), якщо виконується більшість із таких умов:
- Ви хочете використовувати клієнтські бібліотеки та CLI Kubernetes для створення та оновлення нового ресурсу.
- Ви хочете отримати підтримку на верхньому рівні від
kubectl; наприклад, kubectl get my-object object-name. - Ви хочете побудувати нову автоматизацію, яка стежить за оновленнями нового обʼєкта, а потім виконує CRUD інших обʼєктів, або навпаки.
- Ви хочете написати автоматизацію, яка обробляє оновлення обʼєкта.
- Ви хочете використовувати домовленості API Kubernetes, такі як
.spec, .status та .metadata. - Ви хочете, щоб обʼєкт був абстракцією над колекцією контрольованих ресурсів або узагальненням інших ресурсів.
Додавання власних ресурсів
Kubernetes надає два способи додавання власних ресурсів до вашого кластера:
- CRD прості, і їх можна створити без будь-якого програмування.
- Агрегація API потребує програмування, але дає більше контролю над поведінкою API, наприклад над тим, як зберігаються дані та як виконується перетворення між версіями API.
Kubernetes надає ці два варіанти, щоб задовольнити потреби різних користувачів, не жертвуючи ні простотою використання, ні гнучкістю.
Агреговані API — це підлеглі API-сервери, розташовані за основним API-сервером, який діє як проксі. Така організація називається агрегацією API (AA). Для користувачів API Kubernetes виглядає розширеним.
CRD дозволяють користувачам створювати нові типи ресурсів без додавання ще одного API-сервера. Щоб використовувати CRD, не потрібно розуміти агрегацію API.
Незалежно від способу встановлення нові ресурси називаються власними ресурсами (Custom Resources), щоб відрізняти їх від вбудованих ресурсів Kubernetes (таких як Podʼи).
Примітка:
Уникайте використання власного ресурсу як сховища даних застосунків, кінцевих користувачів або моніторингу: архітектурні рішення, які зберігають дані застосунків в API Kubernetes, зазвичай занадто тісно повʼязані.
З архітектурного погляду архітектури застосунків cloud native надають перевагу слабкому звʼязуванню між компонентами. Якщо частина вашого робочого навантаження потребує допоміжного сервісу для своєї звичайної роботи, запустіть цей допоміжний сервіс як компонент або використовуйте його як зовнішній сервіс. Таким чином ваше робоче навантаження не залежатиме від API Kubernetes у своїй звичайній роботі.
CustomResourceDefinitions
API-ресурс CustomResourceDefinition дозволяє вам визначати власні ресурси. Визначення обʼєкта CRD створює новий власний ресурс із вказаними вами назвою та схемою. API Kubernetes обслуговує та обробляє зберігання вашого власного ресурсу. Назва самого обʼєкта CRD має бути дійсною назвою DNS-піддомену, утвореною з визначеної назви ресурсу та його групи API; докладніше дивіться як створити CRD. Крім того, назва обʼєкта, вид/ресурс якого визначено CRD, також має бути дійсною назвою DNS-піддомену.
Це звільняє вас від написання власного API-сервера для обробки власного ресурсу, але загальний характер реалізації означає, що у вас менше гнучкості, ніж з агрегацією API-серверів.
Приклад того, як зареєструвати новий власний ресурс, працювати з екземплярами вашого нового типу ресурсу та використовувати контролер для обробки подій, дивіться в прикладі власного контролера.
Агрегація API-серверів
Зазвичай кожен ресурс в API Kubernetes потребує коду, який обробляє REST-запити та керує постійним зберіганням обʼєктів. Основний API-сервер Kubernetes обробляє вбудовані ресурси, такі як pods та services, а також може узагальнено обробляти власні ресурси через CRD.
Шар агрегації дозволяє вам надавати спеціалізовані реалізації для ваших власних ресурсів, написавши та розгорнувши власний API-сервер. Основний API-сервер делегує запити вашому API-серверу для власних ресурсів, які ви обробляєте, роблячи їх доступними для всіх своїх клієнтів.
Вибір методу для додавання власних ресурсів
CRD простіші у використанні. Агреговані API більш гнучкі. Виберіть метод, який найкраще відповідає вашим потребам.
Зазвичай CRD підходять, якщо:
- У вас небагато полів
- Ви використовуєте ресурс у своїй компанії або як частину невеликого проєкту з відкритим кодом (на відміну від комерційного продукту)
Порівняння простоти використання
CRD простіше створювати, ніж агреговані API.
| CRD | Агрегований API |
|---|
| Не потребує програмування. Користувачі можуть вибрати будь-яку мову для контролера CRD. | Потребує програмування та збирання бінарного файлу й образу. |
| Немає додаткового сервісу для запуску; CRD обробляються API-сервером. | Додатковий сервіс, який потрібно створити і який може зазнати збою. |
| Після створення CRD постійна підтримка не потрібна. Усі виправлення помилок надходять разом зі звичайними оновленнями Kubernetes Master. | Може знадобитися періодично отримувати виправлення помилок з основного репозиторію (upstream), перезбирати й оновлювати агрегований API-сервер. |
| Не потрібно керувати кількома версіями вашого API; наприклад, коли ви контролюєте клієнта для цього ресурсу, ви можете оновлювати його синхронно з API. | Потрібно керувати кількома версіями вашого API; наприклад, коли розробляєте розширення для спільного використання. |
Розширені можливості та гнучкість
Агреговані API пропонують більш розширені можливості API та налаштування інших можливостей; наприклад, рівня зберігання.
| Можливість | Опис | CRD | Агрегований API |
|---|
| Валідація | Допомагає користувачам уникати помилок і дозволяє вам розвивати API незалежно від ваших клієнтів. Ці можливості найбільш корисні, коли є багато клієнтів, які не можуть оновитися одночасно. | Так. Більшість валідацій можна вказати в CRD за допомогою валідації OpenAPI v3.0. Функціональна можливість CRDValidationRatcheting дозволяє ігнорувати збої валідацій, вказаних за допомогою OpenAPI, якщо частина ресурсу, яка не пройшла валідацію, не змінювалася. Будь-які інші валідації підтримуються шляхом додавання валідаційного вебхука. | Так, довільні перевірки |
| Встановлення стандартних значень | Див. вище | Так, або через ключове слово default валідації OpenAPI v3.0 (GA в 1.17), або через змінювальний вебхук (хоча він не виконуватиметься під час читання старих обʼєктів з etcd). | Так |
| Підтримка кількох версій | Дозволяє обслуговувати той самий обʼєкт через дві версії API. Може спростити такі зміни API, як перейменування полів. Менш важливо, якщо ви контролюєте версії клієнтів. | Так | Так |
| Власне сховище | Якщо вам потрібне сховище з іншим режимом продуктивності (наприклад, база даних часових рядів замість сховища ключ-значення) або ізоляція для безпеки (наприклад, шифрування конфіденційної інформації тощо) | Ні | Так |
| Власна бізнес-логіка | Виконання довільних перевірок або дій під час створення, читання, оновлення або видалення обʼєкта | Так, за допомогою вебхуків. | Так |
| Субресурс масштабування | Дозволяє таким системам, як HorizontalPodAutoscaler та PodDisruptionBudget, взаємодіяти з вашим новим ресурсом | Так | Так |
| Субресурс статусу | Дозволяє детальний контроль доступу, коли користувач записує розділ spec, а контролер — розділ status. Дозволяє збільшувати Generation обʼєкта під час зміни даних власного ресурсу (потребує окремих розділів spec і status у ресурсі) | Так | Так |
| Інші субресурси | Додавання операцій, відмінних від CRUD, таких як "logs" або "exec". | Ні | Так |
| strategic-merge-patch | Нові точки доступу підтримують PATCH з Content-Type: application/strategic-merge-patch+json. Корисно для оновлення обʼєктів, які можуть бути змінені як локально, так і сервером. Докладніше див. «Оновлення обʼєктів API на місці за допомогою kubectl patch» | Ні | Так |
| Protocol Buffers | Новий ресурс підтримує клієнтів, які хочуть використовувати Protocol Buffers | Ні | Так |
| Схема OpenAPI | Чи є схема OpenAPI (swagger) для типів, яку можна динамічно отримати із сервера? Чи захищений користувач від помилок у назвах полів завдяки тому, що можна встановлювати лише дозволені поля? Чи примусово перевіряються типи (іншими словами, чи неможливо помістити int у поле string)? | Так, на основі схеми валідації OpenAPI v3.0 (GA в 1.16). | Так |
| Назва екземпляра | Чи накладає цей механізм розширення будь-які обмеження на назви обʼєктів, вид/ресурс яких визначено таким чином? | Так, назва такого обʼєкта має бути дійсною назвою DNS-піддомену. | Ні |
Спільні можливості
Створюючи власний ресурс, через CRD або AA, ви отримуєте багато можливостей для вашого API порівняно з його реалізацією поза платформою Kubernetes:
| Можливість | Що вона робить |
|---|
| CRUD | Нові точки доступу підтримують базові операції CRUD через HTTP та kubectl |
| Watch | Нові точки доступу підтримують операції Watch Kubernetes через HTTP |
| Discovery | Клієнти, такі як kubectl та dashboard, автоматично пропонують операції переліку, відображення та редагування полів для ваших ресурсів |
| json-patch | Нові точки доступу підтримують PATCH з Content-Type: application/json-patch+json |
| merge-patch | Нові точки доступу підтримують PATCH з Content-Type: application/merge-patch+json |
| HTTPS | Нові точки доступу використовують HTTPS |
| Вбудована автентифікація | Доступ до розширення використовує основний API-сервер (шар агрегації) для автентифікації |
| Вбудована авторизація | Доступ до розширення може повторно використовувати авторизацію основного API-сервера; наприклад, RBAC. |
| Завершувачі | Блокування видалення ресурсів розширення, доки не відбудеться зовнішнє очищення. |
| Вебхуки допуску | Встановлення стандартних значень і валідація ресурсів розширення під час будь-якої операції створення, оновлення або видалення. |
| Відображення в UI/CLI | Kubectl та dashboard можуть відображати ресурси розширення. |
| Невстановлене та порожнє | Клієнти можуть відрізняти невстановлені поля від полів із нульовим значенням. |
| Генерація клієнтських бібліотек | Kubernetes надає загальні клієнтські бібліотеки, а також інструменти для генерації клієнтських бібліотек для конкретних типів. |
| Мітки та анотації | Загальні метадані обʼєктів, які інструменти вміють редагувати для основних і власних ресурсів. |
Підготовка до встановлення власного ресурсу
Перш ніж додавати власний ресурс до вашого кластера, слід врахувати кілька моментів.
Код сторонніх розробників і нові точки відмови
Хоча створення CRD саме по собі не додає нових точок відмови (наприклад, через запуск коду сторонніх розробників на вашому API-сервері), пакети (наприклад, Charts) або інші набори для встановлення часто містять CRD, а також Deployment з кодом сторонніх розробників, який реалізує бізнес-логіку нового власного ресурсу.
Встановлення агрегованого API-сервера завжди передбачає запуск нового Deployment.
Сховище
Власні ресурси споживають простір сховища так само, як і ConfigMaps. Створення занадто великої кількості власних ресурсів може перевантажити простір сховища вашого API-сервера.
Власні ресурси розміщуються у сховищі на основі поточної версії зберігання ресурсу, визначеної в специфікації CRD. Будь-яке оновлення власного ресурсу використовує поточну визначену версію зберігання для збереження ресурсу. Усі інші версії повинні або містити всі поля цієї версії, або визначати перетворення, щоб працювати належним чином.
Агреговані API-сервери можуть використовувати те саме сховище, що й основний API-сервер; у такому разі застосовується те саме застереження.
Автентифікація, авторизація та аудит
CRD завжди використовують ту саму автентифікацію, авторизацію та логування аудиту, що й вбудовані ресурси вашого API-сервера.
Якщо ви використовуєте RBAC для авторизації, більшість ролей RBAC не надають доступу до нових ресурсів (окрім ролі cluster-admin або будь-якої ролі, створеної з wildcard-правилами). Вам потрібно явно надати доступ до нових ресурсів. CRD та агреговані API часто постачаються з новими визначеннями ролей для типів, які вони додають.
Агреговані API-сервери можуть використовувати або не використовувати ту саму автентифікацію, авторизацію та аудит, що й основний API-сервер.
Доступ до власного ресурсу
Клієнтські бібліотеки Kubernetes можна використовувати для доступу до власних ресурсів. Не всі клієнтські бібліотеки підтримують власні ресурси. Клієнтські бібліотеки Go та Python підтримують.
Після додавання власного ресурсу ви можете отримати до нього доступ за допомогою:
kubectl- Динамічного клієнта Kubernetes.
- REST-клієнта, який ви напишете.
- Клієнта, згенерованого за допомогою інструментів генерації клієнтів Kubernetes (генерація клієнта є складним завданням, але деякі проєкти можуть постачати клієнта разом із CRD або AA).
Селектори полів власних ресурсів
Селектори полів дозволяють клієнтам вибирати власні ресурси за значенням одного чи кількох полів ресурсу.
Усі власні ресурси підтримують селектори полів metadata.name та metadata.namespace.
Поля, оголошені в CustomResourceDefinition, також можна використовувати із селекторами полів, якщо вони вказані в полі spec.versions[*].selectableFields у CustomResourceDefinition.
Поля власних ресурсів, доступні для вибору
СТАН ФУНКЦІОНАЛУ:
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.30 release.
Поле spec.versions[*].selectableFields у CustomResourceDefinition можна використовувати, щоб оголосити, які ще поля власного ресурсу можна використовувати в селекторах полів.
У цьому прикладі поля .spec.color та .spec.size додаються як поля, доступні для вибору.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: shirts.stable.example.com
spec:
group: stable.example.com
scope: Namespaced
names:
plural: shirts
singular: shirt
kind: Shirt
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
color:
type: string
size:
type: string
selectableFields:
- jsonPath: .spec.color
- jsonPath: .spec.size
additionalPrinterColumns:
- jsonPath: .spec.color
name: Color
type: string
- jsonPath: .spec.size
name: Size
type: string
Після цього за допомогою селекторів полів можна отримати лише ресурси зі значенням color blue:
kubectl get shirts.stable.example.com --field-selector spec.color=blue
Вивід має бути таким:
NAME COLOR SIZE
example1 blue S
example2 blue M
Що далі
2 - Шар агрегації API Kubernetes
Шар агрегації дозволяє розширювати Kubernetes додатковими API, понад те, що пропонують основні API Kubernetes. Додатковими API можуть бути як готові рішення, такі як сервер метрик, так і API, які ви розробляєте самостійно.
Шар агрегації відрізняється від Custom Resource Definitions, які є способом зробити так, щоб kube-apiserver розпізнавав нові види обʼєктів.
Шар агрегації
Шар агрегації працює в одному процесі з kube-apiserver. Поки ресурс розширення не зареєстровано, шар агрегації нічого не робить. Щоб зареєструвати API, ви додаєте обʼєкт APIService, який «заявляє права» на шлях URL в API Kubernetes. Після цього шар агрегації проксіюватиме все, що надсилається на цей шлях API (наприклад, /apis/myextension.mycompany.io/v1/…), до зареєстрованого APIService.
Найпоширеніший спосіб реалізації APIService — запуск API-сервера розширення в Podʼах, які працюють у вашому кластері. Якщо ви використовуєте API-сервер розширення для керування ресурсами у своєму кластері, API-сервер розширення (також пишеться як "extension-apiserver") зазвичай працює в парі з одним або кількома контролерами. Бібліотека apiserver-builder надає кістяк як для API-серверів розширення, так і для відповідних контролерів.
Затримки відповіді
API-сервери розширення повинні мати мережевий звʼязок із малою затримкою до kube-apiserver і від нього. Запити виявлення мають проходити шлях туди й назад від kube-apiserver за пʼять секунд або менше.
Якщо ваш API-сервер розширення не може відповідати цій вимозі щодо затримки, розгляньте зміни, які дозволять їй відповідати.
Що далі
Або дізнайтеся, як розширити API Kubernetes за допомогою Custom Resource Definitions.