На цій сторінці наведено рекомендації та міркування щодо проєктування вебхуків допуску в Kubernetes. Ця інформація призначена для операторів кластерів, які запускають сервери вебхуків допуску або сторонні застосунки, що змінюють або перевіряють ваші API-запити.
Перед читанням цієї сторінки переконайтеся, що ви знайомі з такими поняттями:
Контроль допуску відбувається, коли до API Kubernetes надсилається будь-який запит на створення, оновлення або видалення. Контролери допуску перехоплюють запити, що відповідають визначеним вами критеріям. Потім ці запити надсилаються до змінювальних або валідаційних вебхуків допуску. Такі вебхуки часто пишуть, щоб переконатися, що певні поля в специфікаціях обʼєктів існують або мають певні дозволені значення.
Вебхуки — це потужний механізм розширення API Kubernetes. Погано спроєктовані вебхуки часто спричиняють порушення роботи робочих навантажень, оскільки вебхуки мають великий контроль над обʼєктами в кластері. Як і інші механізми розширення API, вебхуки складно тестувати у великому масштабі на сумісність з усіма вашими робочими навантаженнями, іншими вебхуками, надбудовами та втулками.
Крім того, з кожним випуском Kubernetes додає або змінює API: зʼявляються нові можливості, можливості переходять на стадію бета чи стабільну, деякі застарівають. Навіть стабільні API Kubernetes можуть змінюватися. Наприклад, API Pod змінився у v1.29, щоб додати можливість sidecar-контейнерів. Хоча обʼєкт Kubernetes рідко стає несправним через новий API Kubernetes, вебхуки, які очікувано працювали з попередніми версіями API, можуть не впоратися з новішими змінами цього API. Це може призвести до неочікуваної поведінки після оновлення кластерів до новіших версій.
На цій сторінці описано поширені сценарії збоїв вебхуків і те, як уникнути їх завдяки обережному та продуманому проєктуванню й реалізації ваших вебхуків.
Навіть якщо ви не запускаєте власні вебхуки допуску, деякі сторонні застосунки, які ви запускаєте у своїх кластерах, можуть використовувати змінювальні або валідаційні вебхуки допуску.
Щоб перевірити, чи є у вашому кластері змінювальні вебхуки допуску, виконайте таку команду:
kubectl get mutatingwebhookconfigurations
У виводі буде перелічено всі змінювальні контролери допуску в кластері.
Щоб перевірити, чи є у вашому кластері валідаційні вебхуки допуску, виконайте таку команду:
kubectl get validatingwebhookconfigurations
У виводі буде перелічено всі валідаційні контролери допуску в кластері.
Kubernetes пропонує кілька варіантів контролю допуску та застосування політик. Розуміння того, коли використовувати конкретний варіант, допоможе покращити затримку та продуктивність, зменшити накладні витрати на керування й уникнути проблем під час оновлення версій. У наведеній нижче таблиці описано механізми, які дозволяють змінювати або перевіряти ресурси під час допуску:
| Механізм | Опис | Сценарії використання |
|---|---|---|
| Змінювальний вебхук допуску | Перехоплює API-запити перед допуском і за потреби змінює їх за допомогою власної логіки. |
|
| Змінювальна політика допуску | Перехоплює API-запити перед допуском і за потреби змінює їх за допомогою виразів Common Expression Language (CEL). |
|
| Валідаційний вебхук допуску | Перехоплює API-запити перед допуском і перевіряє їх на відповідність складним визначенням політик. |
|
| Валідаційна політика допуску | Перехоплює API-запити перед допуском і перевіряє їх на відповідність виразам CEL. |
|
Загалом використовуйте контроль допуску на основі вебхуків, коли вам потрібен розширюваний спосіб оголошення або налаштування логіки. Використовуйте вбудований контроль допуску на основі CEL, коли потрібно оголосити простішу логіку без накладних витрат на роботу сервера вебхуків. Проєкт Kubernetes рекомендує за можливості використовувати контроль допуску на основі CEL.
Якщо ви використовуєте CustomResourceDefinitions, не використовуйте вебхуки допуску для перевірки значень у специфікаціях CustomResource або для встановлення стандартних значень для полів. Kubernetes дозволяє вам визначати правила перевірки та стандартні значення полів під час створення CustomResourceDefinitions.
Щоб дізнатися більше, дивіться такі ресурси:
У цьому розділі описано рекомендації щодо покращення продуктивності та зменшення затримки. Стисло вони такі:
Змінювальні вебхуки допуску викликаються послідовно. Залежно від налаштування змінювальних вебхуків деякі з них можуть викликатися кілька разів. Кожен виклик змінювального вебхука додає затримку до процесу допуску. На відміну від них, валідаційні вебхуки викликаються паралельно.
Під час проєктування змінювальних вебхуків враховуйте ваші вимоги до затримки та її допустимий рівень. Чим більше змінювальних вебхуків у вашому кластері, тим більша ймовірність зростання затримки.
Щоб зменшити затримку, зверніть увагу на таке:
Враховуйте будь-які інші компоненти у вашому кластері, які можуть конфліктувати зі змінами, що їх вносить ваш вебхук. Наприклад, якщо ваш вебхук додає мітку, яку видаляє інший контролер, ваш вебхук викликається знову. Це призводить до циклу.
Щоб виявити такі цикли, спробуйте таке:
Оновіть політику аудиту вашого кластера, щоб записувати події аудиту. Використовуйте такі параметри:
level: RequestResponseverbs: ["patch"]omitStages: RequestReceivedНалаштуйте правило аудиту так, щоб створювати події для конкретних ресурсів, які змінює ваш вебхук.
Перевірте події аудиту: чи вебхуки повторно викликаються кілька разів із застосуванням того самого патча до того самого обʼєкта, чи поле обʼєкта кілька разів оновлюється й повертається назад.
Вебхуки допуску мають виконуватися якомога швидше (зазвичай за мілісекунди), оскільки вони збільшують затримку API-запитів. Використовуйте для вебхуків невеликий тайм-аут.
Докладніше дивіться в розділі Тайм-аути.
Вебхуки допуску мають використовувати певну форму балансування навантаження для високої доступності та кращої продуктивності. Якщо вебхук працює всередині кластера, ви можете запустити кілька бекендів вебхука за Service типу ClusterIP.
Під час проєктування вебхука враховуйте вимоги до доступності вашого кластера. Наприклад, під час простою вузлів або збоїв у зонах Kubernetes позначає Podʼи як NotReady, щоб балансувальники навантаження могли перенаправити трафік до доступних зон і вузлів. Ці оновлення Podʼів можуть викликати ваші змінювальні вебхуки. Залежно від кількості задіяних Podʼів сервер змінювального вебхука може перевищити тайм-аут або спричинити затримки в обробці Podʼів. Унаслідок цього трафік не буде перенаправлено так швидко, як потрібно.
Враховуйте ситуації, подібні до наведеного прикладу, під час створення ваших вебхуків. Виключайте операції, які є результатом реакції Kubernetes на неминучі інциденти.
У цьому розділі наведено рекомендації щодо фільтрації запитів, які викликають конкретні вебхуки. Стисло вони такі:
Вебхуки допуску викликаються лише тоді, коли API-запит відповідає конфігурації вебхука. Обмежте область дії кожного вебхука, щоб зменшити кількість непотрібних викликів до сервера вебхука. Зверніть увагу на такі обмеження області дії:
kube-system. Якщо ви запускаєте власні Podʼи в просторі імен kube-system, використовуйте objectSelector, щоб не змінити критичне робоче навантаження.kube-node-lease. Зміна Lease вузлів може призвести до невдалих оновлень вузлів. Застосовуйте валідаційний контроль до обʼєктів Lease у цьому просторі імен, лише якщо ви впевнені, що він не поставить ваш кластер під загрозу.namespaceSelector.Контролери допуску підтримують кілька полів, за допомогою яких можна зіставляти запити, що відповідають певним критеріям. Наприклад, ви можете використовувати namespaceSelector, щоб відбирати запити, спрямовані на конкретний простір імен.
Для точнішої фільтрації запитів використовуйте поле matchConditions у конфігурації вебхука. Це поле дозволяє написати кілька виразів CEL, які мають повертати true, щоб запит викликав ваш вебхук допуску. Використання matchConditions може значно зменшити кількість викликів до вашого сервера вебхука.
Докладніше дивіться в розділі Зіставлення запитів: matchConditions.
Стандартно вебхуки допуску працюють для будь-яких версій API, які стосуються вказаного ресурсу. Цією поведінкою керує поле matchPolicy у конфігурації вебхука. Вкажіть значення Equivalent у полі matchPolicy або пропустіть це поле, щоб вебхук працював для будь-якої версії API.
Докладніше дивіться в розділі Зіставлення запитів: matchPolicy.
У цьому розділі наведено рекомендації щодо області дії змін та особливостей полів обʼєктів. Стисло вони такі:
Сервери вебхуків допуску надсилають HTTP-відповіді, які вказують, що робити з конкретним запитом до API Kubernetes. Така відповідь є обʼєктом AdmissionReview. Змінювальний вебхук може додати конкретні поля для зміни перед дозволом допуску за допомогою полів patchType та patch у відповіді. Переконайтеся, що ви змінюєте лише ті поля, які потребують змін.
Наприклад, розгляньмо змінювальний вебхук, налаштований так, щоб Deployments web-server мали щонайменше три репліки. Коли запит на створення обʼєкта Deployment відповідає конфігурації вашого вебхука, вебхук має оновити лише значення поля spec.replicas.
Поля у специфікаціях обʼєктів Kubernetes можуть містити масиви. Деякі масиви містять пари ключ:значення (наприклад, поле envVar у специфікації контейнера), тоді як інші масиви не мають ключів (наприклад, поле readinessGates у специфікації Pod). Порядок значень у полі масиву може бути важливим в деяких ситуаціях. Наприклад, порядок аргументів у полі args специфікації контейнера може впливати на контейнер.
Під час зміни масивів враховуйте таке:
add замість replace, щоб випадково не замінити потрібне значення.Переконайтеся, що ваші вебхуки працюють лише з вмістом надісланого їм AdmissionReview і не вносять сторонніх змін. Такі додаткові зміни, які називають побічними ефектами, можуть спричинити конфлікти під час допуску, якщо їх належним чином не узгодити. Якщо вебхук не має побічних ефектів, поле .webhooks[].sideEffects слід встановити в None.
Якщо побічні ефекти потрібні під час оцінювання допуску, їх слід придушувати під час обробки обʼєкта AdmissionReview, у якому dryRun має значення true, а поле .webhooks[].sideEffects слід встановити в NoneOnDryRun.
Докладніше дивіться в розділі Побічні ефекти.
Вебхук, що працює всередині кластера, може спричинити взаємоблокування власного розгортання, якщо його налаштовано перехоплювати ресурси, потрібні для запуску його власних Podʼів.
Наприклад, змінювальний вебхук допуску налаштовано так, щоб допускати запити create для Pod, лише якщо в Pod встановлено певну мітку (наприклад, env: prod). Сервер вебхука працює в Deployment, який не встановлює мітку env.
Коли вузол, на якому працюють Podʼи сервера вебхука, стає несправним, Deployment вебхука намагається перепланувати Podʼи на інший вузол. Однак наявний сервер вебхука відхиляє запити, оскільки мітку env не встановлено. Унаслідок цього міграція не може відбутися.
Виключіть простір імен, де працює ваш вебхук, за допомогою namespaceSelector.
Цикли залежностей можуть виникати у таких сценаріях:
Щоб уникнути таких циклів залежностей, спробуйте таке:
objectSelector.Змінювальні вебхуки допуску підтримують поле конфігурації failurePolicy. Це поле вказує, чи повинен API-сервер допустити або відхилити запит у разі збою вебхука. Збої вебхука можуть статися через тайм-аути або помилки у логіці сервера.
Стандартно вебхуки допуску встановлюють поле failurePolicy у Fail. API-сервер відхиляє запит, якщо вебхук зазнає збою. Однак таке стандартне відхилення може призвести до відхилення запитів, що відповідають вимогам, під час простою вебхука.
Дозвольте вашим змінювальним вебхукам «fail open», встановивши поле failurePolicy в Ignore. Використовуйте валідаційний контролер, щоб перевіряти стан запитів і переконуватися, що вони відповідають вашим політикам.
Цей підхід має такі переваги:
Загалом проєктуйте свої вебхуки з припущенням, що API Kubernetes можуть змінитися в наступній версії. Не пишіть сервер, який вважає стабільність API чимось гарантованим. Наприклад, випуск sidecar-контейнерів у Kubernetes додав поле restartPolicy до API Pod.
Змінювальні вебхуки, які реагують на широкий спектр API-запитів, можуть ненавмисно викликати самі себе. Наприклад, розгляньмо вебхук, який реагує на всі запити в кластері. Якщо налаштувати вебхук на створення обʼєктів Event для кожної зміни, він реагуватиме на власні запити на створення обʼєктів Event.
Щоб уникнути цього, встановлюйте унікальну мітку на всі ресурси, які створює ваш вебхук. Виключіть цю мітку з умов зіставлення вашого вебхука.
Деякі обʼєкти Kubernetes в API-сервері не можуть змінюватися. Наприклад, коли ви розгортаєте статичний Pod, kubelet на вузлі створює в API-сервері дзеркальний Pod для відстеження статичного Podʼа. Однак зміни дзеркального Podʼа не поширюються на статичний Pod.
Не намагайтеся змінювати ці обʼєкти під час допуску. Усі дзеркальні Podʼи мають анотацію kubernetes.io/config.mirror. Щоб виключити дзеркальні Podʼи й водночас зменшити ризик безпеки від ігнорування анотації, дозволяйте статичним Podʼам працювати лише в конкретних просторах імен.
У цьому розділі наведено рекомендації щодо порядку виклику вебхуків і проєктування ідемпотентних вебхуків. Стисло вони такі:
Змінювальні вебхуки допуску не виконуються в стабільному порядку. Момент виклику конкретного вебхука може залежати від різних чинників. Не покладайтеся на те, що ваш вебхук виконається в певний момент процесу допуску. Інші вебхуки все ще можуть змінити ваш змінений обʼєкт.
Наведені нижче рекомендації можуть допомогти мінімізувати ризик ненавмисних змін:
Кожен змінювальний вебхук допуску має бути ідемпотентним. Вебхук має бути здатним працювати з обʼєктом, який він уже змінив, не вносячи додаткових змін, окрім початкової.
Крім того, усі змінювальні вебхуки у вашому кластері мають бути ідемпотентними як сукупність. Після завершення фази змін контролю допуску кожен окремий змінювальний вебхук має бути здатним працювати з обʼєктом, не вносячи до нього додаткових змін.
Залежно від вашого середовища забезпечити ідемпотентність у великому масштабі може бути складно. Можуть допомогти такі рекомендації:
У наведених нижче прикладах показано ідемпотентну логіку змін:
Для запиту create Pod встановіть поле .spec.securityContext.runAsNonRoot Pod у true.
Для запиту create Pod, якщо поле .spec.containers[].resources.limits контейнера не встановлено, встановіть стандартні обмеження ресурсів.
Для запиту create Pod додайте sidecar-контейнер із назвою foo-sidecar, якщо контейнера з назвою foo-sidecar ще немає.
У цих випадках вебхук можна безпечно викликати повторно, і він може допустити обʼєкт, у якому ці поля вже встановлено.
У наведених нижче прикладах показано неідемпотентну логіку змін:
Для запиту create Pod додайте sidecar-контейнер із назвою foo-sidecar і суфіксом із поточною позначкою часу (наприклад, foo-sidecar-19700101-000000).
Повторний виклик вебхука може призвести до того, що той самий sidecar буде додано до Podʼа кілька разів, щоразу з іншою назвою контейнера. Так само вебхук може додати дубльовані контейнери, якщо sidecar уже є в Podʼі, наданому користувачем.
Для запиту create/update Pod відхиліть запит, якщо Pod має мітку env, інакше додайте до Pod мітку env: prod.
Повторний виклик вебхука призведе до того, що вебхук завершиться збоєм на власному результаті.
Для запиту create Pod додайте sidecar-контейнер із назвою foo-sidecar без перевірки, чи існує контейнер foo-sidecar.
Повторний виклик вебхука призведе до дублювання контейнерів у Pod, через що запит стане недійсним і API-сервер його відхилить.
У цьому розділі наведено рекомендації щодо тестування змінювальних вебхуків і перевірки змінених обʼєктів. Стисло вони такі:
Ретельне тестування має бути основною частиною вашого циклу випуску нових або оновлених вебхуків. За можливості тестуйте будь-які зміни вебхуків кластера в тестовому середовищі, яке максимально нагадує ваші промислові кластери. Принаймні використовуйте інструмент на кшталт minikube або kind, щоб створити невеликий тестовий кластер для змін вебхуків.
Ваші змінювальні вебхуки не повинні порушувати жодні перевірки, що застосовуються до обʼєкта перед допуском. Наприклад, розгляньмо змінювальний вебхук, який встановлює стандартний запит CPU Podʼа на певне значення. Якщо обмеження CPU цього Podʼа нижче за змінений запит, Pod не пройде допуск.
Тестуйте кожен змінювальний вебхук на відповідність перевіркам, що працюють у вашому кластері.
Перед оновленням промислових кластерів до нової мінорної версії протестуйте свої вебхуки та робочі навантаження в тестовому середовищі. Порівняйте результати, щоб переконатися, що ваші вебхуки й далі працюють очікувано після оновлення.
Крім того, використовуйте такі ресурси, щоб стежити за змінами API:
Змінювальні вебхуки виконуються до завершення перед запуском будь-яких валідаційних вебхуків. Стабільного порядку застосування змін до обʼєктів немає. Унаслідок цього ваші зміни може перезаписати змінювальний вебхук, який виконується пізніше.
Додайте до свого кластера валідаційний контролер допуску, такий як ValidatingAdmissionWebhook або ValidatingAdmissionPolicy, щоб переконатися, що ваші зміни збереглися. Наприклад, розгляньмо змінювальний вебхук, який додає поле restartPolicy: Always до певних init-контейнерів, щоб вони працювали як sidecar-контейнери. Ви можете запустити валідаційний вебхук, щоб переконатися, що ці init-контейнери зберегли конфігурацію restartPolicy: Always після завершення всіх змін.
Докладніше дивіться в таких ресурсах:
У цьому розділі наведено рекомендації щодо розгортання змінювальних вебхуків допуску. Стисло вони такі:
Коли ви будете готові розгорнути змінювальний вебхук у кластері, виконайте дії в такому порядку:
failurePolicy у маніфесті MutatingWebhookConfiguration в Ignore. Це допоможе уникнути порушень через неправильно налаштовані вебхуки.namespaceSelector у маніфесті MutatingWebhookConfiguration на тестовий простір імен.Стежте за вебхуком у тестовому просторі імен, щоб виявити проблеми, а потім розгорніть вебхук в інших просторах імен. Якщо вебхук перехоплює API-запит, який не мав перехоплювати, призупиніть розгортання та скоригуйте область дії конфігурації вебхука.
Змінювальні вебхуки — це потужні контролери Kubernetes. Використовуйте RBAC або інший механізм авторизації, щоб обмежити доступ до конфігурацій і серверів ваших вебхуків. Для RBAC переконайтеся, що такий доступ мають лише довірені субʼєкти:
admissionregistration.k8s.io/v1Якщо сервер вашого змінювального вебхука працює у кластері, обмежте доступ до створення або зміни будь-яких ресурсів у цьому просторі імен.
Наведені нижче проєкти є прикладами «якісних» реалізацій власних серверів вебхуків. Ви можете використовувати їх як відправну точку під час проєктування власних вебхуків. Не використовуйте ці приклади як є; беріть їх за відправну точку й проєктуйте свої вебхуки так, щоб вони добре працювали у вашому конкретному середовищі.
Елементи на цій сторінці відносяться до сторонніх продуктів чи проєктів, які надають функціонал, необхідний для Kubernetes. Автори проєкту Kubernetes не несуть відповідальності за ці проєкти. Ознайомтесь з настановами на вебсайті CNCF для отримання докладної інформації.
Ознайомтесь з посібником з контенту перед тим, як пропонувати додавання посилання на стороні компоненти.