Огляд API
Цей розділ містить довідкову інформацію про API Kubernetes.
REST API є фундаментальною основою Kubernetes. Усі операції та комунікації між компонентами та зовнішніми командами користувачів є викликами REST API, які обробляє API-сервер. Внаслідок цього все в Kubernetes обробляється як обʼєкти API та має відповідний запис в API.
Довідник API Kubernetes містить список API для версії Kubernetes v1.30.
Для отримання загальної інформації, читайте API Kubernetes. Керування доступом до API Kubernetes описує, як клієнти можуть автентифікуватися до сервера API Kubernetes, та як їхні запити авторизуються.
Версіювання API
Схеми серіалізації JSON та Protobuf слідують однаковими принципами для змін схеми. Наступні описи стосуються обох форматів.
Версіювання API та версіювання програмного забезпечення непрямо повʼязані. Пропозиція з версіювання API та релізів описує відносини між версіюванням API та версіюванням програмного забезпечення.
Різні версії API вказують на різні рівні стабільності та підтримки. Докладнішу інформацію про критерії кожного рівня можна знайти в документації API Changes.
Ось короткий огляд кожного рівня:
Групи API
Групи API спрощують розширення API Kubernetes. Група API вказується в REST-шляху та в полі apiVersion
серіалізованого обʼєкта.
У Kubernetes існує кілька груп API:
- core (також називається legacy) група знаходиться за REST-шляхом
/api/v1
. Основна група не вказується як частина поля apiVersion
, наприклад, apiVersion: v1
. - Названі групи знаходяться за REST-шляхом
/apis/$GROUP_NAME/$VERSION
та використовують apiVersion: $GROUP_NAME/$VERSION
(наприклад, apiVersion: batch/v1
). Повний список підтримуваних груп API можна знайти в довіднику API Kubernetes.
Увімкнення чи вимкнення груп API
Деякі ресурси та групи API типово увімкнені. Ви можете увімкнути чи вимкнути їх, встановивши --runtime-config
на API-сервері. Прапорець --runtime-config
приймає розділені комами пари <key>[=<value>]
, що описують конфігурацію запуску API-сервера. Якщо частина =<value>
пропущена, вона розглядається так, ніби вказано =true
. Наприклад:
- для вимкнення
batch/v1
встановіть --runtime-config=batch/v1=false
- для увімкнення
batch/v2alpha1
встановіть --runtime-config=batch/v2alpha1
- для увімкнення конкретної версії API, наприклад,
storage.k8s.io/v1beta1/csistoragecapacities
, встановіть --runtime-config=storage.k8s.io/v1beta1/csistoragecapacities
Примітка:
При увімкненні чи вимкненні груп, чи ресурсів потрібно перезапустити API-сервер та controller manager, щоб внести зміни до --runtime-config
.Збереження
Kubernetes зберігає свій серіалізований стан у термінах ресурсів API, записуючи їх в etcd.
Що далі
1 - Концепції API Kubernetes
API Kubernetes — це програмний інтерфейс на основі ресурсів (RESTful), який надається через HTTP. Він підтримує отримання, створення, оновлення та видалення основних ресурсів за допомогою стандартних HTTP-дієслів (POST, PUT, PATCH, DELETE, GET).
Для деяких ресурсів API включає додаткові субресурси, що дозволяють детальніше налаштовувати авторизацію (наприклад, окремі представлення для деталей Pod та отримання логів), і може приймати та надавати ці ресурси в різних форматах для зручності або ефективності.
Kubernetes підтримує ефективні сповіщення про зміни ресурсів за допомогою watches. Kubernetes також забезпечує послідовні операції зі списками, щоб клієнти API могли ефективно кешувати, відстежувати та синхронізувати стан ресурсів.
Ви можете переглянути Довідник API онлайн або прочитати далі, щоб дізнатися про API загалом.
Терміни API Kubernetes
Kubernetes зазвичай використовує загальноприйняту термінологію RESTful для опису концепцій API:
- Тип ресурсу — це назва, що використовується в URL (
pods
, namespaces
, services
) - Усі типи ресурсів мають конкретне представлення (їх схему обʼєкта), яке називається kind
- Список екземплярів типу ресурсу називається колекцією
- Окремий екземпляр типу ресурсу називається ресурсом і зазвичай представляє обʼєкт
- Для деяких типів ресурсів API включає один або більше субресурсів, які представлені як URI-шляхи після назви ресурсу
Більшість типів ресурсів API Kubernetes є обʼєктами — вони представляють конкретний екземпляр концепції у кластері, як-от pod або namespace. Невелика кількість типів ресурсів API є віртуальними, оскільки вони часто представляють операції над обʼєктами, а не самі обʼєкти, такі як перевірка дозволів (використання POST із JSON-кодованим тілом SubjectAccessReview
для ресурсу subjectaccessreviews
), або субресурс eviction
у Pod (використовується для запуску виселення, ініційованого API).
Імена обʼєктів
Усі обʼєкти, які ви можете створити через API, мають унікальне імʼя, що дозволяє ідемпотентне створення та отримання, за винятком віртуальних типів ресурсів, які можуть не мати унікальних імен, якщо вони не можуть бути отримані або не залежать від ідемпотентності. У межах простору імен може бути лише один обʼєкт з вказаним іменем для даного виду. Однак, якщо ви видалите обʼєкт, ви можете створити новий обʼєкт з тим самим іменем. Деякі обʼєкти не мають простору імен (наприклад: Nodes), тому їх імена повинні бути унікальними у всьому кластері.
Дієслова API
Майже всі типи ресурсів підтримують стандартні HTTP-дієслова — GET, POST, PUT, PATCH, та DELETE. Kubernetes також використовує власні дієслова, які часто пишуться малими літерами, щоб відрізняти їх від HTTP-дієслів.
Kubernetes використовує термін list для опису отримання колекції ресурсів, щоб відрізняти його від отримання одного ресурсу, яке зазвичай називається get. Якщо ви надішлете HTTP-запит GET із параметром ?watch
, Kubernetes називає це watch, а не get (див.
Ефективне виявлення змін для деталей).
Для запитів PUT Kubernetes внутрішньо класифікує їх як create або update залежно від стану наявного обʼєкта. Update відрізняється від patch; HTTP-дієслово для patch - PATCH.
URI ресурсів
Усі типи ресурсів або належать кластеру (/apis/GROUP/VERSION/*
), або простору імен (/apis/GROUP/VERSION/namespaces/NAMESPACE/*
). Тип ресурсу, що належить простору імен, буде видалений при видаленні простору імен, і доступ до цього типу ресурсу контролюється перевірками авторизації в межах простору імен.
Примітка: основні ресурси використовують /api
замість /apis
і пропускають сегмент GROUP.
Приклади:
/api/v1/namespaces
/api/v1/pods
/api/v1/namespaces/my-namespace/pods
/apis/apps/v1/deployments
/apis/apps/v1/namespaces/my-namespace/deployments
/apis/apps/v1/namespaces/my-namespace/deployments/my-deployment
Ви також можете отримати доступ до колекцій ресурсів (наприклад, переліку усіх Nodes). Наступні шляхи використовуються для отримання колекцій та ресурсів:
Оскільки простір імен є ресурсом кластерного рівня, ви можете отримати перелік (“колекцію”) всіх просторів імен за допомогою GET /api/v1/namespaces
та деталі про конкретний простір імен за допомогою GET /api/v1/namespaces/NAME
.
- Субресурс кластерного рівня:
GET /apis/GROUP/VERSION/RESOURCETYPE/NAME/SUBRESOURCE
- Субресурс рівня простору імен:
GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE/NAME/SUBRESOURCE
Підтримувані дієслова для кожного субресурсу будуть відрізнятися залежно від обʼєкта — див. Довідник API для отримання додаткової інформації. Немає можливості отримати доступ до субресурсів через декілька ресурсів — зазвичай використовується новий віртуальний тип ресурсу, якщо це стає необхідним.
Ефективне виявлення змін
API Kubernetes дозволяє клієнтам зробити початковий запит на обʼєкт або колекцію, а потім відстежувати зміни з моменту цього запиту: це watch. Клієнти можуть відправити list або get і потім зробити наступний запит watch.
Для реалізації цього відстеження змін кожен обʼєкт Kubernetes має поле resourceVersion
, яке представляє версію цього ресурсу, що зберігається в постійному шарі збереження. При отриманні колекції ресурсів (як простору імен, так і кластерного рівня), відповідь від сервера API містить значення resourceVersion
. Клієнт може використовувати це значення resourceVersion
для ініціювання watch проти сервера API.
Коли ви надсилаєте запит watch, сервер API відповідає потоком змін. Ці зміни перераховують результати операцій (таких як create, delete, та update), що відбулись після resourceVersion
, значення якого було вказане як параметр до запиту watch. Загальний механізм watch дозволяє клієнту отримати поточний стан і потім підписатися на подальші зміни, не пропускаючи жодної події.
Якщо клієнт watch відʼєднується, тоді цей клієнт може розпочати новий сеанс watch з останнього повернутого resourceVersion
; клієнт також може виконати новий запити get/list і розпочати знову. Див. Семантика версій ресурсів для отримання детальнішої інформації.
Наприклад:
Отримання списку всіх Podʼів у вказаному просторі імен.
GET /api/v1/namespaces/test/pods
---
200 OK
Content-Type: application/json
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {"resourceVersion":"10245"},
"items": [...]
}
Починаючи з версії ресурсу 10245, отримуйте сповіщення про будь-які операції API (такі як create, delete, patch або update), що впливають на Podʼи у просторі імен test. Кожне сповіщення про зміну — це документ JSON. Тіло відповіді HTTP (надається як application/json
) складається із серії документів JSON.
GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245
---
200 OK
Transfer-Encoding: chunked
Content-Type: application/json
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10596", ...}, ...}
}
{
"type": "MODIFIED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "11020", ...}, ...}
}
...
Сервер Kubernetes буде зберігати історичний запис змін лише протягом обмеженого часу. Кластери, що використовують etcd 3, стандартно зберігають зміни за останні 5 хвилин. Коли запитувані операції watch не вдаються через недоступність історичної версії цього ресурсу, клієнти повинні обробляти цей випадок, розпізнаючи код статусу 410 Gone
, очищаючи свій локальний кеш, виконуючи новий get або list запит, і починаючи watch з resourceVersion
, яке було повернуто.
Для підписки на колекції бібліотеки клієнтів Kubernetes зазвичай пропонують певну форму стандартного інструменту для логіки list-потім-watch. (У бібліотеці клієнтів Go це називається Reflector
і знаходиться в пакеті k8s.io/client-go/tools/cache
).
Закладки для Watch
Щоб зменшити вплив короткого вікна історії, API Kubernetes надає подію спостереження під назвою BOOKMARK
. Це особливий вид події, що позначає, що всі зміни до вказаної клієнтом resourceVersion
вже були надіслані. Документ, що представляє подію BOOKMARK
, має тип який отримується запитом, але включає лише поле .metadata.resourceVersion
. Наприклад:
GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245&allowWatchBookmarks=true
---
200 OK
Transfer-Encoding: chunked
Content-Type: application/json
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10596", ...}, ...}
}
...
{
"type": "BOOKMARK",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "12746"} }
}
Як клієнт, ви можете запитувати події BOOKMARK
, встановлюючи параметр запиту allowWatchBookmarks=true
у запиті watch, але не слід припускати, що закладки будуть повертатися з певним інтервалом, і клієнти не можуть очікувати, що сервер API надішле будь-яку подію BOOKMARK
, навіть якщо її було запитано.
Потокові списки
СТАН ФУНКЦІОНАЛУ: Kubernetes v1.27 [alpha]
У великих кластерах отримання колекції деяких типів ресурсів може призвести до значного збільшення використання ресурсів (переважно RAM) панелі управління. Щоб зменшити цей вплив та спростити користування шаблоном list + watch, Kubernetes v1.27 вводить альфа-функцію підтримки запиту початкового стану (раніше запитуваного через запит list) як частини запиту watch.
За умови, що ввімкнено функціонал WatchList
, це можна зробити, вказавши sendInitialEvents=true
як параметр рядка запиту у запиті watch. Якщо встановлено, сервер API починає потік спостереження з синтетичних початкових подій (типу ADDED
) для побудови всього стану всіх наявних обʼєктів, після чого йде подія BOOKMARK
(якщо запитано через параметр allowWatchBookmarks=true
). Подія закладки включає версію ресурсу, до якої його було синхронізовано. Після надсилання події закладки сервер API продовжує роботу як для будь-якого іншого запиту watch.
Коли ви встановлюєте sendInitialEvents=true
у рядку запиту, Kubernetes також вимагає, щоб ви встановили resourceVersionMatch
до значення NotOlderThan
. Якщо ви вказали resourceVersion
у рядку запиту без значення або не вказали його взагалі, це інтерпретується як запит на узгоджене читання (consistent read); подія закладки надсилається, коли стан синхронізовано щонайменше до моменту узгодженого читання з моменту, коли запит почав оброблятися. Якщо ви вказуєте resourceVersion
(у рядку запиту), подія закладки надсилається, коли стан синхронізовано щонайменше до вказаної версії ресурсу.
Приклад
Приклад: ви хочете спостерігати за колекцією Podʼів. Для цієї колекції поточна версія ресурсу
становить 10245, і є два Podʼи: foo
та bar
. Надсилання наступного запиту (який явно запитує узгоджене читання, встановлюючи порожню версію ресурсу за допомогою resourceVersion=
) може призвести до наступної послідовності подій:
GET /api/v1/namespaces/test/pods?watch=1&sendInitialEvents=true&allowWatchBookmarks=true&resourceVersion=&resourceVersionMatch=NotOlderThan
---
200 OK
Transfer-Encoding: chunked
Content-Type: application/json
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "8467", "name": "foo"}, ...}
}
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "5726", "name": "bar"}, ...}
}
{
"type": "BOOKMARK",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10245"} }
}
...
<далі йде звичайний потік спостереження, починаючи з resourceVersion="10245">
Стиснення відповідей
СТАН ФУНКЦІОНАЛУ: Kubernetes v1.16 [beta]
Опція APIResponseCompression
дозволяє серверу API стискати відповіді на запити get та list, зменшуючи використання мережевої пропускної здатності та покращуючи продуктивність у великих кластерах. Її стандартно увімкнено з Kubernetes 1.16 і її можна вимкнути додаванням APIResponseCompression=false
у прапорець --feature-gates
на сервері API.
Стиснення відповідей API може значно зменшити розмір відповіді, особливо для великих ресурсів або колекцій. Наприклад, запит list для Podʼів може повернути сотні кілобайт або навіть мегабайти даних, залежно від кількості Podʼів та їх атрибутів. Стиснення відповіді дозволяє зберегти мережеву пропускну здатність та зменшити затримки.
Щоб перевірити, чи працює APIResponseCompression
, ви можете надіслати запит get або list на сервер API з заголовком Accept-Encoding
та перевірити розмір відповіді та заголовки. Наприклад:
GET /api/v1/pods
Accept-Encoding: gzip
---
200 OK
Content-Type: application/json
content-encoding: gzip
...
Заголовок content-encoding
вказує, що відповідь стиснута за допомогою gzip
.
Отримання великих наборів результатів частинами
СТАН ФУНКЦІОНАЛУ: Kubernetes v1.29 [stable]
У великих кластерах отримання колекції деяких типів ресурсів може призвести до дуже великих відповідей, що може вплинути на сервер та клієнта. Наприклад, у кластері може бути десятки тисяч Podʼів, кожен з яких еквівалентний приблизно 2 КіБ у форматі JSON. Отримання всіх Podʼів через всі простори імен може призвести до дуже великої відповіді (10-20 МБ) та спожити багато ресурсів сервера.
Сервер API Kubernetes підтримує можливість розбиття одного великого запиту на колекцію на багато менших частин, зберігаючи при цьому узгодженість загального запиту. Кожна частина може бути повернута послідовно, що зменшує загальний розмір запиту і дозволяє клієнтам, орієнтованим на користувачів, показувати результати поетапно для покращення швидкості реагування.
Ви можете запитувати сервер API для обробки list запиту, використовуючи сторінки (які Kubernetes називає chunks). Щоб отримати одну колекцію частинами, підтримуються два параметри запиту limit
та continue
у запитах до колекцій, і поле відповіді continue
повертається з усіх операцій list у полі metadata
колекції. Клієнт повинен вказати максимальну кількість результатів, яку він бажає отримати у кожній частині за допомогою limit
, і сервер поверне кількість ресурсів у результаті не більше limit
та включить значення continue
, якщо у колекції є більше ресурсів.
Як клієнт API, ви можете передати це значення continue
серверу API у наступному запиті, щоб вказати серверу повернути наступну сторінку (chunk) результатів. Продовжуючи до тих пір, поки сервер не поверне порожнє значення continue
, ви можете отримати всю колекцію.
Як і у випадку з операцією watch, токен continue
закінчується через короткий проміжок часу (стандартно 5 хвилин) і повертає 410 Gone
, якщо більше результатів не може бути повернуто. У цьому випадку клієнт повинен буде почати з початку або опустити параметр limit
.
Наприклад, якщо у кластері є 1,253 Podʼів і ви хочете отримувати частини по 500 Podʼів за раз, запитуйте ці частини наступним чином:
Отримати всі Podʼи в кластері, отримуючи до 500 Podʼів за раз.
GET /api/v1/pods?limit=500
---
200 OK
Content-Type: application/json
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion":"10245",
"continue": "ENCODED_CONTINUE_TOKEN",
"remainingItemCount": 753,
...
},
"items": [...] // повертає Podʼи 1-500
}
Продовжити попередній запит, отримуючи наступний набір з 500 Podʼів.
GET /api/v1/pods?limit=500&continue=ENCODED_CONTINUE_TOKEN
---
200 OK
Content-Type: application/json
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion":"10245",
"continue": "ENCODED_CONTINUE_TOKEN_2",
"remainingItemCount": 253,
...
},
"items": [...] // повертає Podʼи 501-1000
}
Продовжити попередній запит, отримуючи останні 253 Podʼів.
GET /api/v1/pods?limit=500&continue=ENCODED_CONTINUE_TOKEN_2
---
200 OK
Content-Type: application/json
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion":"10245",
"continue": "", // токен continue порожній, тому що ми досягли кінця списку
...
},
"items": [...] // повертає Podʼи 1001-1253
}
Зверніть увагу, що resourceVersion
колекції залишається постійним в кожному запиті, що вказує на те, що сервер показує вам узгоджену копію Podʼів. Podʼи, що створюються, оновлюються або видаляються після версії 10245
, не будуть показані, якщо ви не зробите окремий запит list без токена continue
. Це дозволяє вам розбивати великі запити на менші частини, а потім виконувати операцію watch на повному наборі, не пропускаючи жодного оновлення.
Поле remainingItemCount
вказує кількість наступних елементів у колекції, які не включені у цю відповідь. Якщо запит list містив мітки або поля селектори, тоді кількість залишкових елементів невідома, і сервер API не включає поле remainingItemCount
у свою відповідь. Якщо list запит завершено (або тому, що він не розбивається на частини, або тому, що це остання частина), то більше немає залишкових елементів, і сервер API не включає поле remainingItemCount
у свою відповідь. Очікуване використання `remainingItemCount — оцінка розміру колекції.
Колекції
У термінології Kubernetes відповідь, яку ви отримуєте за допомогою list, є колекцією. Однак Kubernetes визначає конкретні види для колекцій різних типів ресурсів. Колекції мають вид, названий на честь виду ресурсу, з доданим List
.
Коли ви надсилаєте запит API для певного типу, всі елементи, повернуті цим запитом, є цього типу. Наприклад, коли ви надсилаєте list Services, відповідь колекції має kind
, встановлений на ServiceList
; кожен елемент у цій колекції представляє один Service. Наприклад:
GET /api/v1/services
{
"kind": "ServiceList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "2947301"
},
"items": [
{
"metadata": {
"name": "kubernetes",
"namespace": "default",
...
"metadata": {
"name": "kube-dns",
"namespace": "kube-system",
...
Є десятки типів колекцій (таких як PodList
, ServiceList
та NodeList
), визначених в API Kubernetes. Ви можете отримати більше інформації про кожен тип колекції з довідника Kubernetes API.
Деякі інструменти, такі як kubectl
, представляють механізм колекцій Kubernetes трохи інакше, ніж сам API Kubernetes. Оскільки вихідні дані kubectl
можуть включати відповідь з декількох операцій list на рівні API, kubectl
представляє список елементів, використовуючи kind: List
. Наприклад:
kubectl get services -A -o yaml
apiVersion: v1
kind: List
metadata:
resourceVersion: ""
selfLink: ""
items:
- apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2021-06-03T14:54:12Z"
labels:
component: apiserver
provider: kubernetes
name: kubernetes
namespace: default
...
- apiVersion: v1
kind: Service
metadata:
annotations:
prometheus.io/port: "9153"
prometheus.io/scrape: "true"
creationTimestamp: "2021-06-03T14:54:14Z"
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: CoreDNS
name: kube-dns
namespace: kube-system
Примітка:
Памʼятайте, що API Kubernetes не має kind
з іменем List
.
kind: List
є клієнтським внутрішнім деталям реалізації для обробки колекцій, які можуть бути різними типами обʼєктів. Уникайте залежності від kind: List
в автоматизації або іншому коді.
Отримання ресурсів у вигляді таблиць
Коли ви запускаєте kubectl get
, стандартний формат виводу є простою табличною репрезентацією одного або кількох екземплярів певного типу ресурсу. У минулому клієнти повинні були відтворювати табличний і описовий вивід, реалізований у kubectl
, щоб виконувати прості списки обʼєктів. Деякі обмеження цього підходу включають нетривіальну логіку при роботі з певними обʼєктами. Крім того, типи, надані API агрегуванням або сторонніми ресурсами, не відомі під час компіляції. Це означає, що повинні бути реалізовані загальні механізми для типів, які не розпізнаються клієнтом.
Щоб уникнути можливих обмежень, описаних вище, клієнти можуть запитувати табличну репрезентацію обʼєктів, делегуючи серверу специфічні деталі виводу. API Kubernetes реалізує стандартні HTTP-узгодження щодо типу контенту: передача заголовка Accept
, що містить значення application/json;as=Table;g=meta.k8s.io;v=v1
з запитом GET
попросить сервер повернути обʼєкти у форматі таблиці.
Наприклад, список усіх Podʼів у кластері у форматі таблиці.
GET /api/v1/pods
Accept: application/json;as=Table;g=meta.k8s.io;v=v1
---
200 OK
Content-Type: application/json
{
"kind": "Table",
"apiVersion": "meta.k8s.io/v1",
...
"columnDefinitions": [
...
]
}
Для типів ресурсів API, які не мають табличного визначення, відомого панелі управління, сервер API повертає стандартну таблицю, яка складається з полів name
та creationTimestamp
ресурсу.
GET /apis/crd.example.com/v1alpha1/namespaces/default/resources
---
200 OK
Content-Type: application/json
...
{
"kind": "Table",
"apiVersion": "meta.k8s.io/v1",
...
"columnDefinitions": [
{
"name": "Name",
"type": "string",
...
},
{
"name": "Created At",
"type": "date",
...
}
]
}
Не всі типи ресурсів API підтримують табличну відповідь; наприклад, CustomResourceDefinitions можуть не визначати відповідність полів таблиці, а APIService, що розширює основний API Kubernetes може взагалі не обслуговувати табличні відповіді. Якщо ви створюєте клієнта, що використовує інформацію з таблиці та який повинен працювати з усіма типами ресурсів, включаючи розширення, ви повинні робити запити, які вказують кілька типів контенту у заголовку Accept
. Наприклад:
Accept: application/json;as=Table;g=meta.k8s.io;v=v1, application/json
Альтернативні представлення ресурсів
Типово Kubernetes повертає обʼєкти, серіалізовані у форматі JSON з типом контенту application/json
. Це станадртний формат серіалізації для API. Однак клієнти можуть запросити більш ефективне представлення у форматі Protobuf цих обʼєктів для покращення продуктивності в масштабі. API Kubernetes реалізує стандартні HTTP-узгодження щодо типу контенту: передача заголовка Accept
з викликом GET
запросить сервер повернути відповідь у вашому бажаному медіа-типі, тоді як надсилання обʼєкта у форматі Protobuf на сервер для виклику PUT
або POST
означає, що ви повинні відповідним чином встановити заголовок Content-Type
.
Сервер поверне відповідь з заголовком Content-Type
, якщо запитаний формат підтримується, або помилку 406 Not acceptable
, якщо жоден з медіа-типів, які ви запросили, не підтримується. Усі вбудовані типи ресурсів підтримують медіа-тип application/json
.
Дивіться довідник API Kubernetes для списку підтримуваних типів контенту для кожного API.
Наприклад:
Список всіх Podʼів у кластері у форматі Protobuf.
GET /api/v1/pods
Accept: application/vnd.kubernetes.protobuf
---
200 OK
Content-Type: application/vnd.kubernetes.protobuf
... binary encoded PodList object
Створення Podʼа, надсиланням даних у форматі Protobuf на сервер, але із запитом відповідіу форматі JSON.
POST /api/v1/namespaces/test/pods
Content-Type: application/vnd.kubernetes.protobuf
Accept: application/json
... binary encoded Pod object
---
200 OK
Content-Type: application/json
{
"kind": "Pod",
"apiVersion": "v1",
...
}
Не всі типи ресурсів API підтримують Protobuf; зокрема, Protobuf недоступний для ресурсів, визначених як CustomResourceDefinitions або обслуговуються через шар агрегації. Як клієнт, який може працювати з розширеними типами, ви повинні вказати кілька типів контенту у заголовку запиту Accept
для підтримки відкату до JSON. Наприклад:
Accept: application/vnd.kubernetes.protobuf, application/json
Кодування Protobuf у Kubernetes
Kubernetes використовує обгортку для кодування відповідей Protobuf. Ця обгортка починається з 4-байтового магічного числа для ідентифікації контенту на диску або в etcd як Protobuf (на відміну від JSON), а потім слідує Protobuf-кодована обгортка повідомлення, яка описує кодування і тип основного обʼєкта, а потім містить сам обʼєкт.
Формат обгортки виглядає так:
Чотирибайтовий префікс магічного числа:
Байти 0-3: "k8s\x00" [0x6b, 0x38, 0x73, 0x00]
Кодоване повідомлення Protobuf з наступним IDL:
message Unknown {
// typeMeta повинен мати рядкові значення для "kind" та "apiVersion", встановлені на обʼєкті JSON
optional TypeMeta typeMeta = 1;
// raw буде містити повністю серіалізований обʼєкт у форматі Protobuf. Дивіться визначення Protobuf у клієнтських бібліотеках для певного kind.
optional bytes raw = 2;
// contentEncoding — це кодування, що використовується для raw даних. Відсутність означає відсутність кодування.
optional string contentEncoding = 3;
// contentType — це метод серіалізації, використаний для серіалізації 'raw'. Відсутність означає application/vnd.kubernetes.protobuf
// і зазвичай опускається.
optional string contentType = 4;
}
message TypeMeta {
// apiVersion — це група/версія для цього типу
optional string apiVersion = 1;
// kind — це назва схеми обʼєкта. Визначення Protobuf повинно існувати для цього обʼєкта.
optional string kind = 2;
}
Примітка:
Клієнти, які отримують відповідь у форматі application/vnd.kubernetes.protobuf
, яка не відповідає очікуваному префіксу, повинні відхилити відповідь, оскільки майбутні версії можуть потребувати зміни формату серіалізації у несумісний спосіб і зроблять це, змінивши префікс.Видалення ресурсів
Коли ви видаляєте ресурс, цей процес проходить у два етапи:
- Завершення (finalization)
- Видалення (removal)
{
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"finalizers": ["url.io/neat-finalization", "other-url.io/my-finalizer"],
"deletionTimestamp": null,
}
}
Коли клієнт вперше надсилає запит на видалення ресурсу, .metadata.deletionTimestamp
встановлюється на поточний час. Після встановлення .metadata.deletionTimestamp
, зовнішні контролери, які працюють з завершувачами (finalizers), можуть почати виконувати свою очистку в будь-який час, у будь-якому порядку.
Порядок не встановлюється примусово між завершувачами, оскільки це може призвести до значного ризику застрягання .metadata.finalizers
.
Поле .metadata.finalizers
є спільним: будь-який áктор з дозволом може змінювати його порядок.
Якби список завершувачів оброблявся по порядку, це могло б призвести до ситуації, коли компонент, відповідальний за перший завершувач у списку, чекає на якийсь сигнал (значення поля, зовнішню систему або інше), що створюється компонентом, відповідальним за завершувач пізніше у списку, що призводить до застярягання всього списку.
Без примусового впорядкування завершувачі можуть вільно визначати свій власний порядок і не є вразливими до змін у списку.
Після видалення останнього завершувача ресурс фактично видаляється з etcd.
API для одного ресурсу
API Kubernetes з дієсловами get, create, update, patch, delete та proxy підтримують тільки одиничні ресурси. Ці дієслова з підтримкою одиничного ресурсу не підтримують надсилання кількох ресурсів разом в упорядкованому або неупорядкованому списку чи транзакції.
Коли клієнти (включаючи kubectl) виконують дії з набором ресурсів, клієнт робить серію одиничних API запитів до ресурсу, а потім, за потреби, агрегує відповіді.
На відміну від цього, API Kubernetes з дієсловами list і watch дозволяють отримувати кілька ресурсів, а deletecollection дозволяє видаляти кілька ресурсів.
Валідація полів
Kubernetes завжди перевіряє тип полів. Наприклад, якщо поле в API визначене як число, ви не можете встановити це поле в текстове значення. Якщо поле визначене як масив рядків, ви можете надати тільки масив. Деякі поля можна пропустити, інші поля є обовʼязковими. Пропуск обовʼязкового поля у запиті API є помилкою.
Якщо ви зробите запит з додатковим полем, яке не розпізнається панеллю управління кластера, тоді поведінка сервера API є складнішою.
Типово, сервер API видаляє поля, які він не розпізнає, з вхідних даних, які він отримує (наприклад, тіло JSON запиту PUT
).
Є дві ситуації, коли сервер API видаляє поля, які ви надали у HTTP-запиті.
Ці ситуації такі:
- Поле не розпізнається, оскільки воно не входить до схеми OpenAPI ресурсу. (Одним винятком є CRDs, які явно обирають не обрізати невідомі поля через
x-kubernetes-preserve-unknown-fields
). - Поле дублюється в обʼєкті.
Валідація для нерозпізнаних або дубльованих полів
СТАН ФУНКЦІОНАЛУ: Kubernetes v1.27 [stable]
З версії 1.25 і далі, нерозпізнані або дубльовані поля в обʼєкті виявляються через валідацію на сервері при використанні HTTP-дієслів, які можуть надсилати дані (POST
, PUT
та PATCH
). Можливі рівні валідації: Ignore
, Warn
(стандартно) та Strict
.
Ignore
- Сервер API успішно обробляє запит так, ніби у ньому немає неправильних полів, відкидаючи всі невідомі та дубльовані поля та не повідомляючи про це.
Warn
- (Стандартно) Сервер API успішно обробляє запит і надсилає клієнту попередження. Попередження надсилається за допомогою заголовка відповіді
Warning:
, додаючи один елемент попередження для кожного невідомого або дубльованого поля. Для отримання додаткової інформації про попередження та API Kubernetes дивіться статтю блогу Warning: Helpful Warnings Ahead. Strict
- Сервер API відхиляє запит з помилкою 400 Bad Request, коли виявляє будь-які невідомі або дубльовані поля. Повідомлення відповіді від сервера API вказує всі невідомі або дубльовані поля, які сервер API виявив.
Рівень валідації полів встановлюється параметром запиту fieldValidation
.
Примітка:
Якщо ви надсилаєте запит, що вказує на нерозпізнане поле, яке також є недійсним з іншої причини (наприклад, запит надає рядкове значення, де API очікує цілого числа для відомого поля), тоді сервер API відповідає з помилкою 400 Bad Request, але не надасть жодної інформації про невідомі або дубльовані поля (тільки про ту фатальну помилку, яку він виявив першою).
У цьому випадку ви завжди отримаєте відповідь про помилку, незалежно від того, який рівень валідації полів ви запросили.
Інструменти, які надсилають запити на сервер (такі як kubectl
), можуть встановлювати свої власні типові значення, які відрізняються від рівня валідації Warn
, що стандартно використовується сервером API.
Інструмент kubectl
використовує прапорець --validate
для встановлення рівня валідації полів. Він приймає значення ignore
, warn
та strict
, а також приймає значення true
(еквівалентно strict
) і false
(еквівалентно ignore
). Станадртне налаштування валідації для kubectl — це --validate=true
, що означає сувору валідацію полів на стороні сервера.
Коли kubectl не може підключитися до сервера API з валідацією полів (сервери API до Kubernetes 1.27), він повернеться до використання валідації на стороні клієнта. Валідація на стороні клієнта буде повністю видалена у майбутній версії kubectl.
Примітка:
До Kubernetes 1.25 прапорець kubectl --validate
використовувався для перемикання валідації на стороні клієнта увімквимкання/вимиканнямнено булевого прапореця.Dry-run
СТАН ФУНКЦІОНАЛУ: Kubernetes v1.19 [stable]
При використанні HTTP-дієслів, які можуть змінювати ресурси (POST
, PUT
, PATCH
і DELETE
), ви можете надіслати свій запит у режимі dry run. Режим dry run допомагає оцінити запит через типові етапи обробки запиту (ланцюг допумків, валідацію, конфлікти злиття) аж до збереження обʼєктів у сховищі. Тіло відповіді на запит є максимально наближеним до відповіді у режимі non-dry-run. Kubernetes гарантує, що dry-run запити не будуть збережені в сховищі і не матимуть жодних інших побічних ефектів.
Виконання dry-run запиту
Dry-run активується встановленням параметра запиту dryRun
. Цей параметр є рядковим, діє як перерахування, і єдині прийнятні значення:
- [без значення]
- Дозволити побічні ефекти. Ви запитуєте це за допомогою рядка запиту типу
?dryRun
або ?dryRun&pretty=true
. Відповідь є остаточним обʼєктом, який був би збережений, або помилкою, якщо запит не може бути виконаний. All
- Кожен етап виконується як зазвичай, за винятком кінцевого етапу збереження, де побічні ефекти запобігаються.
Коли ви встановлюєте ?dryRun=All
, усі відповідні контролерів допуску виконуються, перевіряючи запит після зміни, злиття виконується для PATCH
, поля заповнюються станадартними значеннями, і проводиться валідація схеми. Зміни не зберігаються в базовому сховищі, але остаточний обʼєкт, який був би збережений, все ще повертається користувачеві разом із звичайним кодом статусу.
Якщо версія запиту без dry-run викликала б контролер доступу, який має побічні ефекти, запит буде відхилений, щоб уникнути небажаних побічних ефектів. Усі вбудовані втулки контролю доступу підтримують dry-run. Додатково, admission webhooks можуть оголосити у своїй конфігураційній моделі, що вони не мають побічних ефектів, встановивши поле sideEffects
на None
.
Примітка:
Якщо вебхук дійсно має побічні ефекти, то поле sideEffects
має бути встановлено на "NoneOnDryRun". Ця зміна є доречною за умови, що вебхук також модифіковано щоб він розумів поле DryRun
у AdmissionReview і для запобігання побічним ефектам на будь-який запит, позначений як dry run.Приклад dry-run запиту, який використовує ?dryRun=All
:
POST /api/v1/namespaces/test/pods?dryRun=All
Content-Type: application/json
Accept: application/json
Відповідь буде виглядати так само, як для запиту без dry-run, але значення деяких згенерованих полів можуть відрізнятися.
Згенеровані значення
Деякі значення обʼєкта зазвичай генеруються перед його збереженням. Важливо не покладатися на значення цих полів, встановлених dry-run запитом, оскільки ці значення, ймовірно, будуть відрізнятися в dry-run режимі від реального запиту. Деякі з цих полів:
name
: якщо встановлено generateName
, name
матиме унікальне випадкове імʼяcreationTimestamp
/ deletionTimestamp
: фіксує час створення/видаленняUID
: унікально ідентифікує обʼєкт і генерується випадково (недетерміновано)resourceVersion
: відстежує збережену версію обʼєкта- Будь-яке поле, встановлене мутаційним контролером допуску
- Для ресурсу
Service
: Порти або IP-адреси, які kube-apiserver надає обʼєктам Service
Авторизація dry-run
Авторизація для dry-run і non-dry-run запитів ідентична. Таким чином, щоб виконати dry-run запит, ви повинні мати дозвіл на виконання non-dry-run запиту.
Наприклад, щоб виконати dry-run patch для Deployment, ви повинні мати дозвіл на виконання цього patch. Ось приклад правила для Kubernetes RBAC, що дозволяє робити patch для Deployment:
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["patch"]
Дивіться Огляд авторизації.
Оновлення наявних ресурсів
Kubernetes надає декілька способів оновлення наявних обʼєктів. Ви можете прочитати вибір механізму оновлення, щоб дізнатися, який підхід найкраще підходить для вашого випадку.
Ви можете перезаписати (оновити) наявний ресурс, наприклад, ConfigMap, використовуючи HTTP PUT. Для запиту PUT відповідальність за вказання resourceVersion
(отриманого з обʼєкта, що оновлюється) лежить на клієнті. Kubernetes використовує інформацію resourceVersion
, щоб сервер API міг виявити втрачені оновлення і відхилити запити від клієнта, який не актуальний для кластера. У разі зміни ресурсу (коли resourceVersion
, надана клієнтом, застаріла), сервер API повертає відповідь з помилкою 409 Conflict
.
Замість надсилання запиту PUT клієнт може надіслати інструкцію серверу API для накладання патчу до наявного ресурсу. Патч зазвичай підходить, якщо зміна, яку клієнт хоче внести, не залежить від наявних даних. Клієнти, яким потрібне ефективне виявлення втрачених оновлень, повинні розглянути можливість зробити свій запит умовним до існуючого resourceVersion
(або HTTP PUT, або HTTP PATCH), а потім обробити будь-які повтори, які можуть знадобитися у разі конфлікту.
API Kubernetes підтримує чотири різні операції PATCH, які визначаються відповідним заголовком HTTP Content-Type
:
application/apply-patch+yaml
- Серверне застосування YAML (специфічне розширення Kubernetes, засноване на YAML). Всі документи JSON є дійсними в YAML, тому ви також можете надавати JSON, використовуючи цей тип медіа. Дивіться серіалізація для серверного застосування для отримання додаткової інформації. Для Kubernetes це операція створення, якщо обʼєкт не існує, або операція накладання патчу, якщо обʼєкт вже існує.
application/json-patch+json
- JSON Patch, як визначено в RFC6902. JSON патч — це послідовність операцій, які виконуються з ресурсом; наприклад,
{"op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ]}
. Для Kubernetes це операція накладання патчу. Патч з використанням application/json-patch+json
може включати умови для перевірки консистентності, дозволяючи операції зазнати невдачі, якщо ці умови не виконуються (наприклад, щоб уникнути втрати оновлення). application/merge-patch+json
- JSON Merge Patch, як визначено в RFC7386. JSON Merge Patch фактично є частковим представленням ресурсу. Поданий JSON комбінується з поточним ресурсом для створення нового, а потім новий зберігається. Для Kubernetes це операція накладання патчу.
application/strategic-merge-patch+json
- Strategic Merge Patch (специфічне розширення Kubernetes на основі JSON). Strategic Merge Patch — це власна реалізація JSON Merge Patch. Ви можете використовувати Strategic Merge Patch лише з вбудованими API або з агрегованими серверами API, які мають спеціальну підтримку для цього. Ви не можете використовувати
application/strategic-merge-patch+json
з будь-яким API, визначеним за допомогою CustomResourceDefinition.
Примітка:
Механізм серверного застосування Kubernetes замінив Strategic Merge Patch.
Функція Серверного застосування Kubernetes дозволяє панелі управління відстежувати керовані поля для новостворених обʼєктів. SСерверне застосування забезпечує чітку схему для управління конфліктами полів, пропонує серверні операції apply і update, та замінює функціональність на стороні клієнта kubectl apply
.
Для серверного застосування Kubernetes обробляє запит як створення, якщо обʼєкт ще не існує, і як патч в іншому випадку. Для інших запитів, які використовують PATCH на рівні HTTP, логічна операція Kubernetes завжди є патч.
Дивіться Серверне застосування для отримання додаткової інформації.
Вибір механізму оновлення
HTTP PUT для заміни наявного ресурсу
Операція оновлення (HTTP PUT
) проста у виконанні та гнучка, але має недоліки:
- Потрібно вирішувати конфлікти, де
resourceVersion
обʼєкта змінюється між моментом його читання клієнтом і спробою записувати назад. Kubernetes завжди виявляє конфлікт, але вам як авторові клієнта потрібно реалізувати повторні спроби. - Ви можете випадково видаляти поля, якщо декодуєте обʼєкт локально (наприклад, використовуючи client-go, ви можете отримати поля, які ваш клієнт не вміє обробляти, і потім видаляти їх під час оновлення).
- Якщо на обʼєкт накладається багато конкурентних операцій (навіть на поле або набір полів, які ви не намагаєтеся редагувати), ви можете мати проблеми з надсиланням оновлення. Проблема гостріша для великих обʼєктів та для обʼєктів з багатьма полями.
HTTP PATCH з використанням JSON Patch
Оновлення патчем корисне через такі причини:
- Оскільки ви надсилаєте лише різницю, ви маєте менше даних для надсилання у запиті
PATCH
. - Ви можете робити зміни, які ґрунтуються на наявних значеннях, наприклад, копіювати значення певного поля в анотацію.
- На відміну від оновлення (HTTP
PUT
), ваші зміни можуть відбуватися відразу навіть при частих змінах не повʼязаних полів: зазвичай вам не потрібно повторювати спроби.- Вам все ще може знадобитися вказати
resourceVersion
(щоб відповідати існуючому обʼєкту), якщо ви хочете бути особливо обережними, щоб уникнути втрати оновлень. - Все ж це хороша практика написати деяку логіку повторної спроби у випадку помилок.
- Ви можете використовувати тестові умови для обережного створення конкретних умов оновлення. Наприклад, ви можете збільшити лічильник без його читання, якщо існуюче значення відповідає вашим очікуванням. Ви можете це зробити без ризику втрати оновлення, навіть якщо обʼєкт змінився іншим чином з моменту вашого останнього запису до нього. (Якщо тестова умова не виконається, ви можете використовувати поточне значення і потім записати змінене число).
Проте:
- Вам потрібна більша локальна (клієнтська) логіка для створення патчу; дуже корисно мати реалізацію бібліотеки JSON Patch або навіть створення JSON Patch специально для Kubernetes.
- Як автору клієнтського програмного забезпечення, вам потрібно бути обережним при створенні патчу (тіла запиту HTTP), щоб не видаляти поля (порядок операцій має значення).
HTTP PATCH з використанням Server-Side Apply
Серверне застосування має чіткі переваги:
- Одноразовий прохід веред-назад: зазвичай спочатку не потребує виконання
GET
запиту.- і ви все ще можете виявляти конфлікти для неочікуваних змін
- у вас є можливість примусово перезаписати конфлікт, якщо це доцільно
- Реалізація клієнта легка для створення
- Ви отримуєте атомарну операцію створення або оновлення без додаткових зусиль (аналогічно
UPSERT
у деяких діалектах SQL).
Проте:
- Серверне застосування зовсім не працює для змін полів, які залежать від поточного значення обʼєкта.
- Ви можете застосовувати оновлення лише до обʼєктів. Деякі ресурси в HTTP API Kubernetes не є обʼєктами (вони не мають поля
.metadata
), а серверне застосування стосується лише обʼєктів Kubernetes.
Версії ресурсів
Версії ресурсів — це рядки, які ідентифікують внутрішню версію обʼєкта на сервері. Версії ресурсів можуть використовуватися клієнтами для визначення змін в обʼєктах або для зазначення вимог до консистентності даних при отриманні, переліку та перегляді ресурсів. Версії ресурсів повинні розглядатися клієнтами як непрозорі та передаватися без змін назад на сервер.
Не слід припускати, що версії ресурсів є числовими або можуть бути впорядковані. API-клієнти можуть порівнювати лише дві версії ресурсів на рівність (це означає, що ви не можете порівнювати версії ресурсів за відносними значеннями "більше" або "менше").
Клієнти знаходять версії ресурсів в ресурсах, включаючи ресурси з потоку відповіді під час спостереження (watch) або при отримані переліку (list) ресурсів.
v1.meta/ObjectMeta — metadata.resourceVersion
екземпляра ресурсу ідентифікує версію ресурсу, на якій останній раз він був змінений.
v1.meta/ListMeta — metadata.resourceVersion
колекції ресурсів (відповідь на перелік (list)) ідентифікує версію ресурсу, на якій була створена колекція.
Параметри resourceVersion
у рядках запитів
Операції отримання (get), переліку (list) та спостереження (watch) підтримують параметр resourceVersion
. Починаючи з версії v1.19, сервери API Kubernetes також підтримують параметр resourceVersionMatch
у запитах list.
Сервер API інтерпретує параметр resourceVersion
по-різному, залежно від операції, яку ви запитуєте, та від значення resourceVersion
. Якщо ви встановлюєте resourceVersionMatch
, то це також впливає на спосіб порівняння.
Семантика для операцій get та list
Для операцій get та list, семантика параметра resourceVersion
така:
get:
resourceVersion невстановлено | resourceVersion="0" | resourceVersion="{значення, відмінне від 0}" |
---|
Найновіший | Будь-яке | Не старше |
list:
Починаючи з версії v1.19, сервери API Kubernetes підтримують параметр resourceVersionMatch
у запитах list. Якщо ви встановлюєте як resourceVersion
, так і resourceVersionMatch
, то параметр resourceVersionMatch
визначає, як сервер API інтерпретує resourceVersion
.
Вам завжди слід встановлювати параметр resourceVersionMatch
, коли ви встановлюєте resourceVersion
у запиті list. Однак будьте готові обробляти випадок, де сервер API, що відповідає, не підтримує resourceVersionMatch
та ігнорує його.
Крім випадків сильних вимог до консистентності, використання resourceVersionMatch=NotOlderThan
та відомої resourceVersion
є бажаним, оскільки це може забезпечити кращу продуктивність та масштабованість вашого кластеру, ніж залишати resourceVersion
і resourceVersionMatch
невстановленими, що вимагає отримання кворуму для обслуговування.
Встановлення параметра resourceVersionMatch
без встановлення resourceVersion
є недійсним.
Ця таблиця пояснює поведінку запитів list з різними комбінаціями resourceVersion
та resourceVersionMatch
:
Параметри resourceVersionMatch та розбиття на сторінки для listПараметр resourceVersionMatch | Параметри розбиття на сторінки | resourceVersion не встановлено | resourceVersion="0" | resourceVersion="{значення, відмінне від 0}" |
---|
не встановлено | limit не встановлено | Найновіший | Any | Не старше |
не встановлено | limit=<n>, continue не встановлено | Найновіший | Any | Точно |
не встановлено | limit=<n>, continue=<токен> | Continue Token, Exact | Недійсний, розглядається як Continue Token, Exact | Недійсний, HTTP 400 Bad Request |
resourceVersionMatch=Exact | limit не встановлено | Недійсний | Недійсний | Exact |
resourceVersionMatch=Exact | limit=<n>, continue не встановлено | Недійсний | Недійсний | Exact |
resourceVersionMatch=NotOlderThan | limit не встановлено | Недійсний | Any | NotOlderThan |
resourceVersionMatch=NotOlderThan | limit=<n>, continue не встановлено | Недійсний | Any | NotOlderThan |
Примітка:
Якщо сервер API вашого кластера не враховує параметр resourceVersionMatch
, поведінка буде такою самою, як і якщо ви його не встановили.Сенс семантики операцій get та list такий:
- Any
- Повернути дані на будь-якій версії ресурсу. Вибирається найновіша доступна версія ресурсу, але не потрібна сильна консистентність; дані на будь-якій версії ресурсу можуть бути обслуговані. Є можливість отримати дані на значно старішій версії ресурсу, яку клієнт раніше спостерігав, особливо в конфігураціях високої доступності через розділи або застарілі кеші. Клієнти, які не можуть терпіти це, не повинні використовувати цю семантику.
- Найновіший
- Повернути дані на найновішій версії ресурсу. Повернені дані повинні бути консистентними (детально: обслуговуються з etcd за допомогою кворумного читання).
- NotOlderThan
- Повернути дані, які є принаймні так новими, як наданий
resourceVersion
. Вибирається найновіша доступна інформація, але будь-яка інформація, яка не старше наданої resourceVersion
, може бути обслугована. Для запитів list до серверів, які підтримують параметр resourceVersionMatch
, це гарантує, що .metadata.resourceVersion
колекції не старше вказаної resourceVersion
, але не надає гарантії щодо .metadata.resourceVersion
будь-яких елементів у цій колекції. - Exact
- Повернути дані на точній версії ресурсу, яка надана. Якщо надана
resourceVersion
недоступна, сервер відповідає HTTP 410 "Відсутній". Для запитів list до серверів, які підтримують параметр resourceVersionMatch
, це гарантує, що .metadata.resourceVersion
колекції співпадає з resourceVersion
, яку ви запросили у рядку запиту. Ця гарантія не поширюється на .metadata.resourceVersion
будь-яких елементів у цій колекції. - Continue Token, Exact
- Повернути дані на версії ресурсу початкового виклику list розділеного на сторінки. Повернені продовження токенів відповідальні за відстеження початково наданої версії ресурсу для всіх викликів list розділених на сторінки після початкового виклику list.
Примітка:
Коли ви перелічцєте (
list) ресурси та отримуєте відповідь у вигляді колекції, відповідь містить
метадані списку колекції, а також
метадані обʼєктів для кожного елемента у цій колекції. Для окремих обʼєктів, знайдених у відповіді колекції,
.metadata.resourceVersion
відстежує, коли цей обʼєкт був останній раз оновлений, а не те, наскільки актуальний обʼєкт, коли він обслуговується.
При використанні resourceVersionMatch=Не старше
та встановленому ліміті клієнти мають обробляти відповіді HTTP 410 "Gone". Наприклад, клієнт може повторно спробувати з новішою resourceVersion
або використовувати resourceVersion=""
.
При використанні resourceVersionMatch=Точно
та не встановленому ліміті, клієнти мають перевірити, що .metadata.resourceVersion
колекції співпадає з запитаною resourceVersion
, і обробити випадок, коли це не так. Наприклад, клієнт може використовувати запит з встановленим лімітом.
Семантика для операції watch
Для операцій watch, семантика параметра resourceVersion
така:
watch:
resourceVersion для watchresourceVersion невстановлено | resourceVersion="0" | resourceVersion="{значення, відмінне від 0}" |
---|
Отримати стан і почати з найновішого | Отримати стан і почати з будь-якого | Почати точно з |
Сенс цієї семантики для watch такий:
- Отримати стан і почати з будь-якого
Увага:
Watch, ініційовані таким чином, можуть повернути довільно застарілі дані. Будь ласка, перегляньте цю семантику перед її використанням і за можливості віддавайте перевагу іншим семантикам.Почати watch на будь-якій версії ресурсу; найбільш нова доступна версія є переважною, але не обовʼязковою. Дозволено будь-яку початкову версію ресурсу. Можливо, що watch почнеться на набагато старішій версії ресурсу, яку клієнт раніше спостерігав, особливо в конфігураціях високої доступності через розділи або застарілі кеші. Клієнти, які не можуть терпіти таке відмотування назад, не повинні починати watch з цією семантикою. Для встановлення початкового стану, watch починається з синтетичних подій "Added" для всіх екземплярів ресурсів, які існують на початковій версії ресурсу. Усі наступні події watch стосуються всіх змін, що сталися після початкової версії ресурсу, з якої почався watch.- Отримати стан і почати з найновішого
- Почати watch на найбільш новій версії ресурсу, яка повинна бути консистентною (детально: обслуговується з etcd за допомогою отримання кворуму). Для встановлення початкового стану watch починається з синтетичних подій "Added" для всіх екземплярів ресурсів, які існують на початковій версії ресурсу. Усі наступні події watch стосуються всіх змін, що сталися після початкової версії ресурсу, з якої почався watch.
- Почати точно з
- Почати watch на точній версії ресурсу. Події watch стосуються всіх змін після наданої версії ресурсу. На відміну від "Отримати стан і почати з найновішого" та "Отримати стан і почати з будь-якого", watch не починається з синтетичних подій "Added" для наданої версії ресурсу. Вважається, що клієнт вже має початковий стан на стартовій версії ресурсу, оскільки клієнт надав цю версію ресурсу.
Відповіді "410 Gone"
Сервери не зобовʼязані зберігати всі старі версії ресурсів і можуть повернути код HTTP 410 (Gone)
, якщо клієнт запитує resourceVersion
, який старіший, ніж версія, збережена сервером. Клієнти повинні бути готові обробляти відповіді 410 (Gone)
. Дивіться розділ Ефективне виявлення змін для отримання додаткової інформації про те, як обробляти відповіді 410 (Gone)
при спостереженні за ресурсами.
Якщо ви запитуєте resourceVersion
, який знаходиться за межами допустимого діапазону, то, залежно від того, чи обслуговується запит з кешу чи ні, API-сервер може відповісти HTTP-відповіддю 410 Gone
.
Недоступні версії ресурсів
Сервери не зобовʼязані обслуговувати нерозпізнані версії ресурсів. Якщо ви запитуєте list або get для версії ресурсу, яку API-сервер не розпізнає, то API-сервер може або:
- почекати трохи, поки версія ресурсу не стане доступною, а потім завершити з тайм-аутом і відповіддю
504 (Gateway Timeout)
, якщо надана версія ресурсу не стане доступною в розумний термін; - відповісти заголовком
Retry-After
, вказуючи, через скільки секунд клієнт повинен повторити запит.
Якщо ви запитуєте версію ресурсу, яку API-сервер не розпізнає, kube-apiserver додатково ідентифікує свої відповіді на помилки повідомленням "Too large resource version".
Якщо ви робите запит watch для нерозпізнаної версії ресурсу, API-сервер може чекати невизначений час (до тайм-ауту запиту), поки версія ресурсу не стане доступною.
2 - Server-Side Apply
СТАН ФУНКЦІОНАЛУ: Kubernetes v1.22 [stable]
Kubernetes підтримує співпрацю кількох аплікаторів для керування полями одного обʼєкта.
Server-Side Apply (Серверне застосування) надає необовʼязковий механізм для контролера вашого кластера, щоб відстежувати зміни в полях обʼєкта. На рівні конкретного ресурсу, Server-Side Apply записує та відстежує інформацію про контроль над полями цього обʼєкта.
Server-Side Apply допомагає користувачам та контролерам керувати своїми ресурсами за допомогою декларативної конфігурації. Клієнти можуть створювати та змінювати обʼєкти декларативно, подаючи їх повністю визначений намір.
Повністю визначений намір — це частковий обʼєкт, який містить лише ті поля та значення, щодо яких у користувача є чітке уявлення. Цей намір або створює новий обʼєкт (використовуючи стандартні значення для невизначених полів), або обʼєднується з наявним обʼєктом через API сервер.
Порівняння з Client-Side Apply пояснює, як Server-Side Apply відрізняється від початкової реалізації kubectl apply
на стороні клієнта.
Управління полями
Kubernetes API сервер відстежує керовані поля для всіх новостворених обʼєктів.
При спробі застосувати обʼєкт, поля, які мають інше значення і належать іншому менеджеру, спричинять конфлікт. Це зроблено для того, щоб сигналізувати, що операція може скасувати зміни іншого спільника. Записи до обʼєктів з керованими полями можуть бути примусовими, в такому випадку значення будь-якого конфліктного поля буде перезаписане, а право власності передане.
Кожного разу, коли значення поля змінюється, право власності переходить від поточного менеджера до менеджера, що здійснює зміну.
Операція застосування перевіряє, чи є інші менеджери полів, які також володіють полем. Якщо поле не належить жодному іншому менеджеру полів, це поле встановлюється на стандартне значення (якщо таке є), або видаляється з обʼєкта. Те саме правило застосовується до полів, які є списками, асоціативними списками або map.
Для того, щоб користувач міг керувати полем в контексті Server-Side Apply, він повинен покладатися на те, що значення поля не зміниться. Користувач, який останнім висловив свою думку щодо значення поля, буде записаний як поточний менеджер поля. Це можна зробити, змінивши дані менеджера поля явним чином за допомогою HTTP POST
(створення), PUT
(оновлення), або не-застосувального PATCH
(патч). Ви також можете оголосити та записати менеджера поля, включивши значення для цього поля в операції Server-Side Apply.
Запит на патч в контексті Server-Side Apply вимагає від клієнта вказати свою ідентичність як менеджера поля. При використанні Server-Side Apply спроба змінити поле, що контролюється іншим менеджером, призведе до відхилення запиту, якщо клієнт не виконає примусове перевизначення. Для деталей щодо примусових перевизначень дивіться Конфлікти.
Коли два або більше аплікатора встановлюють поле на однакове значення, вони спільно володіють цим полем. Будь-яка спроба змінити значення спільного поля будь-ким з аплікаторів призведе до конфлікту. Спільні власники поля можуть відмовитися від права власності на поле, здійснивши запит на патч в контексті Server-Side Apply, який не включає це поле.
Деталі управління полями зберігаються в полі managedFields
, яке є частиною metadata
обʼєкта.
Якщо ви видалите поле з маніфесту і застосуєте цей маніфест, Server-Side Apply перевірить, чи є інші менеджери полів, які також володіють цим полем. Якщо поле не належить жодному іншому менеджеру полів, воно буде або видалене з поточного обʼєкта, або скинуте до стандартного значення, якщо таке є. Те саме правило застосовується до елементів асоціативного списку або map.
У порівнянні з (застарілою) kubectl.kubernetes.io/last-applied-configuration
анотацією, яка управляється kubectl
, Server-Side Apply використовує більш декларативний підхід, який відстежує управління полями користувача (або клієнта), а не останній застосований стан користувача. Побічним ефектом використання Server-Side Apply є також доступність інформації про те, який менеджер поля управляє кожним полем в обʼєкті.
Приклад
Простий приклад обʼєкта, створеного за допомогою Server-Side Apply, може виглядати так:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-cm
namespace: default
labels:
test-label: test
managedFields:
- manager: kubectl
operation: Apply # зверніть увагу на великі літери: "Apply" (або "Update")
apiVersion: v1
time: "2010-10-10T0:00:00Z"
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:labels:
f:test-label: {}
f:data:
f:key: {}
data:
key: some value
Цей приклад обʼєкта ConfigMap містить один запис про управління полями в .metadata.managedFields
. Запис управління полями складається з основної інформації про саму сутність, що виконує управління, а також з деталей про поля, якими управляють, та відповідну операцію (Apply
або Update
). Якщо запит, що останнім змінив це поле, був патчем Server-Side Apply, тоді значення operation
буде Apply
; в іншому випадку, це буде Update
.
Є ще один можливий результат. Клієнт може подати недійсний запит. Якщо повністю зазначений намір не створює дійсний обʼєкт, запит не вдасться виконати.
Однак, можливо змінити .metadata.managedFields
за допомогою операції оновлення або патчу, які не використовують Server-Side Apply. Це наполегливо не рекомендується, але може бути доцільно спробувати, якщо, наприклад, .metadata.managedFields
потрапить у неконсистентний стан (що не повинно відбуватися при нормальній роботі).
Формат managedFields
описаний у довіднику API Kubernetes.
Увага:
Поле .metadata.managedFields
керується API сервером. Ви повинні уникати його ручного оновлення.Конфлікти
Конфлікт — це спеціальна помилка статусу, яка виникає, коли операція Apply
намагається змінити поле, на яке інший менеджер також заявляє права на керування. Це запобігає ненавмисному перезапису значення, встановленого іншим користувачем. У разі конфлікту аплікатор має 3 варіанти для вирішення конфліктів:
Перезаписати значення, стати єдиним менеджером: Якщо перезапис значення був навмисним (або якщо аплікатор є автоматичним процесом, таким як контролер), аплікатор повинен встановити параметр запиту force
в true
(для kubectl apply
використовується параметр командного рядка --force-conflicts
) і повторити запит. Це змусить операцію завершитись успішно, змінить значення поля та видалить це поле з усіх інших записів менеджерів у managedFields
.
Не перезаписувати значення, відмовитися від права управління: Якщо аплікатор більше не піклується про значення поля, він може видалити його зі своєї локальної моделі ресурсу і зробити новий запит, виключивши це конкретне поле. Це залишить значення незмінним і видалить поле із запису аплікатора у managedFields
.
Не перезаписувати значення, стати спільним менеджером: Якщо аплікатор все ще піклується про значення поля, але не хоче його перезаписувати, він може змінити значення цього поля у своїй локальній моделі ресурсу, щоб відповідати значенню обʼєкта на сервері, а потім зробити новий запит, враховуючи це локальне оновлення. Це залишить значення незмінним і зробить це поле керованим спільно аплікатором та всіма іншими менеджерами, які вже заявили про керування ним.
Менеджери полів
Менеджери визначають окремі робочі процеси, які змінюють обʼєкт (особливо корисно при конфліктах!), і можуть бути вказані через параметр запиту fieldManager
як частина запиту на зміни. Коли ви застосовуєте зміни до ресурсу, параметр fieldManager
є обовʼязковим. Для інших оновлень сервер API визначає ідентифікатор менеджера поля з заголовка HTTP "User-Agent:" (якщо він присутній).
Коли ви використовуєте інструмент kubectl
для виконання операції Server-Side Apply, kubectl
типово встановлює ідентифікатор менеджера в "kubectl"
.
Серіалізація
На рівні протоколу Kubernetes представляє тіла повідомлень Server-Side Apply у форматі YAML, з медіа типом application/apply-patch+yaml
.
Примітка:
Незалежно від того, чи ви подаєте дані у форматі JSON чи YAML, використовуйте application/apply-patch+yaml
як значення заголовка Content-Type
.
Усі документи JSON є дійсними документами YAML. Однак, у Kubernetes є помилка, яка полягає в тому, що він використовує парсер YAML, який не повністю реалізує специфікацію YAML. Деякі JSON екранування можуть не бути розпізнаними.
Серіалізація є такою ж, як для обʼєктів Kubernetes, за винятком того, що клієнти не зобовʼязані надсилати повний обʼєкт.
Ось приклад тіла повідомлення Server-Side Apply (повністю специфікований намір):
{
"apiVersion": "v1",
"kind": "ConfigMap"
}
(це зробить оновлення без змін, за умови, що це було надіслано як тіло patch запиту до дійсного ресурсу v1/configmaps
, з відповідним заголовком запиту Content-Type
).
Операції з області управління полями
Операції API Kubernetes, де враховується управління полями, включають:
- Server-Side Apply (HTTP
PATCH
, з типом контенту application/apply-patch+yaml
) - Заміна наявного обʼєкта (update для Kubernetes;
PUT
на рівні HTTP)
Обидві операції оновлюють .metadata.managedFields
, але поводяться трохи по-різному.
Якщо не вказано примусове перезаписування, операція apply, що зустрічає конфлікти на рівні полів, завжди зазнає невдачі; у противагу, якщо зміну здійснено за допомогою update, що впливає на кероване поле, конфлікт ніколи не призводить до невдачі операції.
Усі запити Server-Side Apply patch повинні ідентифікувати себе, надаючи параметр запиту fieldManager
, тоді як цей параметр запиту є необовʼязковим для операцій update. Нарешті, при використанні операції Apply
ви не можете визначати managedFields
у тілі запиту, який ви надсилаєте.
Приклад обʼєкта з декількома менеджерами може виглядати так:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-cm
namespace: default
labels:
test-label: test
managedFields:
- manager: kubectl
operation: Apply
apiVersion: v1
fields:
f:metadata:
f:labels:
f:test-label: {}
- manager: kube-controller-manager
operation: Update
apiVersion: v1
time: '2019-03-30T16:00:00.000Z'
fields:
f:data:
f:key: {}
data:
key: new value
У цьому прикладі друга операція була виконана як update менеджером з назвою kube-controller-manager
. Запит на оновлення був успішним і змінив значення в полі даних, що призвело до зміни управління цим полем на kube-controller-manager
.
Якби була спроба застосувати це оновлення за допомогою Server-Side Apply, запит зазнав би невдачі через конфлікт управління.
Стратегія злиття
Стратегія злиття, реалізована в Server-Side Apply, забезпечує більш стабільний життєвий цикл обʼєкта. Server-Side Apply намагається обʼєднати поля на основі того, хто ними керує, замість того, щоб замінювати їх значення. Таким чином, кілька акторів можуть оновлювати один і той самий обʼєкт без несподіваних перешкод.
Коли користувач надсилає обʼєкт із повністю специфікованим наміром на точку доступу Server-Side Apply, сервер зʼєднує його з поточним обʼєктом, надаючи перевагу значенню з тіла запиту, якщо воно вказане в обох місцях. Якщо набір елементів, присутніх у застосованій конфігурації, не є надмножиною елементів, застосованих тим самим користувачем минулого разу, кожен відсутній елемент, яким не керують інші аплікатори, видаляється. Для отримання додаткової інформації про те, як схема обʼєкта використовується для прийняття рішень під час злиття, дивіться sigs.k8s.io/structured-merge-diff.
API Kubernetes (та код Go, який реалізує це API для Kubernetes) дозволяє визначати маркери стратегії злиття. Ці маркери описують підтримувану стратегію злиття для полів в обʼєктах Kubernetes. Для CustomResourceDefinition, ви можете встановити ці маркери під час визначення власного ресурсу.
Маркер Golang | Розширення OpenAPI | Можливі значення | Опис |
---|
//+listType | x-kubernetes-list-type | atomic /set /map | Застосовується до списків. set застосовується до списків, які включають лише скалярні елементи. Ці елементи повинні бути унікальними. map застосовується до списків вкладених типів. Значення ключів (див. listMapKey ) повинні бути унікальними в списку. atomic може застосовуватися до будь-якого списку. Якщо налаштовано як atomic , весь список замінюється під час злиття. У будь-який момент часу список належить одному менеджеру. Якщо set або map , різні менеджери можуть окремо керувати елементами. |
//+listMapKey | x-kubernetes-list-map-keys | Список імен полів, наприклад, ["port", "protocol"] | Застосовується лише при +listType=map . Список імен полів, значення яких унікально ідентифікують елементи у списку. Хоча ключів може бути багато, listMapKey є одниною, тому що ключі потрібно вказувати індивідуально в типі Go. Поля ключів повинні бути скалярами. |
//+mapType | x-kubernetes-map-type | atomic /granular | Застосовується до map. atomic означає, що map можна замінити повністю тільки одним менеджером. granular означає, що map підтримує окремих менеджерів, які оновлюють окремі поля. |
//+structType | x-kubernetes-map-type | atomic /granular | Застосовується до структур; інакше те ж використання та анотація OpenAPI, як //+mapType . |
Якщо listType
відсутній, сервер API інтерпретує patchStrategy=merge
як listType=map
і відповідний маркер patchMergeKey
як listMapKey
.
Тип списку atomic
є рекурсивним.
(У коді Go для Kubernetes, ці маркери вказуються як коментарі, і авторам коду не потрібно повторювати їх як теґи полів).
Власні ресурси та Серверне застосування
Стандартно, Server-Side Apply обробляє власні ресурси користувачів як неструктуровані дані. Усі ключі розглядаються як поля структури, а всі списки вважаються атомарними.
Якщо у визначенні CustomResourceDefinition міститься схема, яка містить анотації, визначені у попередньому розділі Стратегія злиття, ці анотації будуть використовуватись під час злиття обʼєктів цього типу.
Сумісність при зміні топології
У рідкісних випадках автор CustomResourceDefinition (CRD) або вбудованого ресурсу може захотіти змінити специфічну топологію поля у своєму ресурсі, не збільшуючи його версію API. Зміна топології типів шляхом оновлення кластера або CRD має різні наслідки при оновленні наявних обʼєктів. Є дві категорії змін: коли поле переходить від map
/set
/granular
до atomic
і навпаки.
Коли listType
, mapType
або structType
змінюються з map
/set
/granular
на atomic
, весь список, map або структура наявних обʼєктів будуть в підсумку належати акторам, які володіли елементом цих типів. Це означає, що будь-яка подальша зміна цих обʼєктів призведе до конфлікту.
Коли listType
, mapType
або structType
змінюються з atomic
на map
/set
/granular
, сервер API не може визначити нову власність цих полів. Через це конфлікти не виникатимуть під час оновлення обʼєктів із цими полями. Тому не рекомендується змінювати тип із atomic
на map
/set
/granular
.
Візьмемо, наприклад, власний ресурс користувача ресурс:
---
apiVersion: example.com/v1
kind: Foo
metadata:
name: foo-sample
managedFields:
- manager: "manager-one"
operation: Apply
apiVersion: example.com/v1
fields:
f:spec:
f:data: {}
spec:
data:
key1: val1
key2: val2
До того, як spec.data
зміниться з atomic
на granular
, manager-one
володіє полем spec.data
і всіма полями в ньому (key1
та key2
). Коли CRD змінюється, щоб зробити spec.data
granular
, manager-one
продовжує володіти полем верхнього рівня spec.data
(що означає, що жоден інший менеджер не може видалити map data
без конфлікту), але він більше не володіє key1
та key2
, тому інший менеджер може змінити або видалити ці поля без конфлікту.
Використання Server-Side Apply в контролер
Як розробник контролера, ви можете використовувати Server-Side Apply як спосіб спростити логіку оновлення вашого контролера. Основні відмінності від кead-modify-write та/або patch наступні:
- застосований обʼєкт повинен містити всі поля, які цікавлять контролер.
- немає способу видалити поля, які не були застосовані контролером раніше (контролер все ще може надіслати patch або update для цих випадків використання).
- обʼєкт не обовʼязково має бути прочитаним перед тим;
resourceVersion
не потрібно вказувати.
Для контролерів рекомендується завжди застосовувати конфлікти на обʼєктах, якими вони володіють і керують, оскільки вони можуть не мати можливості розвʼязати або подіяти на ці конфлікти.
Передача власності
Окрім контролю конкурентності, забезпеченого вирішенням конфліктів, Server-Side Apply надає можливості для виконання координованих переходів власності полів від користувачів до контролерів.
Це найкраще пояснюється на прикладі. Розглянемо, як безпечно перевести власність поля replicas
від користувача до контролера, дозволяючи автоматичне горизонтальне масштабування для Deployment, використовуючи ресурс HorizontalPodAutoscaler та його супровідний контролер.
Скажімо, користувач визначив Deployment з replicas
, встановленим на бажане значення:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
І користувач створив Deployment, використовуючи Server-Side Apply, наступним чином:
kubectl apply -f https://k8s.io/examples/application/ssa/nginx-deployment.yaml --server-side
Пізніше автоматичне масштабування увімкнено для Deployment; наприклад:
kubectl autoscale deployment nginx-deployment --cpu-percent=50 --min=1 --max=10
Тепер користувач хоче видалити replicas
з конфігурації, щоб вони випадково не конфліктували з HorizontalPodAutoscaler (HPA) та його контролером. Однак виникають перегони: може пройти деякий час, перш ніж HPA вирішить змінити .spec.replicas
; якщо користувач видаляє .spec.replicas
перед тим, як HPA запише в поле і стане його власником, тоді API-сервер встановить .spec.replicas
на 1 (стандартна кількість реплік для Deployment). Це не те, що хоче користувач, ще й тимчасово — це може погіршити робоче навантаження.
Є два рішення:
(базовий) Залиште replicas
в конфігурації; коли HPA нарешті запише в це поле, система сповістить користувачу про конфлікт при спробі зробити це. На цьому етапі безпечно видалити його з конфігурації.
(більш розширений) Однак, якщо користувач не хоче чекати, наприклад, через те що вони хочуть, щоб кластер був зрозумілим для їх колег, тоді вони можуть виконати наступні кроки, щоб зробити видалення replicas
з їх конфігурації безпечним:
Спочатку користувач визначає новий маніфест, що містить лише поле replicas
:
# Збережіть цей файл як 'nginx-deployment-replicas-only.yaml'.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
Примітка:
Файл YAML для SSA у цьому випадку містить лише поля, які ви хочете змінити. Вам не слід надавати повністю сумісний з Deployment маніфест, якщо ви хочете змінити лише поле spec.replicas
, використовуючи SSA.Користувач застосовує цей маніфест, використовуючи приватне імʼя менеджера полів. У цьому прикладі користувач вибрав handover-to-hpa
:
kubectl apply -f nginx-deployment-replicas-only.yaml \
--server-side --field-manager=handover-to-hpa \
--validate=false
Якщо застосування призводить до конфлікту з контролером HPA, тоді нічого не робіть. Конфлікт вказує на те, що контролер вже вимагає поле на цьому етапі.
На цьому етапі користувач може видалити поле replicas
з маніфесту:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
Зауважте, що кожного разу, коли контролер HPA встановлює значення поля replicas
на нове значення, тимчасовий менеджер полів більше не володіє жодними полями й буде автоматично видалений. Додаткового прибирання не потрібно.
Передача власності між менеджерами
Менеджери полів можуть передавати власність поля між собою, встановлюючи значення поля в тому самому значенні в обох їх застосованих конфігураціях, що призводить до того, що вони спільно володіють полем. Після цього менеджери можуть відмовитися від володіння полям та завершити передачу іншому менеджеру поля, видаливши поле з їх застосованої конфігурації.
Порівняння з Client-Side Apply
Server-Side Apply призначений як для заміни початкової реалізації команди kubectl apply
на стороні клієнта, так і для забезпечення простого та ефективного механізму для контролерів, щоб впроваджувати свої зміни.
Порівняно з анотацією last-applied
, якою керує kubectl
, Server-Side Apply використовує більш декларативний підхід, що відстежує управління полями обʼєкта, а не останній стан, застосований користувачем. Це означає, що як побічний ефект використання Server-Side Apply, стає доступною інформація про те, який менеджер полів керує кожним полем в обʼєкті.
Наслідком виявлення та вирішення конфліктів, реалізованих у Server-Side Apply, є те, що аплікатор завжди має актуальні значення полів у своєму локальному стані. Якщо ні, то він отримає конфлікт під час наступного застосування. Будь-який з трьох варіантів розвʼязання конфліктів призводить до того, що застосована конфігурація стає актуальною підмножиною полів обʼєкта на сервері.
Це відрізняється від Client-Side Apply, де застарілі значення, які були перезаписані іншими користувачами, залишаються в локальній конфігурації аплікатора. Ці значення стають точними лише тоді, коли користувач оновлює конкретне поле, якщо взагалі оновлює, і аплікатор не має способу дізнатися, чи наступне застосування перезапише зміни інших користувачів.
Ще однією відмінністю є те, що аплікатор, використовуючи Client-Side Apply, не може змінити версію API, яку він використовує, тоді як Server-Side Apply підтримує цей випадок використання.
Міграція між client-side і server-side apply
Перехід з client-side apply на server-side apply
Користувачі client-side apply, які керують ресурсом за допомогою kubectl apply
, можуть почати використовувати server-side apply з наступним прапорцем.
kubectl apply --server-side [--dry-run=server]
Стандартно, управління полями обʼєкта переходить з client-side apply на kubectl server-side apply без виникнення конфліктів.
Увага:
Тримайте анотацію last-applied-configuration
в актуальному стані. Анотація визначає поля, якими керує client-side apply. Будь-які поля, якими не керує client-side apply, викликають конфлікти.
Наприклад, якщо ви використовували kubectl scale
для оновлення поля replicas після client-side apply, тоді це поле не належить client-side apply і створює конфлікти при kubectl apply --server-side
.
Ця поведінка стосується server-side apply з менеджером полів kubectl
. Як виняток, ви можете відмовитися від цієї поведінки, вказавши іншого, не стандартного менеджера полів, як показано в наступному прикладі. Стандартним менеджером полів для kubectl server-side apply є kubectl
.
kubectl apply --server-side --field-manager=my-manager [--dry-run=server]
Повернення з server-side apply на client-side apply
Якщо ви керуєте ресурсом за допомогою kubectl apply --server-side
, ви можете перейти на client-side apply безпосередньо за допомогою kubectl apply
.
Повернення працює тому, що kubectl Server-Side Apply тримає анотацію last-applied-configuration
в актуальному стані, якщо ви використовуєте kubectl apply
.
Ця поведінка стосується Server-Side Apply з менеджером полів kubectl. Як виняток, ви можете відмовитися від цієї поведінки, вказавши іншого, не стандартного менеджера полів, як показано в наступному прикладі. Стандартним менеджером полів для kubectl server-side apply є kubectl
.
kubectl apply --server-side --field-manager=my-manager [--dry-run=server]
Реалізація API
Дієслово PATCH
для ресурсу, який підтримує Server-Side Apply, може приймати неофіційний тип контенту application/apply-patch+yaml
. Користувачі Server-Side Apply можуть надіслати частково специфіковані обʼєкти у вигляді YAML як тіло запиту PATCH
до URI ресурсу. При застосуванні конфігурації слід завжди включати всі поля, які є важливими для результату (наприклад, бажаний стан), який ви хочете визначити.
Усі повідомлення в форматі JSON є дійсним YAML. Деякі клієнти вказують запити Server-Side Apply, використовуючи тіла запитів у форматі YAML, які також є дійсним JSON.
Контроль доступу і дозволи
Оскільки Server-Side Apply є типом PATCH
, субʼєкт (такий як Роль для Kubernetes RBAC) потребує дозволу patch для редагування наявних ресурсів, а також дозволу на дієслово create для створення нових ресурсів за допомогою Server-Side Apply.
Очищення managedFields
Можливо видалити всі managedFields
з обʼєкта, переписавши їх за допомогою patch (JSON Merge Patch, Strategic Merge Patch, JSON Patch) або через update (HTTP PUT
); іншими словами, через будь-яку операцію запису, окрім apply. Це можна зробити, переписавши поле managedFields
порожнім записом. Два приклади:
PATCH /api/v1/namespaces/default/configmaps/example-cm
Accept: application/json
Content-Type: application/merge-patch+json
{
"metadata": {
"managedFields": [
{}
]
}
}
PATCH /api/v1/namespaces/default/configmaps/example-cm
Accept: application/json
Content-Type: application/json-patch+json
If-Match: 1234567890123456789
[{"op": "replace", "path": "/metadata/managedFields", "value": [{}]}]
Це перепише managedFields
списком, що містить один порожній запис, що в результаті повністю видалить managedFields
з обʼєкта. Зверніть увагу, що встановлення managedFields
як порожнього списку не скине це поле. Це зроблено спеціально, щоб managedFields
ніколи не видалялися клієнтами, які не знають про це поле.
У випадках, коли операція скидання комбінується зі змінами інших полів, крім managedFields
, це призведе до того, що спочатку managedFields
буде скинуто, а інші зміни будуть оброблені пізніше. У результаті аплікатор бере на себе відповідальність за будь-які поля, оновлені в тому ж запиті.
Примітка:
Server-Side Apply не правильно відстежує власність на субресурси, які не отримують тип обʼєкта ресурсу. Якщо ви використовуєте Server-Side Apply з таким субресурсом, змінені поля можуть не відслідковуватися.Що далі
Ви можете прочитати про managedFields
у довіднику API Kubernetes для верхнього рівня поля metadata
.
3 - Бібліотеки клієнтів
Ця сторінка містить огляд бібліотек клієнтів для використання Kubernetes API різними мовами програмування.
Для написання застосунків, що використовують Kubernetes REST API, вам не потрібно самостійно реалізовувати виклики API та типи запитів/відповідей. Ви можете використовувати бібліотеку клієнтів для мови програмування, яку ви використовуєте.
Бібліотеки клієнтів часто виконують загальні завдання, такі як автентифікація. Більшість бібліотек клієнтів можуть знаходити та використовувати Kubernetes Service Account для автентифікації, якщо API клієнт працює всередині кластера Kubernetes, або можуть розуміти формат kubeconfig файлу для читання облікових даних та адреси API сервера.
Офіційно підтримувані бібліотеки клієнтів Kubernetes
Наступні бібліотеки клієнтів офіційно підтримуються Kubernetes SIG API Machinery.
Бібліотеки клієнтів, що підтримуються спільнотою
Примітка: Цей розділ містить посилання на проєкти сторонніх розробників, які надають функціонал, необхідний для Kubernetes. Автори проєкту Kubernetes не несуть відповідальності за ці проєкти. Проєкти вказано в алфавітному порядку. Щоб додати проєкт до цього списку, ознайомтеся з
посібником з контенту перед надсиланням змін.
Докладніше. Наступні бібліотеки клієнтів Kubernetes надаються і підтримуються їх авторами, а не командою Kubernetes.
4 - Загальна мова виразів у Kubernetes
Загальна мова виразів (Common Expression Language, CEL) використовується в API Kubernetes для оголошення правил валідації, політик та інших обмежень чи умов.
Вирази CEL оцінюються безпосередньо на сервері API, що робить CEL зручним альтернативним рішенням для зовнішніх механізмів, таких як вебхуки, для багатьох випадків розширення функціональності. Ваші вирази CEL продовжують виконуватись, поки компонент сервера API у складі панелі управління залишається доступним.
Огляд мови
Мова CEL має простий синтаксис, який схожий на вирази в C, C++, Java, JavaScript і Go.
CEL була розроблена для вбудовування в застосунки. Кожна "програма" CEL — це один вираз, який обраховується до одного значення. Вирази CEL зазвичай короткі "одноразові", що добре вбудовуються в строкові поля ресурсів API Kubernetes.
Вхідні дані для програми CEL — це "змінні". Кожне поле API Kubernetes, яке містить CEL, декларує в документації API, які змінні доступні для використання для цього поля. Наприклад, у полі x-kubernetes-validations[i].rules
у CustomResourceDefinitions доступні змінні self
і oldSelf
, що відносяться до попереднього та поточного стану даних власного ресурсу користувача, які потрібно перевірити за допомогою виразу CEL. Інші поля API Kubernetes можуть оголошувати різні змінні. Дивіться документацію API для полів API, щоб дізнатися, які змінні доступні для цього поля.
Приклади виразів CEL:
Приклади виразів CEL та їх призначенняПравило | Призначення |
---|
self.minReplicas <= self.replicas && self.replicas <= self.maxReplicas | Перевірити, що три поля, що визначають репліки, розташовані в правильному порядку |
'Available' in self.stateCounts | Перевірити, що в map існує запис з ключем 'Available' |
(self.list1.size() == 0) != (self.list2.size() == 0) | Перевірити, що один із двох списків не порожній, але не обидва одночасно |
self.envars.filter(e, e.name = 'MY_ENV').all(e, e.value.matches('^[a-zA-Z]*$') | Перевірити поле 'value' у запису listMap, де поле ключа 'name' дорівнює 'MY_ENV' |
has(self.expired) && self.created + self.ttl < self.expired | Перевірити, що дата 'expired' є пізніше дати 'created' плюс тривалість 'ttl' |
self.health.startsWith('ok') | Перевірити, що строкове поле 'health' має префікс 'ok' |
self.widgets.exists(w, w.key == 'x' && w.foo < 10) | Перевірити, що властивість 'foo' елемента listMap з ключем 'x' менше 10 |
type(self) == string ? self == '99%' : self == 42 | Перевірити поле типу int-або-string для обох випадків: int та string |
self.metadata.name == 'singleton' | Перевірити, що імʼя обʼєкта відповідає конкретному значенню (робить його унікальним) |
self.set1.all(e, !(e in self.set2)) | Перевірити, що два списки (listSets) не перетинаються |
self.names.size() == self.details.size() && self.names.all(n, n in self.details) | Перевірити, що map 'details' має ключі, які відповідають елементам у списку 'names' |
self.details.all(key, key.matches('^[a-zA-Z]*$')) | Перевірити ключі map 'details' |
self.details.all(key, self.details[key].matches('^[a-zA-Z]*$')) | Перевірити значення map 'details' |
Опції CEL, особливості мови та бібліотеки
CEL налаштовується з наступними опціями, бібліотеками та особливостями мови, введеними у зазначених версіях Kubernetes:
Опція, бібліотека або особливість мови CEL | Включено | Доступність |
---|
Стандартні макроси | has , all , exists , exists_one , map , filter | Усі версії Kubernetes |
Стандартні функції | Дивіться офіційний список стандартних визначень | Усі версії Kubernetes |
Однорідні агрегаційні літерали | | Усі версії Kubernetes |
Часовий пояс UTC за замовчуванням | | Усі версії Kubernetes |
Рання перевірка декларацій | | Усі версії Kubernetes |
бібліотека розширених рядків, Версія 1 | charAt , indexOf , lastIndexOf , lowerAscii , upperAscii , replace , split , join , substring , trim | Усі версії Kubernetes |
Бібліотека списків Kubernetes | Дивіться бібліотеку списків Kubernetes | Усі версії Kubernetes |
Бібліотека регулярних виразів Kubernetes | Дивіться бібліотеку регулярних виразів Kubernetes | Усі версії Kubernetes |
Бібліотека URL Kubernetes | Дивіться бібліотеку URL Kubernetes | Усі версії Kubernetes |
Бібліотека авторизації Kubernetes | Дивіться бібліотеку авторизації Kubernetes | Усі версії Kubernetes |
Бібліотека кількостей Kubernetes | Дивіться бібліотеку кількостей Kubernetes | Версії Kubernetes 1.29+ |
Опційні типи CEL | Дивіться опційні типи CEL | Версії Kubernetes 1.29+ |
Порівняння чисел різних типів CEL | Дивіться порівняння чисел різних типів CEL | Версії Kubernetes 1.29+ |
Функції CEL, особливості та налаштування мови підтримують відкат панелі управління Kubernetes. Наприклад, опційні значення CEL були введені у Kubernetes 1.29, і лише сервери API цієї версії або новіші прийматимуть запити на запис виразів CEL, які використовують опційні значення CEL. Однак, коли кластер відкочується до версії Kubernetes 1.28, вирази CEL, що використовують "опційні значення CEL", які вже збережені в ресурсах API, продовжуватимуть правильно оцінюватись.
Бібліотеки CEL Kubernetes
Крім спільнотних бібліотек CEL, Kubernetes включає бібліотеки CEL, які доступні у всіх місцях використання CEL в Kubernetes.
Бібліотека списків Kubernetes
Бібліотека списків включає indexOf
та lastIndexOf
, які працюють аналогічно функціям рядків з такими самими назвами. Ці функції повертають перший або останній індекс елемента у списку.
Бібліотека списків також включає min
, max
та sum
. Сума підтримується для всіх типів чисел, а також для типу тривалості. Мінімум та максимум підтримуються для всіх типів, що можна порівняти.
Також надається функція isSorted
для зручності та підтримується для всіх типів, які можна порівняти.
Приклади:
Приклади виразів CEL, що використовують функції бібліотеки списківВираз CEL | Призначення |
---|
names.isSorted() | Перевірити, що список імен зберігається в алфавітному порядку |
items.map(x, x.weight).sum() == 1.0 | Перевірити, що "ваги" списку обʼєктів дорівнюють 1.0 |
lowPriorities.map(x, x.priority).max() < highPriorities.map(x, x.priority).min() | Перевірити, що два набори пріоритетів не перекриваються |
names.indexOf('should-be-first') == 1 | Вимагати, щоб перше імʼя у списку було певним значенням |
Для отримання додаткової інформації дивіться бібліотеку списків Kubernetes godoc.
Бібліотека регулярних виразів Kubernetes
Крім функції matches
, наданої стандартною бібліотекою CEL, бібліотека регулярних виразів надає функції find
та findAll
, що дозволяють виконувати ширший спектр операцій з регулярними виразами.
Приклади:
Приклади виразів CEL, що використовують функції бібліотеки регулярних виразівВираз CEL | Призначення |
---|
"abc 123".find('[0-9]+') | Знайти перше число у рядку |
"1, 2, 3, 4".findAll('[0-9]+').map(x, int(x)).sum() < 100 | Перевірити, що сума чисел у рядку менше 100 |
Для отримання додаткової інформації дивіться бібліотеку регулярних виразів Kubernetes godoc.
Бібліотека URL Kubernetes
Для спрощення та безпечної обробки URL надані наступні функції:
isURL(string)
перевіряє, чи є рядок рядком дійсним URL з пакетом Go net/url. Рядок повинен бути абсолютним URL.url(string) URL
конвертує рядок в URL або викликає помилку, якщо рядок не є дійсним URL.
Після розбору за допомогою функції url
, отриманий обʼєкт URL має наступні методи доступу: getScheme
, getHost
, getHostname
, getPort
, getEscapedPath
та getQuery
.
Приклади:
Приклади виразів CEL, що використовують функції бібліотеки URLВираз CEL | Призначення |
---|
url('https://example.com:80/').getHost() | Отримати частину хосту 'example.com:80' URL. |
url('https://example.com/path with spaces/').getEscapedPath() | Повертає '/path%20with%20spaces/' |
Для отримання додаткової інформації дивіться бібліотеку URL Kubernetes godoc.
Бібліотека авторизатора Kubernetes
Для виразів CEL в API, де доступна змінна типу Authorizer
, авторизатор може використовуватися для виконання перевірок авторизації для принципала (автентифікованого користувача) запиту.
Перевірки ресурсів API виконуються наступним чином:
Вкажіть групу та ресурс для перевірки: Authorizer.group(string).resource(string) ResourceCheck
.
Опційно викличте будь-яку комбінацію наступних функцій побудови для подальшого обмеження перевірки авторизації. Зверніть увагу, що ці функції повертають тип отримувача та можуть бути зʼєднані ланцюгом:
ResourceCheck.subresource(string) ResourceCheck
ResourceCheck.namespace(string) ResourceCheck
ResourceCheck.name(string) ResourceCheck
Викличте ResourceCheck.check(verb string) Decision
, щоб виконати перевірку авторизації.
Викличте allowed() bool
або reason() string
, щоб переглянути результат перевірки авторизації.
Не-ресурсна авторизація виконується так:
- Вкажіть лише шлях:
Authorizer.path(string) PathCheck
. - Викличте
PathCheck.check(httpVerb string) Decision
, щоб виконати перевірку авторизації. - Викличте
allowed() bool
або reason() string
, щоб переглянути результат перевірки авторизації.
Для виконання перевірки авторизації для службового облікового запису:
Authorizer.serviceAccount(namespace string, name string) Authorizer
Приклади виразів CEL, що використовують функції бібліотеки авторизатораВираз CEL | Призначення |
---|
authorizer.group('').resource('pods').namespace('default').check('create').allowed() | Повертає true, якщо принципалу (користувачу або службовому обліковому запису) дозволено створювати Podʼи у просторі імен 'default'. |
authorizer.path('/healthz').check('get').allowed() | Перевіряє, чи авторизований принципал (користувач або службовий обліковий запис) виконує HTTP GET-запити до шляху API /healthz. |
authorizer.serviceAccount('default', 'myserviceaccount').resource('deployments').check('delete').allowed() | Перевіряє, чи службовий обліковий запис має дозвіл на видалення deployments. |
Для отримання додаткової інформації дивіться бібліотеку авторизатора Kubernetes godoc.
Бібліотека кількості Kubernetes
У Kubernetes 1.28 додана підтримка обробки рядків кількості (наприклад, 1,5G, 512k, 20Mi).
isQuantity(string)
перевіряє, чи є рядок дійсною кількістю відповідно до Кількості ресурсів Kubernetes.quantity(string) Quantity
конвертує рядок у кількість або викликає помилку, якщо рядок не є дійсною кількістю.
Після розбору за допомогою функції quantity
, отриманий обʼєкт кількості має наступний набір методів:
Набір доступних методів для кількостіМетод | Повертає тип | Опис |
---|
isInteger() | bool | Повертає true, якщо asInteger може бути викликано без помилки. |
asInteger() | int | Повертає представлення поточного значення як int64, якщо це можливо, або викликає помилку, якщо конвертація призводить до переповнення або втрати точності. |
asApproximateFloat() | float | Повертає представлення кількості як float64, що може втратити точність. |
sign() | int | Повертає 1 , якщо кількість додатня, -1 , якщо вона відʼємна, або 0 , якщо вона нуль. |
add(<Quantity>) | Quantity | Повертає суму двох кількостей. |
add(<int>) | Quantity | Повертає суму кількості та цілого числа. |
sub(<Quantity>) | Quantity | Повертає різницю між двома кількостями. |
sub(<int>) | Quantity | Повертає різницю між кількістю та цілим числом. |
isLessThan(<Quantity>) | bool | Повертає true, якщо отримувач менше операнта. |
isGreaterThan(<Quantity>) | bool | Повертає true, якщо отримувач більше операнта. |
compareTo(<Quantity>) | int | Порівнює отримувача з операндом та повертає 0, якщо вони рівні, 1, якщо отримувач більший або -1, якщо отримувач менший за операнд. |
Приклади:
Приклади виразів CEL, що використовують функції бібліотеки кількостіВираз CEL | Призначення |
---|
quantity("500000G").isInteger() | Перевірка, чи конвертація в ціле число викликає помилку. |
quantity("50k").asInteger() | Точна конвертація в ціле число. |
quantity("9999999999999999999999999999999999999G").asApproximateFloat() | Втратна конвертація в плаваючий рядок. |
quantity("50k").add(quantity("20k")) | Додати дві кількості. |
quantity("50k").sub(20000) | Відняти ціле число від кількості. |
quantity("50k").add(20).sub(quantity("100k")).sub(-50000) | Ланцюгове додавання та віднімання цілих чисел та кількостей. |
quantity("200M").compareTo(quantity("0.2G")) | Порівняти дві кількості. |
quantity("150Mi").isGreaterThan(quantity("100Mi")) | Перевірити, чи кількість більша за отримувача. |
quantity("50M").isLessThan(quantity("100M")) | Перевірити, чи кількість менша за отримувача. |
Перевірка типів
CEL — це поступово типізована мова.
Деякі поля API Kubernetes містять повністю перевірені типи CEL-виразів. Наприклад, Правила валідації власних ресурсів повністю перевірені за типом.
Деякі поля API Kubernetes містять частково перевірені типи CEL-виразів. Частково перевірений вираз — це вираз, в якому деякі змінні статично типізовані, а інші — динамічно типізовані. Наприклад, в CEL-виразах ValidatingAdmissionPolicies, змінна request
має тип, але змінна object
динамічно типізована. У звʼязку з цим вираз, що містить request.namex
, не пройде перевірку типів, оскільки поле namex
не визначене. Однак object.namex
пройде перевірку типів навіть тоді, коли поле namex
не визначене для типів ресурсів, на які посилається object
, оскільки object
динамічно типізований.
Макрос has()
в CEL можна використовувати у виразах CEL для перевірки доступності поля динамічно типізованої змінної перед спробою доступу до значення поля. Наприклад:
has(object.namex) ? object.namex == 'special' : request.name == 'special'
Інтеграція системи типів
Таблиця, що показує взаємозвʼязок між типами OpenAPIv3 та CELТип OpenAPIv3 | Тип CEL |
---|
'object' з Properties | object / "тип повідомлення" (type(<object>) обчислюється як selfType<uniqueNumber>.path.to.object.from.self |
'object' з AdditionalProperties | map |
'object' з x-kubernetes-embedded-type | object / "тип повідомлення", 'apiVersion', 'kind', 'metadata.name' і 'metadata.generateName' включені в схему |
'object' з x-kubernetes-preserve-unknown-fields | object / "тип повідомлення", невідомі поля НЕ доступні у виразі CEL |
x-kubernetes-int-or-string | об'єднання int або string, self.intOrString < 100 || self.intOrString == '50%' обчислюється як true для 50 і "50%" |
'array' | list |
'array' з x-kubernetes-list-type=map | list з базованими на map рівноправністю та унікальними ключами |
'array' з x-kubernetes-list-type=set | list з базованими на set рівноправністю та унікальними елементами |
'boolean' | boolean |
'number' (усі формати) | double |
'integer' (усі формати) | int (64) |
немає еквівалента | uint (64) |
'null' | null_type |
'string' | string |
'string' з format=byte (base64 encoded) | bytes |
'string' з format=date | timestamp (google.protobuf.Timestamp) |
'string' з format=datetime | timestamp (google.protobuf.Timestamp) |
'string' з format=duration | duration (google.protobuf.Duration) |
Також дивіться: Типи CEL, Типи OpenAPI, Структурні схеми Kubernetes.
Порівняння рівності для масивів з x-kubernetes-list-type
типу set
або map
ігнорує порядок елементів. Наприклад, [1, 2] == [2, 1]
якщо масиви представляють значення Kubernetes set
.
Конкатенація для масивів з x-kubernetes-list-type
використовує семантику типу списку:
set
: X + Y
виконує об'єднання, де позиції елементів у X
зберігаються, а не перетинаючі елементи у Y
додаються, зберігаючи їх частковий порядок.map
: X + Y
виконує об'єднання, де позиції ключів у X
зберігаються, але значення перезаписуються значеннями у Y
, коли ключові множини X
і Y
перетинаються. Елементи у Y
з неперетинаючими ключами додаються, зберігаючи їх частковий порядок.
Екранування
Тільки імена властивостей ресурсів Kubernetes форми [a-zA-Z_.-/][a-zA-Z0-9_.-/]*
доступні з CEL. Доступні імена властивостей екрануються згідно з наступними правилами при доступі у виразі:
Таблиця правил екранування ідентифікаторів CELекрануюча послідовність | еквівалент імені властивості |
---|
__underscores__ | __ |
__dot__ | . |
__dash__ | - |
__slash__ | / |
__{keyword}__ | ЗАРЕЗЕРВОВАНЕ ключове слово CEL |
Коли ви екрануєте будь-яке з ЗАРЕЗЕРВОВАНИХ ключових слів CEL, збіг повинен точно відповідати імені властивості та використовувати екранування з підкресленням (наприклад, int
у слові sprint
не буде екрановано, і це не буде необхідно).
Приклади екранування:
Приклади екранованих ідентифікаторів CELімʼя властивості | правило з екранованим імʼям властивості |
---|
namespace | self.__namespace__ > 0 |
x-prop | self.x__dash__prop > 0 |
redact__d | self.redact__underscores__d > 0 |
string | self.startsWith('kube') |
Обмеження ресурсів
CEL не є повноцінною мовою Тюрінга і пропонує різноманітні засоби безпеки для обмеження часу виконання. Функції обмеження ресурсів CEL забезпечують зворотний звʼязок розробникам щодо складності виразів та допомагають захистити сервер API від надмірного споживання ресурсів під час оцінювання. Ці функції використовуються для запобігання надмірного споживання ресурсів сервера API під час виконання CEL.
Ключовим елементом функцій обмеження ресурсів є одиниця вартості, яку CEL визначає як спосіб відстеження використання ЦП. Одиниці вартості незалежні від системного навантаження та апаратного забезпечення. Одиниці вартості також є детермінованими; для будь-якого заданого виразу CEL та вхідних даних, оцінка виразу інтерпретатором CEL завжди призведе до однакової вартості.
Багато з основних операцій CEL мають фіксовані витрати. Найпростіші операції, такі як порівняння (наприклад, <
), мають вартість 1. Деякі мають вищу фіксовану вартість, наприклад, оголошення літералів списку мають фіксовану базову вартість 40 одиниць вартості.
Виклики функцій, реалізованих у рідному коді, оцінюються на основі часової складності операції. Наприклад, операції, що використовують регулярні вирази, такі як match
та find
, оцінюються з використанням приблизної вартості length(regexString)*length(inputString)
. Приблизна вартість відображає найгірший випадок часової складності реалізації RE2 в Go.
Бюджет вартості під час виконання
Усі вирази CEL, які оцінюються Kubernetes, обмежені бюджетом вартості під час виконання. Бюджет вартості під час виконання — це оцінка фактичного використання ЦП, що обчислюється шляхом інкрементування лічильника одиниць вартості під час інтерпретації виразу CEL. Якщо інтерпретатор CEL виконає занадто багато інструкцій, бюджет вартості під час виконання буде перевищено, виконання виразу буде зупинено і результатом стане помилка.
Деякі ресурси Kubernetes визначають додатковий бюджет вартості під час виконання, який обмежує виконання декількох виразів. Якщо загальна вартість виразів перевищує бюджет, виконання виразів буде зупинено і результатом стане помилка. Наприклад, валідація власного ресурсу користувача має бюджет вартості під час виконання за одну валідацію для всіх Правил Валідації, які оцінюються для валідації власного ресурсу.
Оцінювані обмеження вартості
Для деяких ресурсів Kubernetes, сервер API також може перевірити, чи не буде найгірший випадок оціненого часу виконання виразів CEL надто дорогим для виконання. Якщо так, сервер API запобігає записуванню виразу CEL у ресурсі API, відхиляючи операції створення або оновлення, що містять вираз CEL у ресурсі API. Ця функція пропонує сильнішу гарантію, що вирази CEL, записані у ресурс API, будуть оцінені під час виконання без перевищення бюджету вартості під час виконання.
5 - Політика застарівання Kubernetes
Цей документ описує політику застарівання для різних аспектів системи.
Kubernetes — це велика система з багатьма компонентами та багатьма учасниками. Як і в будь-якому такому програмному забезпеченні, набір функцій природно розвивається з часом, і іноді функцію може знадобитися видалити. Це може включати API, прапорець або навіть всю функцію. Щоб уникнути порушення роботи наявних користувачів, Kubernetes дотримується політики застарівання для аспектів системи, які підлягають видаленню.
Застарівання частин API
Оскільки Kubernetes є системою, що керується API, API еволюціонував з часом, віддзеркалюючи постійно змінюване розуміння проблемної області. API Kubernetes фактично є набором API, які називаються "групами API", і кожна група API має свою незалежну версію. Версії API поділяються на 3 основні треки, кожен з яких має різні політики застарівання:
Приклад | Трек |
---|
v1 | GA (загальнодоступна, стабільна) |
v1beta1 | Beta (попередній випуск, перед GA) |
v1alpha1 | Alpha (експериментальна) |
Конкретний випуск Kubernetes може підтримувати будь-яку кількість груп API та будь-яку кількість версій кожного з них.
Наступні правила регулюють застарівання елементів API. Це включає:
- Ресурси REST (також відомі як обʼєкти API)
- Поля ресурсів REST
- Анотації на ресурсах REST, включаючи "бета" анотації, але не включаючи "альфа" анотації
- Перелічувані або постійні значення
- Структури конфігурації компонентів
Ці правила застосовуються між офіційними випусками, а не між довільними внесками коду в основну гілку або гілки випусків.
Правило №1: Елементи API можуть бути видалені лише шляхом інкрементування версії групи API.
Після того, як елемент API був доданий до групи API у певній версії, він не може бути видалений з цієї версії або суттєво змінений, незалежно від треку.
Примітка:
З історичних причин є 2 "монолітні" групи API — "core" (без назви групи) і "extensions". Ресурси будуть поступово переміщені з цих застарілих груп API до більш доменно-специфічних груп API.Правило №2: Обʼєкти API повинні мати можливість переходу між версіями API в даному випуску без втрати інформації, за винятком випадків, коли цілі ресурси REST не існують у деяких версіях.
Наприклад, обʼєкт може бути записаний як v1, потім прочитаний як v2 і перетворений на v1, і отриманий ресурс v1 буде ідентичний оригіналу. Представлення у v2 може відрізнятися від v1, але система повинна вміти конвертувати між ними в обидва боки. Крім того, будь-яке нове поле, додане у v2, повинно мати можливість обміну на v1 і назад, що означає, що v1 можливо доведеться додати еквівалентне поле або представити його як анотацію.
Правило №3: Версія API в даному треку не може бути застарілою на користь менш стабільної версії API.
- GA версії API можуть замінювати бета та альфа версії API.
- Бета версії API можуть замінювати попередні бета та альфа версії API, але не можуть замінювати GA версії API.
- Альфа версії API можуть замінювати попередні альфа версії API, але не можуть замінювати GA або бета версії API.
Правило №4а: Тривалість життя API визначається рівнем стабільності API
- GA версії API можуть бути позначені як застарілі, але не можуть бути видалені в межах основної версії Kubernetes
- Бета версії API застарівають не раніше ніж через 9 місяців або 3 мінорних випуски після впровадження (що довше), і більше не обслуговуються через 9 місяців або 3 мінорних випуски після застарівання (що довше)
- Альфа версії API можуть бути видалені в будь-якому випуску без попереднього повідомлення про застарівання
Це гарантує, що підтримка бета API охоплює максимальний підтримуваний розрив версій у 2 випуски, і що API не застоюються на нестабільних бета версіях, накопичуючи продуктивне використання, яке буде порушене, коли підтримка бета API закінчиться.
Примітка:
Зараз немає планів щодо основної версії Kubernetes, що видаляє GA API.Примітка:
До тих пір, поки
#52185 не буде вирішено, жодні версії API, які були віднесені до зберігання, не можуть бути видалені. Обслуговування REST точок доступу для цих версій може бути відключено (відповідно до графіків застарівання в цьому документі), але API сервер повинен залишатися здатним декодувати/конвертувати раніше збережені дані зі сховища.
Правило №4б: "Бажана" версія API та "версія зберігання" для даної групи можуть не просуватися до того, як буде зроблено випуск, що підтримує як нову версію, так і попередню версію.
Користувачі повинні мати можливість оновитися до нової версії Kubernetes, а потім повернутися до попередньої версії, не конвертуючи нічого до нової версії API або уникаючи порушень (якщо вони явно не використовували функції, доступні лише в новішій версії). Це особливо очевидно у збереженому представленні обʼєктів.
Все це найкраще ілюструється прикладами. Уявіть собі випуск Kubernetes, версія X, який вводить нову групу API. Новий випуск Kubernetes виходить приблизно кожні 4 місяці (3 на рік). Наступна таблиця описує, які версії API підтримуються в ряді наступних випусків.
Випуск | Версії API | Бажана/Версія зберігання | Примітки |
---|
X | v1alpha1 | v1alpha1 | |
X+1 | v1alpha2 | v1alpha2 | - v1alpha1 видалено, "необхідна дія" інформація про випуск
|
X+2 | v1beta1 | v1beta1 | - v1alpha2 видалено, "необхідна дія" інформація про випуск
|
X+3 | v1beta2, v1beta1 (застар іла) | v1beta1 | - v1beta1 застаріла, "необхідна дія" інформація про випуск
|
X+4 | v1beta2, v1beta1 (застаріла) | v1beta2 | |
X+5 | v1, v1beta1 (застаріла), v1beta2 (застаріла) | v1beta2 | - v1beta2 застаріла, "необхідна дія" інформація про випуск
|
X+6 | v1, v1beta2 (застаріла) | v1 | - v1beta1 видалено, "необхідна дія" інформація про випуск
|
X+7 | v1, v1beta2 (застаріла) | v1 | |
X+8 | v2alpha1, v1 | v1 | - v1beta2 видалено, "необхідна дія" інформація про випуск
|
X+9 | v2alpha2, v1 | v1 | - v2alpha1 видалено, "необхідна дія" інформація про випуск
|
X+10 | v2beta1, v1 | v1 | - v2alpha2 видалено, "необхідна дія" інформація про випуск
|
X+11 | v2beta2, v2beta1 (застаріла), v1 | v1 | - v2beta1 застаріла, "необхідна дія" інформація про випуск
|
X+12 | v2, v2beta2 (застаріла), v2beta1 (застаріла), v1 (застаріла) | v1 | - v2beta2 застаріла, "необхідна дія" інформація про випуск
- v1 застаріла на користь v2, але не буде видалена
|
X+13 | v2, v2beta1 (застаріла), v2beta2 (застаріла), v1 (застаріла) | v2 | |
X+14 | v2, v2beta2 (застаріла), v1 (застаріла) | v2 | - v2beta1 видалено, "необхідна дія" інформація про випуск
|
X+15 | v2, v1 (застаріла) | v2 | - v2beta2 видалено, "необхідна дія" інформація про випуск
|
REST ресурси (або обʼєкти API)
Розглянемо гіпотетичний REST ресурс з назвою Widget, який був присутній у версії API v1 у наведеній вище хронології і який потрібно визнати застарілим. Ми документуємо та оголошуємо про його застарівання синхронно з випуском X+1. Ресурс Widget все ще існує у версії API v1 (застарілий), але не у v2alpha1. Ресурс Widget продовжує існувати та функціонувати у випусках до, та включно з, X+8. Лише у випуску X+9, коли API v1 виходить з використання, ресурс Widget перестає існувати та його віповідна поведінка видаляється.
Починаючи з Kubernetes v1.19, виконання запиту до застарілої точки доступу REST API:
Повертає заголовок Warning
(як визначено у RFC7234, Розділ 5.5) у відповіді API.
Додає "k8s.io/deprecated":"true"
анотацію до події аудиту, зареєстрованої для запиту.
Встановлює метрику apiserver_requested_deprecated_apis
gauge у значення 1
у процесі kube-apiserver
. Метрика має мітки group
, version
, resource
, subresource
, які можна поєднати з метрикою apiserver_request_total
, і мітку removed_release
, яка вказує випуск Kubernetes, в якому API більше не буде обслуговуватися. Наступний запит Prometheus повертає інформацію про запити, зроблені до застарілих API, які будуть видалені у версії v1.22:
apiserver_requested_deprecated_apis{removed_release="1.22"} * on(group,version,resource,subresource) group_right() apiserver_request_total
Поля REST ресурсів
Як і REST ресурси в цілому, так і окреме поле, яке було присутнє у версії API v1, має існувати та функціонувати до видалення API v1. На відміну від ресурсів в цілому, API v2 можуть вибрати інше представлення для поля, допоки є можливість виконувати перехід між версіями в обидва боки. Наприклад, поле v1 з назвою "magnitude", яке було застарілим, може називатися "deprecatedMagnitude" в API v2. Коли v1 врешті буде видалено, застаріле поле може бути видалене з v2.
Перераховані або константні значення
Як і для REST ресурсу в цілому, так і його полів, константне значення, яке підтримувалося в API v1, має існувати та функціонувати до видалення API v1.
Структури конфігурацій компонентів
Конфігурації компонентів версіонуються та керуються аналогічно до REST ресурсів.
Майбутні роботи
З часом Kubernetes запровадить більш детальні версії API, і тоді ці правила будуть скориговані за потреби.
Застарівання прапорця або CLI
Система Kubernetes складається з кількох різних програм, які співпрацюють між собою. Іноді випуск Kubernetes може видаляти прапорці або команди CLI (загалом "елементи CLI") у цих програмах. Програми природно діляться на дві основні групи — програми для користувачів і програми для адміністраторів, які трохи відрізняються своїми політиками застарівання. Якщо прапорець явно не позначено або задокументовано як "alpha" або "beta", він вважається стабільним (GA).
Елементи CLI фактично є частиною API до системи, але оскільки вони не версіонуються так само, як REST API, правила застарівання наступні:
Правило №5а: Елементи CLI компонентів для користувачів (наприклад, kubectl) повинні функціонувати після оголошення їх застарівання не менше ніж:
- GA: 12 місяців або 2 випуски (залежно від того, що довше)
- Beta: 3 місяці або 1 випуск (залежно від того, що довше)
- Alpha: 0 випусків
Правило №5б: Елементи CLI компонентів для адміністраторів (наприклад, kubelet) повинні функціонувати після оголошення їх застарівання не менше ніж:
- GA: 6 місяців або 1 випуск (залежно від того, що довше)
- Beta: 3 місяці або 1 випуск (залежно від того, що довше)
- Alpha: 0 випусків
Правило №5в: Елементи командного інтерфейсу (CLI) не можуть бути застарілими на користь менш стабільних елементів CLI.
Схоже на Правило №3 для API, якщо елемент інтерфейсу командного рядка замінюється альтернативною реалізацією, наприклад, перейменуванням наявного елемента або переходом на використання конфігурації, отриманої з файлу, замість аргументу командного рядка, ця рекомендована альтернатива повинна мати той самий або вищий рівень стабільності.
Правило №6: Застарілі елементи CLI повинні видавати попередження (можливо, такі, що відключаються) при використанні.
Застарівання функціонала або поведінки
Час від часу випуск Kubernetes потребує визнання застарілим певного функціонала або поведінки системи, яка не контролюється API або CLI. У цьому випадку правила застарівання такі:
Правило №7: Застарілі функції повинні функціонувати не менше 1 року після оголошеного застарівання.
Якщо функцію або поведінку замінює альтернативна реалізація, яка вимагає роботи для переходу, повинні бути зусилля спростити перехід, якщо це можливо. Якщо альтернативна реалізація контролюється організацією Kubernetes, застосовуються наступні правила:
Правило №8: Функцію або поведінку не можна визнати застарілою на користь альтернативної реалізації, яка менш стабільна.
Наприклад, загальнодоступну функцію не можна визнати застарілою на користь бета-заміщення. Проєкт Kubernetes, однак, закликає користувачів переходити на альтернативні реалізації навіть до досягнення ними того самого рівня зрілості. Це особливо важливо для дослідження нових використань функції або отримання раннього зворотного звʼязку щодо заміщення.
Альтернативні реалізації іноді можуть бути зовнішніми інструментами або продуктами, наприклад, функція може перейти від kubelet до середовища виконання контейнерів, яке не контролюється проєктом Kubernetes. У таких випадках правило не може бути застосоване, але повинні бути зусилля, щоб забезпечити наявність шляху переходу, який не компрометує рівень зрілості компонентів. У прикладі з середовищами виконання контейнерів, зусилля можуть включати спроби забезпечити те, що популярні середовища виконання контейнерів мають версії, які пропонують такий самий рівень стабільності під час впровадження цієї заміни.
Правила застарівання для функцій та поведінки не означають, що всі зміни в системі керуються цією політикою. Ці правила застосовуються тільки до значних, видимих для користувача поведінок, які впливають на правильність роботи програм, що працюють на Kubernetes або впливають на адміністрування кластерів Kubernetes, і які повністю видаляються.
Виняток з вищезазначеного правила — це функціональні можливості. Функціональні можливості — це пари ключ=значення, які дозволяють користувачам увімкнути/вимкнути експериментальні функції.
Функціональні можливості призначені для охоплення життєвого циклу розробки функції — вони не призначені для API, що мають існувати довгий час. Таким чином, очікується, що вони будуть застарілі та видалені після того, як функція стане GA або буде відкинута.
Під час руху функції через стадії, повʼязані функціональні можливості, змінюються. Життєвий цикл функції, збігається з їх відповідними функціональними можливостями, такий:
- Alpha: функціональні можливості стандартно вимкнені та можуть бути увімкнені користувачем.
- Beta: функціональні можливості стандартно увімкнені та можуть бути вимкнені користувачем.
- GA: функціональні можливості застарілі (див. "Застарівання") і стають нечинними.
- GA, вікно застарівання завершено: функціональні можливості видаляються, і виклики до них більше не приймаються.
Застарівання
Функції можуть бути видалені на будь-якому етапі життєвого циклу до GA. Коли функції видаляються перед виходом GA, їхні повʼязані функціональні можливості також застарівають.
Якщо виконується спроба вимкнути нечинні функціональні можливості, виклик не вдається, щоб уникнути непідтримуваних сценаріїв, які в іншому випадку можуть працювати мовчки.
У деяких випадках видалення функцій до виходу GA вимагає значного часу. Функціональні можливості можуть залишатися чинними до тих пір, поки повʼязана з ними функція не буде повністю видалена, після чого самі функціональні можливості можуть бути визнані застарілими.
Коли видалення функціональних можливостей для GA-функції також вимагає значного часу, виклики до функціональних можливостей можуть залишатися чинними, якщо функціональні можливості не впливають на функцію і не викликають помилок.
Функції, які мають бути вимкнені користувачами, повинні включати механізм для вимкнення функції в повʼязаних функціональних можливостях.
Версіонування для функціональних можливостей відрізняється від раніше обговорених компонентів, тому правила застарівання такі:
Правило №9: Функціональні можливості повинні бути визнані застарілими, коли відповідна функція, якою вони керують, переходить на етап життєвого циклу наступним чином. Функціональні можливості повинні функціонувати не менше ніж:
- Від бета-функції до GA: 6 місяців або 2 випуски (залежно від того, що довше)
- Від бета-функції до EOL: 3 місяці або 1 випуск (залежно від того, що довше)
- Від альфа-функції до EOL: 0 випусків
Правило №10: Застарілі функціональні можливості повинні відповідати попередженням при використанні. Коли функціональні можливості застарівають, вони повинні бути задокументовані як в примітках про випуски, так і в відповідній довідці CLI. Як попередження, так і документація повинні вказувати, чи є функціональні можливості нечинними.
Застарівання метрики
Кожен компонент панелі управління Kubernetes використовує метрики (зазвичай за допомогою точки доступу /metrics
), які зазвичай обробляються адміністраторами кластера. Не всі метрики однакові: деякі метрики широко використовуються як показники рівня сервісу (SLI) або для визначення SLO, тому вони мають більшу важливість. Інші метрики мають більш експериментальний характер або використовуються переважно у процесі розробки Kubernetes.
Відповідно, метрики поділяються на три класи стабільності (ALPHA
, BETA
, STABLE
); це впливає на видалення метрики під час випуску Kubernetes. Ці класи визначаються важливістю метрики. Правила для застарівання та видалення метрики такі:
Правило №11а: Метрики для відповідного класу стабільності повинні функціонувати не менше ніж:
- STABLE: 4 випуски або 12 місяців (що довше)
- BETA: 2 випуски або 8 місяців (що довше)
- ALPHA: 0 випусків
Правило №11б: Метрики, після їх оголошеного застарівання, повинні функціонувати не менше ніж:
- STABLE: 3 випуски або 9 місяців (що довше)
- BETA: 1 випуск або 4 місяці (що довше)
- ALPHA: 0 випусків
Застарілі метрики будуть мати текст опису, у якому буде префікс з повідомленням про застарівання '(Застаріло з x.y)', і під час реєстрації метрики буде запис в лог з попередженням. Подібно до їх стабільних незастарілих аналогів, застарілі метрики будуть автоматично зареєстровані в точці доступу метрик і, отже, будуть видимими.
У наступному випуску (коли deprecatedVersion
метрики дорівнює current_kubernetes_version - 3)), застаріла метрика стане прихованою метрикою. На відміну від їх застарілих аналогів, приховані метрики більше не будуть автоматично реєструватися в точці доступу метрик (таким чином, вони будуть приховані). Однак їх можна буде явно увімкнути через прапорець командного рядка (--show-hidden-metrics-for-version=
). Це надає адміністраторам кластера можливість виходу зі складностей з міграцією від застарілої метрики, якщо вони не змогли відреагувати на раніше надані попередження щодо застарівання. Приховані метрики повинні бути видалені після одного випуску.
Винятки
Жодна політика не може охопити кожну можливу ситуацію. Ця політика є живим документом і буде розвиватися з часом. На практиці будуть ситуації, які не підпадають під цю політику чітко або для яких ця політика стає серйозною перешкодою. Такі ситуації слід обговорювати з SIGs та керівниками проєкту, щоб знайти найкращі рішення для конкретних випадків, завжди памʼятаючи, що Kubernetes прагне бути стабільною системою, яка, наскільки це можливо, ніколи не підводить користувачів. Винятки завжди будуть оголошені в усіх відповідних повідомленням про випуски.
6 - Посібник з міграції від застарілих API
Під час еволюції API Kubernetes періодично переглядаються або оновлюються. Коли API розвиваються, старий API стає застарілим і, зрештою, вилучається. Ця сторінка містить інформацію, яку вам потрібно знати у випадку міграції від застарілих версій API на новіші та стабільніші версії API.
Вилучені API в розрізі версій
v1.32
У випуску v1.32 перестануть обслуговуватися наступні застарілі версії API:
Ресурси контролю потоку
Версія API flowcontrol.apiserver.k8s.io/v1beta3 FlowSchema та PriorityLevelConfiguration більше не буде обслуговуватися у v1.32.
- Перенесіть маніфести та клієнти API на використання версії API flowcontrol.apiserver.k8s.io/v1, доступної з версії v1.29.
- Усі наявні збережені обʼєкти доступні через новий API
- Значні зміни у flowcontrol.apiserver.k8s.io/v1:
- Поле
spec.limited.nominalConcurrencyShares
PriorityLevelConfiguration має стандартне значення 30, коли не вказане, і явне значення 0 не змінюється на 30.
v1.29
У випуску v1.29 перестали обслуговуватися наступні застарілі версії API:
Ресурси контролю потоку
Версія API flowcontrol.apiserver.k8s.io/v1beta2 FlowSchema та PriorityLevelConfiguration більше не обслуговується з версії v1.29.
- Перенесіть маніфести та клієнти API на використання версії API flowcontrol.apiserver.k8s.io/v1, доступної з версії v1.29, або версії API flowcontrol.apiserver.k8s.io/v1beta3, доступної з версії v1.26.
- Усі наявні збережені обʼєкти доступні через новий API
- Значні зміни в flowcontrol.apiserver.k8s.io/v1:
- Поле
spec.limited.assuredConcurrencyShares
PriorityLevelConfiguration перейменоване на spec.limited.nominalConcurrencyShares
і має стандартне значення 30, коли не вказане, і явне значення 0 не змінюється на 30.
- Значні зміни в flowcontrol.apiserver.k8s.io/v1beta3:
- Поле
spec.limited.assuredConcurrencyShares
PriorityLevelConfiguration перейменоване на spec.limited.nominalConcurrencyShares
v1.27
Випуск v1.27 припинив обслуговування наступних застарілих версій API:
CSIStorageCapacity
Версія API CSIStorageCapacity storage.k8s.io/v1beta1 більше не обслуговується з версії v1.27.
- Перенесіть маніфести та клієнти API на версію API storage.k8s.io/v1, доступну з версії v1.24.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Немає помітних змін
v1.26
Випуск v1.26 припинив обслуговування наступних застарілих версій API:
Ресурси керування потоком
Версія API FlowSchema та PriorityLevelConfiguration flowcontrol.apiserver.k8s.io/v1beta1 більше не обслуговується з версії v1.26.
- Перенесіть маніфести та клієнти API на версію API flowcontrol.apiserver.k8s.io/v1beta2.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Немає помітних змін
HorizontalPodAutoscaler
Версія API HorizontalPodAutoscaler autoscaling/v2beta2 більше не обслуговується з версії v1.26.
- Перенесіть маніфести та клієнти API на версію API autoscaling/v2, доступну з версії v1.23.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Помітні зміни:
v1.25
Випуск v1.25 припинив обслуговування наступних застарілих версій API:
CronJob
Версія API CronJob batch/v1beta1 більше не обслуговується з версії v1.25.
- Перенесіть маніфести та клієнти API на версію API batch/v1, доступну з версії v1.21.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Немає помітних змін
EndpointSlice
Версія API EndpointSlice discovery.k8s.io/v1beta1 більше не обслуговується з версії v1.25.
- Перенесіть маніфести та клієнти API на версію API discovery.k8s.io/v1, доступну з версії v1.21.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Помітні зміни в discovery.k8s.io/v1:
- використовуйте поле
nodeName
для кожного Endpoint замість застарілого поля topology["kubernetes.io/hostname"]
- використовуйте поле
zone
для кожного Endpoint замість застарілого поля topology["topology.kubernetes.io/zone"]
topology
замінено полем deprecatedTopology
, яке не доступне для запису у v1
Event
Версія API Event events.k8s.io/v1beta1 більше не обслуговується з версії v1.25.
- Перенесіть маніфести та клієнти API на версію API events.k8s.io/v1, доступну з версії v1.19.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Помітні зміни в events.k8s.io/v1:
type
обмежено до Normal
та Warning
involvedObject
перейменовано в regarding
action
, reason
, reportingController
та reportingInstance
є обовʼязковими при створенні нових events.k8s.io/v1 Events- використовуйте
eventTime
замість застарілого поля firstTimestamp
(яке перейменовано в deprecatedFirstTimestamp
та не допускається в нових events.k8s.io/v1 Events) - використовуйте
series.lastObservedTime
замість застарілого поля lastTimestamp
(яке перейменовано в deprecatedLastTimestamp
та не допускається в нових **events.k8ерсіях API events.k8s.io/v1 Events) - використовуйте
series.count
замість застарілого поля count
(яке перейменовано в deprecatedCount
та не допускається в нових events.k8s.io/v1 Events) - використовуйте
reportingController
замість застарілого поля source.component
(яке перейменовано в deprecatedSource.component
та не допускається в нових events.k8s.io/v1 Events) - використовуйте
reportingInstance
замість застарілого поля source.host
(яке перейменовано в deprecatedSource.host
та не допускається в нових events.k8s.io/v1 Events)
HorizontalPodAutoscaler
Версія API HorizontalPodAutoscaler autoscaling/v2beta1 більше не обслуговується з версії v1.25.
- Перенесіть маніфести та клієнти API на версію API autoscaling/v2, доступну з версії v1.23.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Помітні зміни:
PodDisruptionBudget
Версія API PodDisruptionBudget policy/v1beta1 більше не обслуговується з версії v1.25.
- Перенесіть маніфести та клієнти API на версію API policy/v1, доступну з версії v1.21.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Помітні зміни в policy/v1:
- пустий
spec.selector
({}
), записаний до policy/v1
PodDisruptionBudget, вибирає всі теки в просторі імен (у policy/v1beta1
пустий spec.selector
не вибирав жодні теки). Неустановлений spec.selector
вибирає жодні теки в обох версіях API.
PodSecurityPolicy
PodSecurityPolicy в версії API policy/v1beta1 більше не обслуговується з версії v1.25, і контролер допуску PodSecurityPolicy буде видалено.
Перейдіть до Pod Security Admission або виклику стороннього вебхуку допуску. Для настанов з міграції, див. Міграція з PodSecurityPolicy до вбудованого контролера допуску PodSecurity Admission Controller. Для отримання додаткової інформації про застарілість, див. ВPodSecurityPolicy Deprecation: Past, Present, and Future.
RuntimeClass
RuntimeClass в версії API node.k8s.io/v1beta1 більше не обслуговується з версії v1.25.
- Перенесіть маніфести та клієнти API на версію API node.k8s.io/v1, доступну з версії v1.20.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Немає помітних змін
v1.22
Випуск v1.22 припинив обслуговування наступних застарілих версій API:
Ресурси вебхуків
Версія API admissionregistration.k8s.io/v1beta1 для MutatingWebhookConfiguration та ValidatingWebhookConfiguration більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API admissionregistration.k8s.io/v1, доступну з версії v1.16.
- Усі наявні обʼєкти, які зберігаються, доступні через нові API
- Помітні зміни:
- стандартно
webhooks[*].failurePolicy
змінено з Ignore
на Fail
для v1 - стандартно
webhooks[*].matchPolicy
змінено з Exact
на Equivalent
для v1 - стандартно
webhooks[*].timeoutSeconds
змінено з 30s
на 10s
для v1 - поле
webhooks[*].sideEffects
стандартно видалено, і тепер воно обовʼязкове,
і дозволяється лише None
та NoneOnDryRun
для v1 - стандартно видалено значення поля
webhooks[*].admissionReviewVersions
та робиться обовʼязковим для v1 (підтримувані версії для AdmissionReview - v1
та v1beta1
) - поле
webhooks[*].name
повинно бути унікальним в списку для обʼєктів, створених через admissionregistration.k8s.io/v1
CustomResourceDefinition
Версія API apiextensions.k8s.io/v1beta1 для CustomResourceDefinition більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API apiextensions.k8s.io/v1, доступну з версії v1.16.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Помітні зміни:
- поле
spec.scope
тепер не має станадртного значення Namespaced
і повинно бути явно вказано - поле
spec.version
вилучено в v1; використовуйте замість цього spec.versions
- поле
spec.validation
вилучено в v1; використовуйте замість цього spec.versions[*].schema
- поле
spec.subresources
вилучено в v1; використовуйте замість цього spec.versions[*].subresources
- поле
spec.additionalPrinterColumns
вилучено в v1; використовуйте замість цього spec.versions[*].additionalPrinterColumns
spec.conversion.webhookClientConfig
переміщено в spec.conversion.webhook.clientConfig
в v1spec.conversion.conversionReviewVersions
переміщено в spec.conversion.webhook.conversionReviewVersions
в v1- поле
spec.versions[*].schema.openAPIV3Schema
тепер обовʼязкове при створенні обʼєктів CustomResourceDefinition для v1, і повинно бути структурною схемою spec.preserveUnknownFields: true
заборонено при створенні обʼєктів CustomResourceDefinition для v1; воно повинно бути вказано у визначеннях схем як x-kubernetes-preserve-unknown-fields: true
- В елементах
additionalPrinterColumns
поле JSONPath
перейменовано в jsonPath
в v1
(виправлення #66531)
APIService
Версія API apiregistration.k8s.io/v1beta1 для APIService більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API apiregistration.k8s.io/v1, доступну з версії v1.10.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Немає помітних змін
TokenReview
Версія API authentication.k8s.io/v1beta1 для TokenReview більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API authentication.k8s.io/v1, доступну з версії v1.6.
- Немає помітних змін
Ресурси SubjectAccessReview
Версія API authorization.k8s.io/v1beta1 для LocalSubjectAccessReview, SelfSubjectAccessReview, SubjectAccessReview та SelfSubjectRulesReview більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API authorization.k8s.io/v1, доступну з версії v1.6.
- Помітні зміни:
- Поле
spec.group
перейменовано на spec.groups
в v1 (виправляє #32709)
CertificateSigningRequest
Версія API certificates.k8s.io/v1beta1 для CertificateSigningRequest більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API certificates.k8s.io/v1, доступну з версії v1.19.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Помітні зміни в
certificates.k8s.io/v1
:- Для API-клієнтів, що запитують сертифікати:
- Поле
spec.signerName
тепер обовʼязкове
(див. відомі підписувачи Kubernetes), і запити на kubernetes.io/legacy-unknown
не дозволяються бути створеними через API certificates.k8s.io/v1
- Поле
spec.usages
тепер обовʼязкове, не може містити дубльованих значень та повинно містити лише відомі використання
- Для API-клієнтів, що схвалюють або підписують сертифікати:
status.conditions
не може містити дублюються типиstatus.conditions[*].status
тепер обовʼязковеstatus.certificate
повинно бути в кодуванні PEM та містити лише блоки CERTIFICATE
Lease
Версія API coordination.k8s.io/v1beta1 для Lease більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API coordination.k8s.io/v1, доступну з версії v1.14.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Немає помітних змін
Ingress
Версії API extensions/v1beta1 та networking.k8s.io/v1beta1 для Ingress більше не обслуговуються з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API networking.k8s.io/v1, доступну з версії v1.19.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Помітні зміни:
- Поле
spec.backend
перейменовано на spec.defaultBackend
- Поле
serviceName
бекенду перейменовано на service.name
- Числові поля
servicePort
бекенду перейменовані на service.port.number
- Рядкові поля
servicePort
бекенду перейменовані на service.port.name
pathType
тепер обовʼязковий для кожного вказаного шляху. Варіанти — Prefix
, Exact
, та ImplementationSpecific
. Для відповідності невизначеній поведінці v1beta1
використовуйте ImplementationSpecific
.
IngressClass
Версія API networking.k8s.io/v1beta1 для IngressClass більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API networking.k8s.io/v1, доступну з версії v1.19.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API
- Немає помітних змін
Ресурси RBAC
Версія API rbac.authorization.k8s.io/v1beta1 для ClusterRole, ClusterRoleBinding,
Role та RoleBinding більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API rbac.authorization.k8s.io/v1, доступну з версії v1.8.
- Усі наявні обʼєкти, які зберігаються, доступні через нові API
- Немає помітних змін
PriorityClass
Версія API scheduling.k8s.io/v1beta1 для PriorityClass більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API scheduling.k8s.io/v1, доступну з версії v1.14.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API.
- Немає помітних змін.
Ресурси зберігання
Версія API storage.k8s.io/v1beta1 для CSIDriver, CSINode, StorageClass та VolumeAttachment більше не обслуговується з версії v1.22.
- Перенесіть маніфести та клієнти API на версію API storage.k8s.io/v1
- CSIDriver доступний у storage.k8s.io/v1 починаючи з версії v1.19.
- CSINode доступний у storage.k8s.io/v1 починаючи з версії v1.17.
- StorageClass доступний у storage.k8s.io/v1 починаючи з версії v1.6.
- VolumeAttachment доступний у storage.k8s.io/v1 з версії v1.13.
- Усі наявні обʼєкти, які зберігаються, доступні через нові API.
- Немає помітних змін.
v1.16
Випуск v1.16 припинив обслуговування наступних застарілих версій API:
Мережева політика
Версія API extensions/v1beta1 для NetworkPolicy більше не обслуговується з версії v1.16.
- Перенесіть маніфести та клієнти API на версію API networking.k8s.io/v1, доступну з версії v1.8.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API.
DaemonSet
Версії API extensions/v1beta1 та apps/v1beta2 для DaemonSet більше не обслуговуються з версії v1.16.
- Перенесіть маніфести та клієнти API на версію API apps/v1, доступну з версії v1.9.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API.
- Помітні зміни:
spec.templateGeneration
видалено.spec.selector
тепер є обовʼязковим і незмінним після створення; використовуйте наявні мітки шаблону як селектор для безшовного оновлення.spec.updateStrategy.type
тепер стандартно встановлено на RollingUpdate
(стандартно в extensions/v1beta1
було OnDelete
).
Deployment
Версії API extensions/v1beta1, apps/v1beta1 та apps/v1beta2 для Deployment більше не обслуговуються з версії v1.16.
- Перенесіть маніфести та клієнти API на версію API apps/v1, доступну з версії v1.9.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API.
- Помітні зміни:
spec.rollbackTo
видалено.spec.selector
тепер є обовʼязковим і незмінним після створення; використовуйте наявні мітки шаблону як селектор для безшовного оновлення.spec.progressDeadlineSeconds
тепер стандартно встановлено на 600
секунд
(стандартно в extensions/v1beta1
було без крайнього терміну).spec.revisionHistoryLimit
тепер стандартно встановлено на 10
(стандартно в apps/v1beta1
було 2
, стандартно в extensions/v1beta1
було зберігати всі).maxSurge
та maxUnavailable
тепер стандартно встановлено на 25%
(стандартно в extensions/v1beta1
було 1
).
StatefulSet
Версії API apps/v1beta1 та apps/v1beta2 для StatefulSet більше не обслуговуються з версії v1.16.
- Перенесіть маніфести та клієнти API на версію API apps/v1, доступну з версії v1.9.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API.
- Помітні зміни:
spec.selector
тепер є обовʼязковим і незмінним після створення; використовуйте наявні мітки шаблону як селектор для безшовного оновлення.spec.updateStrategy.type
тепер за замовчуванням встановлено на RollingUpdate
(стандартно в apps/v1beta1
було OnDelete
).
ReplicaSet
Версії API extensions/v1beta1, apps/v1beta1 та apps/v1beta2 для ReplicaSet більше не обслуговуються з версії v1.16.
- Перенесіть маніфести та клієнти API на версію API apps/v1, доступну з версії v1.9.
- Усі наявні обʼєкти, які зберігаються, доступні через новий API.
- Помітні зміни:
spec.selector
тепер є обовʼязковим і незмінним після створення; використовуйте наявні мітки шаблону як селектор для безшовного оновлення.
PodSecurityPolicy
Версія API extensions/v1beta1 для PodSecurityPolicy більше не обслуговується з версії v1.16.
- Перенесіть маніфести та клієнти API на версію API policy/v1beta1, доступну з версії v1.10.
- Зауважте, що версія API policy/v1beta1 для PodSecurityPolicy буде видалена у версії v1.25.
Що робити
Тестування з вимкненими застарілими API
Ви можете протестувати свої кластери, запустивши API сервер зі конкретними вимкненими версіями API, щоб змоделювати майбутні видалення. Додайте наступний прапорець до аргументів запуску API сервера:
--runtime-config=<group>/<version>=false
Наприклад:
--runtime-config=admissionregistration.k8s.io/v1beta1=false,apiextensions.k8s.io/v1beta1,...
Пошук використання застарілих API
Використовуйте попередження клієнтів, метрики та інформацію аудиту, доступні в версії 1.19+ для визначення використання застарілих API.
Перехід на незастарілі API
Оновіть власні інтеграції та контролери, щоб викликати незастарілі API.
Змініть YAML файли, щоб вони посилалися на незастарілі API.
Ви можете використовувати команду kubectl convert
для автоматичного перетворення наявного обʼєкта:
kubectl convert -f <file> --output-version <group>/<version>
.
Наприклад, щоб перетворити старий Deployment на apps/v1
, ви можете виконати:
kubectl convert -f ./my-deployment.yaml --output-version apps/v1
Це перетворення може використовувати не ідеальні стандартні значення. Щоб дізнатися більше про конкретний ресурс, зверніться до довідника API Kubernetes.
Примітка:
Інструмент kubectl convert
не стандартно встановлюється, хоча раніше він був частиною самого kubectl
. Для отримання додаткової інформації ви можете прочитати питання про застарілість та видалення для вбудованої підкоманди.
Щоб дізнатися, як налаштувати kubectl convert
на вашому компʼютері, відвідайте сторінку, яка відповідає вашій операційній системі:
Linux,
macOS або
Windows.
7 - Точки доступу для моніторингу стану API Kubernetes
API сервер Kubernetes надає точки доступу API для індикації поточного стану API сервера. Ця сторінка описує ці точки доступу API та пояснює, як ви можете їх використовувати.
Точки доступу API для моніторингу стану
API сервер Kubernetes надає 3 точки доступу API (healthz
, livez
і readyz
) для індикації поточного стану API сервера. Точка доступу healthz
є застарілою (з Kubernetes v1.16), і ви повинні використовувати більш конкретні точки доступу livez
та readyz
. Точку доступу livez
можна використовувати з прапорцем --livez-grace-period
, щоб вказати тривалість запуску. Для належного завершення роботи ви можете вказати прапорець --shutdown-delay-duration
з точкою доступу /readyz
. Машини, що перевіряють healthz
/livez
/readyz
API сервера, повинні покладатися на HTTP-код статусу. Код статусу 200
вказує, що API сервер є healthy
/live
/ready
, залежно від викликаної точки доступу. Більш докладні опції, показані нижче, призначені для використання людьми-операторами для налагодження їх кластера або розуміння стану API сервера.
Наступні приклади покажуть, як ви можете взаємодіяти з точками доступу моніторингу стану API.
Для всіх точок доступу ви можете використовувати параметр verbose
, щоб вивести перевірки та їхній стан. Це може бути корисно для оператора-людини для налагодження поточного стану API сервера, це не призначено для використання машинами:
curl -k https://localhost:6443/livez?verbose
або з віддаленого хосту з автентифікацією:
kubectl get --raw='/readyz?verbose'
Вивід буде виглядати наступним чином:
[+]ping ok
[+]log ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
healthz check passed
API сервер Kubernetes також підтримує виключення конкретних перевірок. Параметри запиту також можна комбінувати, як у цьому прикладі:
curl -k 'https://localhost:6443/readyz?verbose&exclude=etcd'
Вивід показує, що перевірка etcd
виключено:
[+]ping ok
[+]log ok
[+]etcd excluded: ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
[+]shutdown ok
healthz check passed
Індивідуальні перевірки стану
СТАН ФУНКЦІОНАЛУ: Kubernetes v1.30 [alpha]
Кожна індивідуальна перевірка стану надає HTTP точку доступу і може бути перевірена індивідуально. Схема для індивідуальних перевірок стану — /livez/<healthcheck-name>
або /readyz/<healthcheck-name>
, де livez
і readyz
можуть бути використані для індикації, чи ви хочете перевірити liveness або readiness API сервера відповідно. Шлях <healthcheck-name>
можна знайти, використовуючи прапорець verbose
вище та шлях між [+]
та ok
. Ці індивідуальні перевірки стану не повинні використовуватися машинами, але можуть бути корисні для оператора-людини для налагодження системи:
curl -k https://localhost:6443/livez/etcd