Вимикання вузлів
У кластері Kubernetes вузол може бути вимкнутий плановим відповідним способом або несподівано через такі причини, як відключення електропостачання або інші зовнішні обставини. Вимкнення вузла може призвести до відмови робочого навантаження, якщо вузол не буде виводитись з обслуговування перед вимкненням. Вимкнення вузла може бути відповідним або невідповідним (graceful or non-graceful).
Відповідне вимикання вузла
Kubernetes v1.21 [beta]
(стандартно увімкнено: true)Kubelet намагається виявити вимикання системи вузла та завершує виконання Podʼів на вузлі.
Kubelet забезпечує виконання нормального процесу завершення роботи Podʼа під час вимикання вузла. Під час вимикання вузла kubelet не приймає нові Podʼи (навіть якщо ці Podʼи вже призначені вузлу).
Можливість відповідного вимикання вузла (Graceful node shutdown) залежить від systemd, оскільки вона використовує блокування інгібіторів systemd для затримки вимкнення вузла на певний час.
Вимикання вузла керується функціональною можливістю GracefulNodeShutdown
, що є типово увімкненим з версії 1.21.
Зауважте, що типово обидва налаштування конфігурації, описані нижче, shutdownGracePeriod
та shutdownGracePeriodCriticalPods
, встановлені на нуль, таким чином, не активуючи функціональність відповідного вимикання вузла. Для активації цієї функції, два налаштування конфігурації kubelet повинні бути належним чином налаштовані та встановлені на значення, відмінні від нуля.
Як тільки systemd виявляє або повідомляє про вимикання вузла, kubelet встановлює умову NotReady
на вузлі з причиною "node is shutting down"
. Kube-scheduler дотримується цієї умови та не планує жодних Podʼів на цьому вузлі; очікується, що інші планувальники сторонніх постачальників дотримуватимуться такої ж логіки. Це означає, що нові Podʼи не будуть плануватися на цьому вузлі, і, отже, жоден із них не розпочне роботу.
Kubelet також відхиляє Podʼи під час фази PodAdmission
, якщо виявлено поточне вимикання вузла, так що навіть Podʼи з toleration для node.kubernetes.io/not-ready:NoSchedule
не почнуть виконання там.
Водночас коли kubelet встановлює цю умову на своєму вузлі через API, kubelet також починає завершення будь-яких Podʼів, які виконуються локально.
Під час вимикання kubelet завершує Podʼи у два етапи:
- Завершує роботу звичайних Podʼів, які виконуються на вузлі.
- Завершує роботу критичних Podʼи, які виконуються на вузлі.
Функція відповідного вимикання вузла налаштовується двома параметрами конфігурації kubelet:
shutdownGracePeriod
:- Визначає загальний час, протягом якого вузол повинен затримати вимикання. Це загальний термін допомагає завершити Podʼи як звичайні, так і критичні.
shutdownGracePeriodCriticalPods
:- Визначає термін, який використовується для завершення критичних Podʼів під час вимикання вузла. Це значення повинно бути менше за
shutdownGracePeriod
.
- Визначає термін, який використовується для завершення критичних Podʼів під час вимикання вузла. Це значення повинно бути менше за
Примітка:
Є випадки, коли вимкнення вузла було скасовано системою (або, можливо, вручну адміністратором). У будь-якому з цих випадків вузол повернеться до стануReady
. Однак Podʼи, які вже розпочали процес завершення, не будуть відновлені kubelet і їх потрібно буде перепланувати.Наприклад, якщо shutdownGracePeriod=30s
, а shutdownGracePeriodCriticalPods=10s
, kubelet затримає вимикання вузла на 30 секунд. Під час вимикання перші 20 (30-10) секунд будуть зарезервовані для відповідного завершення звичайних Podʼів, а останні 10 секунд будуть зарезервовані для завершення критичних Podʼів.
Примітка:
Коли Podʼи були виселені під час відповідного вимикання вузла, вони позначаються як вимкнені. Виклик kubectl get pods
показує стан виселених Podʼів як Terminated
. І kubectl describe pod
вказує, що Pod був виселений через вимикання вузла:
Reason: Terminated
Message: Pod was terminated in response to imminent node shutdown.
Відповідне вимикання вузла на основі пріоритету Podʼа
Kubernetes v1.24 [beta]
(стандартно увімкнено: true)Щоб забезпечити більше гнучкості під час відповідного вимикання вузла щодо порядку Podʼів під час вимикання, поступове вимикання вузла враховує PriorityClass для Podʼів, за умови, що ви активували цю функцію у своєму кластері. Функція дозволяє адміністраторам кластера явно визначити порядок Podʼів під час відповідного вимикання вузла на основі priority classes.
Функція відповідного вимикання вузла, яка описана вище, вимикає Podʼи у дві фази: звичайні Podʼи, а потім критичні Podʼи. Якщо потрібна додаткова гнучкість для явного визначення порядку Podʼа під час вимикання в більш деталізований спосіб, можна використовувати відповідне (graceful) вимикання вузла на основі пріоритету Podʼа.
Коли вимикання вузла враховує пріоритет Podʼів, це дозволяє виконувати вимикання вузла у кілька етапів, кожен етап — це завершення роботи Podʼів певного класу пріоритету. Kubelet можна налаштувати з точним числом етапів та часом вимикання для кожного етапу.
Припустимо, що в кластері існують наступні власні класи пріоритету Podʼів:
Назва класу пріоритету Podʼа | Значення класу пріоритету Podʼа |
---|---|
custom-class-a | 100000 |
custom-class-b | 10000 |
custom-class-c | 1000 |
regular/unset | 0 |
В межах конфігурації kubelet налаштування для shutdownGracePeriodByPodPriority
може виглядати так:
Значення класу пріоритету Podʼа | Період вимкнення |
---|---|
100000 | 10 seconds |
10000 | 180 seconds |
1000 | 120 seconds |
0 | 60 seconds |
Відповідна конфігурація YAML kubelet виглядатиме так:
shutdownGracePeriodByPodPriority:
- priority: 100000
shutdownGracePeriodSeconds: 10
- priority: 10000
shutdownGracePeriodSeconds: 180
- priority: 1000
shutdownGracePeriodSeconds: 120
- priority: 0
shutdownGracePeriodSeconds: 60
Вищеописана таблиця означає, що будь-який Pod зі значенням priority
>= 100000 отримає лише 10 секунд на зупинку, будь-який Pod зі значенням >= 10000 і < 100000 отримає 180 секунд для зупинки, будь-який Pod зі значенням >= 1000 і < 10000 отримає 120 секунд для зупинки. Нарешті, всі інші Podʼи отримають 60 секунд для зупинки.
Не обовʼязково вказувати значення, відповідні всім класам. Наприклад, можна використовувати ці налаштування:
Значення класу пріоритету Podʼа | Період вимкнення |
---|---|
100000 | 300 seconds |
1000 | 120 seconds |
0 | 60 seconds |
У вищезазначеному випадку Podʼи з custom-class-b
потраплять в ту ж саму групу, що й custom-class-c
для вимкнення.
Якщо в певному діапазоні відсутні Podʼи, то kubelet не чекатиме на Podʼи у цьому діапазоні пріоритетів. Замість цього, kubelet безпосередньо перейде до наступного діапазону значень пріоритету.
Якщо ця функція увімкнена, а жодна конфігурація не надана, то дії з упорядкування не будуть виконані.
Використання цієї функції передбачає активацію функціональної можливості GracefulNodeShutdownBasedOnPodPriority
, та встановлення ShutdownGracePeriodByPodPriority
в kubelet config до потрібної конфігурації, яка містить значення класу пріоритету Podʼа та відповідні періоди вимкнення.
Примітка:
Можливість враховування пріоритетів Podʼів під час відповідного вимикання вузла була введена як альфа-функція в Kubernetes v1.23. У Kubernetes 1.31 функція є бета-версією та є типово активованою.Метрики graceful_shutdown_start_time_seconds
та graceful_shutdown_end_time_seconds
публікуються у підсистему kubelet для моніторингу вимкнень вузлів.
Обробка невідповідних вимкнень вузлів
Kubernetes v1.28 [stable]
(стандартно увімкнено: true)Дія вимкнення вузла може бути не виявленою Node Shutdown Manager вузла kubelet, чи то через те, що команда не спричинює механізм блокування інгібітора, який використовується kubelet, чи через помилку користувача, тобто ShutdownGracePeriod та ShutdownGracePeriodCriticalPods налаштовані неправильно. Будь ласка, зверніться до вищезазначеної секції Відповідне вимикання вузла для отримання докладнішої інформації.
Коли вузол вимикається, але це не виявляється Node Shutdown Manager вузла kubelet, Podʼи, які є частиною StatefulSet, залишаться в стані завершення на вимкненому вузлі та не зможуть перейти до нового робочого вузла. Це тому, що kubelet на вимкненому вузлі недоступний для видалення Podʼів, і StatefulSet не може створити новий Pod із такою ж назвою. Якщо є томи, які використовуються Podʼами, то VolumeAttachments не буде видалено з оригінального вимкненого вузла, і тому томи використовувані цими Podʼами не можуть бути приєднані до нового робочого вузла. В результаті застосунок, що виконується з StatefulSet, не може працювати належним чином. Якщо оригінальний вимкнений вузол вмикається, Podʼи будуть видалені kubelet, і нові Podʼи будуть створені на іншому робочому вузлі. Якщо оригінальний вимкнений вузол не повертається, ці Podʼи залишаться в стані завершення на вимкненому вузлі назавжди.
Для помʼякшення вищезазначеної ситуації користувач може вручну додати позначку (taint) node.kubernetes.io/out-of-service
з ефектом NoExecute
чи NoSchedule
до вузла, вказавши, що він вийшов із ладу. Якщо у kube-controller-manager увімкнено функціональну можливість NodeOutOfServiceVolumeDetach
, і вузол відзначений як такий, що вийшов з ладу з такою позначкою, Podʼи на вузлі будуть примусово видалені, якщо на них немає відповідних toleration, і операції відʼєднання томів для завершення Podʼів на вузлі відбудуться негайно. Це дозволяє Podʼам на вузлі, що вийшов з ладу, швидко відновитися на іншому вузлі.
Під час такого (non-graceful) вимикання робота Podʼів завершується у дві фази:
- Насильно видаляються Podʼи, які не мають відповідних toleration
out-of-service
. - Негайно виконується операція відʼєднання томів для таких Podʼів.
Примітка:
- Перш ніж додавати позначку
node.kubernetes.io/out-of-service
, слід перевірити, що вузол вже перебуває в стані припинення роботи чи вимикання (не в середині процесу перезапуску). - Користувач повинен вручну видалити позначку out-of-service після того, як Podʼи будуть переміщені на новий вузол, і користувач перевірив, що вимкнений вузол відновився, оскільки саме користувач додав позначку на початку.
Примусове відʼєднання сховища при перевищенні часу очікування
У будь-якій ситуації, де видалення Podʼа не вдалося протягом 6 хвилин, Kubernetes примусово відʼєднає томи, які розмонтувалися, якщо в цей момент вузол несправний. Будь-яке робоче навантаження, що все ще працює на вузлі та використовує том, який примусово відʼєднується, спричинить порушення специфікації CSI, яка стверджує, що ControllerUnpublishVolume
"повинен бути викликаний після всіх викликів NodeUnstageVolume
та NodeUnpublishVolume
в томі, і вони успішно завершилися". В таких обставинах томи на такому вузлі можуть зіткнутися з пошкодженням даних.
Поведінка примусового відʼєднання сховища є необовʼязковою; користувачі можуть вибрати використання функції "Non-graceful node shutdown" замість цього.
Примусове відʼєднання сховища при перевищенні часу очікування можна вимкнути, встановивши поле конфігурації disable-force-detach-on-timeout
в kube-controller-manager
. Вимкнення функції примусового відʼєднання при перевищенні часу очікування означає, що у тому, який розміщено на вузлі, який несправний протягом понад 6 хвилин, не буде видалено його повʼязаний VolumeAttachment.
Після застосування цього налаштування, несправні Podʼи, які все ще приєднані до томів, повинні бути відновлені за допомогою процедури Обробки невідповідних вимкнень вузлів, згаданої вище.
Примітка:
- Під час використання процедури Обробки невідповідних вимкнень вузлів слід бути обережним.
- Відхилення від документованих вище кроків може призвести до пошкодження даних.
Що далі
Дізнайтеся більше про наступне:
- Допис в Блозі – Non-Graceful Node Shutdown.
- Архітектура кластера: Вузли.