Порушення

Порушення

Цей посібник призначений для власників застосунків, які хочуть створити високодоступні застосунки та, таким чином, повинні розуміти, які типи порушень можуть трапитися з Podʼами.

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

Добровільні та невідворотні порушення

Podʼи не зникають, поки хтось (людина або контролер) не знищить їх, або не трапиться невідворотна помилка обладнання чи системного програмного забезпечення.

Ми називаємо ці невідворотні випадки невідворотними порушеннями застосунку. Приклади:

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

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

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

  • видалення Deployment або іншого контролера, який керує Podʼом
  • оновлення шаблону Podʼа в Deployment, що призводить до перезапуску
  • безпосереднє видалення Podʼа (наприклад, випадково)

Дії адміністратора кластера включають:

  • Очищення вузла для ремонту чи оновлення.
  • Очищення вузла з кластера для зменшення масштабу кластера (дізнайтеся більше про автомасштабування вузлів).
  • Видалення Podʼа з вузла, щоб щось інше помістилося на цей вузол.

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

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

Увага:

Не всі добровільні порушення обмежені бюджетами порушень Podʼів. Наприклад, видалення Deployment чи Pod обходить бюджети порушень Podʼів.

Робота з порушеннями

Ось кілька способів помʼякшення невідворотних порушень:

Частота добровільних порушень різниться. На базовому кластері Kubernetes немає автоматизованих добровільних порушень (тільки ті, які ініціює користувач). Однак адміністратор кластера або провайдер хостингу може запускати деякі додаткові сервіси, які призводять до добровільних порушень. Наприклад, розгортання оновлень програмного забезпечення вузла може призвести до добровільних порушень. Також деякі реалізації автомасштабування кластера (вузла) можуть призводити до добровільних порушень для дефрагментації та ущільнення вузлів. Адміністратор кластера або провайдер хостингу мають задокументувати, якого рівня добровільних порушень, якщо такі є, слід очікувати. Деякі параметри конфігурації, такі як використання PriorityClasses у вашій специфікації Podʼа, також можуть призводити до добровільних (і невідворотних) порушень.

Бюджети порушень Podʼів

СТАН ФУНКЦІОНАЛУ: GA since Kubernetes v1.21

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

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

Менеджери кластерів та провайдери хостингу повинні використовувати інструменти, які дотримуються бюджетів порушень Podʼів, викликаючи Eviction API замість прямого видалення Podʼів або Deployments.

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

PDB визначає кількість реплік, яку застосунок може витримати, порівняно з тим, скільки їх має бути. Наприклад, Deployment, який має .spec.replicas: 5, повинен мати 5 Podʼів в будь-який момент часу. Якщо PDB дозволяє бути 4 Podʼам одночасно, то Eviction API дозволить добровільне порушення роботи одного (але не двох) Podʼів одночасно.

Група Podʼів, з яких складається застосунок, визначається за допомогою селектора міток, такого самого, як і той, який використовується контролером застосунку (deployment, stateful-set тощо).

"Передбачена" кількість Podʼів обчислюється з .spec.replicas ресурсу робочого навантаження, який керує цими Podʼами. Панель управління визначає ресурс робочого навантаження, що володіє Podʼом, оглядаючи .metadata.ownerReferences Podʼа.

Невідворотні порушення неможливо запобігти за допомогою PDB; однак вони враховуються в бюджеті.

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

Рекомендується встановлювати політику виселення несправних Podʼів AlwaysAllow у ваших PodDisruptionBudgets для підтримки виселення застосунків, що працюють неправильно, під час очищення вузла. Стандартно очищення чекає, доки Podʼи застосунку стануть справними, перш ніж продовжитися.

Коли Pod виселяється за допомогою API виселення, він коректно завершується з урахуванням налаштування terminationGracePeriodSeconds його PodSpec.

Приклад PodDisruptionBudget

Припустимо, що у кластері є 3 вузли, від node-1 до node-3. У кластері працює кілька застосунків. Один з них має 3 репліки, які спочатку називаються pod-a, pod-b і pod-c. Також показано інший, не повʼязаний з ними Pod без PDB — pod-x. Спочатку Podʼи розташовані так:

node-1node-2node-3
pod-a доступнийpod-b доступнийpod-c доступний
pod-x доступний

Усі 3 Podʼи є частиною Deployment, і вони разом мають PDB, який вимагає, щоб одночасно було доступними принаймні 2 з 3 Podʼів.

Наприклад, припустимо, що адміністратор кластера хоче перезавантажитися в нову версію ядра, щоб виправити помилку в ядрі. Адміністратор кластера спочатку намагається очистити node-1 за допомогою команди kubectl drain. Цей інструмент намагається виселити pod-a і pod-x. Це вдається негайно. Обидва Podʼи одночасно переходять у стан terminating. Це переводить кластер у стан:

node-1 очищуєтьсяnode-2node-3
pod-a завершуєтьсяpod-b доступнийpod-c доступний
pod-x завершується

Deployment помічає, що один з Podʼів завершується, тому він створює заміну під назвою pod-d. Оскільки node-1 закрито для планування (cordoned), заміна опиняється на іншому вузлі. Також щось створило pod-y як заміну для pod-x.

(Примітка: для StatefulSet, pod-a, який міг би мати назву щось на зразок pod-0, повинен був би повністю завершити свою роботу, перш ніж його заміна, яка також має назву pod-0, але має інший UID, може бути створена. В іншому випадку приклад застосовується і до StatefulSet.)

Тепер кластер перебуває у такому стані:

node-1 очищуєтьсяnode-2node-3
pod-a завершуєтьсяpod-b доступнийpod-c доступний
pod-x завершуєтьсяpod-d запускаєтьсяpod-y

У якийсь момент Podʼи завершують свою роботу, і кластер виглядає так:

node-1 очищенийnode-2node-3
pod-b доступнийpod-c доступний
pod-d запускаєтьсяpod-y

На цьому етапі, якщо нетерплячий адміністратор кластера намагається очистити node-2 або node-3, команда очищення буде заблокована, оскільки доступно тільки 2 Podʼи для Deployment, і його PDB вимагає принаймні 2. Після того, як пройде певний час, pod-d стає доступним.

Тепер стан кластера виглядає так:

node-1 очищенийnode-2node-3
pod-b доступнийpod-c доступний
pod-d доступнийpod-y

Тепер адміністратор кластера намагається очистити node-2. Команда drain спробує виселити два Podʼи в певному порядку, скажімо, спочатку pod-b, а потім pod-d. Їй вдасться виселити pod-b. Але коли вона спробує виселити pod-d, то отримає відмову, через те, що це залишить тільки один доступний Pod для Deployment.

Deployment створює заміну для pod-b з назвою pod-e. Оскільки в кластері недостатньо ресурсів для планування pod-e, очищення знову буде заблоковано. Кластер може опинитися в такому стані:

node-1 очищенийnode-2node-3немає вузла
pod-b завершуєтьсяpod-c доступнийpod-e очікує
pod-d доступнийpod-y

На цьому етапі адміністратор кластера повинен додати вузол назад до кластера, щоб продовжити оновлення.

Ви можете побачити, як Kubernetes змінює частоту випадків порушень відповідно до:

  • скільки реплік потрібно для застосунку
  • скільки часу потрібно для коректного вимкнення екземпляра
  • скільки часу потрібно для запуску нового екземпляра
  • типу контролера
  • місткості ресурсів кластера

Стани порушення роботи Podʼа

This is a stable feature in Kubernetes, and has been since the 1.31 release. You can no longer toggle this feature (the associated feature gate has been removed).

Спеціальний стан Podʼа DisruptionTarget додається для того, щоб вказати, що Pod буде видалено через порушення. Поле reason цього стану додатково вказує одну з таких причин завершення Podʼа:

PreemptionByScheduler
Pod має бути витіснений планувальником, щоб звільнити місце для нового Podʼа з вищим пріоритетом. Докладніше дивіться Витіснення за пріоритетом Podʼа.
DeletionByTaintManager
Pod має бути видалений Менеджером Taint (який є частиною контролера життєвого циклу вузла в kube-controller-manager) через NoExecute taint, який Pod не толерує; див. виселення на основі taint.
EvictionByEvictionAPI
Pod був позначений для виселення за допомогою API Kubernetes.
DeletionByPodGC
Pod, який повʼязаний із вузлом, якого вже не існує, має бути видалений за допомогою збору сміття Podʼів.
TerminationByKubelet
Pod було завершено kubelet через виселення внаслідок тиску на вузол, коректне вимкнення вузла або витіснення заради системно критичних Podʼів.

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

Примітка:

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

Разом з очищенням Podʼів механізм збору сміття Podʼів (PodGC) також позначає їх як невдалі, якщо вони перебувають у нетермінальній фазі (див. також збір сміття Podʼів).

Під час використання Job (або CronJob) ви можете використовувати ці стани порушення роботи Podʼів як частину політики збоїв Podʼа вашого Job.

Розділення ролей власника кластера та власника застосунку

Часто корисно розглядати менеджера кластера і власника застосунку як окремі ролі з обмеженим знанням одне про одного. Це розділення обовʼязків може мати сенс у таких сценаріях:

  • коли багато команд розробки застосунків використовують спільний кластер Kubernetes і є природна спеціалізація ролей
  • коли використовуються інструменти або сервіси сторонніх розробників для автоматизації управління кластером

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

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

Як виконувати дії, що порушують роботу, у вашому кластері

Якщо ви є адміністратором кластера і вам потрібно виконати дію, що порушує роботу, на всіх вузлах вашого кластера, таку як оновлення вузла чи системного програмного забезпечення, ось кілька варіантів:

  • Прийняти простій під час оновлення.
  • Перемикнутися на іншу повну репліку кластера.
    • Відсутність простою, але може бути дорогою як для дубльованих вузлів, так і для зусиль людей для оркестрування перемикання.
  • Розробляти застосунки, стійкі до порушень, і використовувати PDB.
    • Відсутність простою.
    • Мінімальне дублювання ресурсів.
    • Дозволяє більше автоматизації адміністрування кластера.
    • Написання застосунків, стійких до порушень, складне, але робота над стійкістю до добровільних порушень здебільшого збігається з роботою над підтримкою автомасштабування та стійкістю до невідворотних порушень.

Що далі

Змінено November 01, 2026 at 1:20 PM PST: [uk] Use «порушення» for disruption (7a181738e5)