Вимикання вузлів

У кластері 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ʼи у два етапи:

  1. Завершує роботу звичайних Podʼів, які виконуються на вузлі.
  2. Завершує роботу критичних Podʼи, які виконуються на вузлі.

Функція відповідного вимикання вузла налаштовується двома параметрами конфігурації kubelet:

  • shutdownGracePeriod:
    • Визначає загальний час, протягом якого вузол повинен затримати вимикання. Це загальний термін допомагає завершити Podʼи як звичайні, так і критичні.
  • shutdownGracePeriodCriticalPods:
    • Визначає термін, який використовується для завершення критичних Podʼів під час вимикання вузла. Це значення повинно бути менше за shutdownGracePeriod.

Наприклад, якщо shutdownGracePeriod=30s, а shutdownGracePeriodCriticalPods=10s, kubelet затримає вимикання вузла на 30 секунд. Під час вимикання перші 20 (30-10) секунд будуть зарезервовані для відповідного завершення звичайних Podʼів, а останні 10 секунд будуть зарезервовані для завершення критичних Podʼів.

Відповідне вимикання вузла на основі пріоритету 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-a100000
custom-class-b10000
custom-class-c1000
regular/unset0

В межах конфігурації kubelet налаштування для shutdownGracePeriodByPodPriority може виглядати так:

Значення класу пріоритету PodʼаПеріод вимкнення
10000010 seconds
10000180 seconds
1000120 seconds
060 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ʼаПеріод вимкнення
100000300 seconds
1000120 seconds
060 seconds

У вищезазначеному випадку Podʼи з custom-class-b потраплять в ту ж саму групу, що й custom-class-c для вимкнення.

Якщо в певному діапазоні відсутні Podʼи, то kubelet не чекатиме на Podʼи у цьому діапазоні пріоритетів. Замість цього, kubelet безпосередньо перейде до наступного діапазону значень пріоритету.

Якщо ця функція увімкнена, а жодна конфігурація не надана, то дії з упорядкування не будуть виконані.

Використання цієї функції передбачає активацію функціональної можливості GracefulNodeShutdownBasedOnPodPriority, та встановлення ShutdownGracePeriodByPodPriority в kubelet config до потрібної конфігурації, яка містить значення класу пріоритету Podʼа та відповідні періоди вимкнення.

Метрики 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ʼів завершується у дві фази:

  1. Насильно видаляються Podʼи, які не мають відповідних toleration out-of-service.
  2. Негайно виконується операція відʼєднання томів для таких Podʼів.

Примусове відʼєднання сховища при перевищенні часу очікування

У будь-якій ситуації, де видалення Podʼа не вдалося протягом 6 хвилин, Kubernetes примусово відʼєднає томи, які розмонтувалися, якщо в цей момент вузол несправний. Будь-яке робоче навантаження, що все ще працює на вузлі та використовує том, який примусово відʼєднується, спричинить порушення специфікації CSI, яка стверджує, що ControllerUnpublishVolume "повинен бути викликаний після всіх викликів NodeUnstageVolume та NodeUnpublishVolume в томі, і вони успішно завершилися". В таких обставинах томи на такому вузлі можуть зіткнутися з пошкодженням даних.

Поведінка примусового відʼєднання сховища є необовʼязковою; користувачі можуть вибрати використання функції "Non-graceful node shutdown" замість цього.

Примусове відʼєднання сховища при перевищенні часу очікування можна вимкнути, встановивши поле конфігурації disable-force-detach-on-timeout в kube-controller-manager. Вимкнення функції примусового відʼєднання при перевищенні часу очікування означає, що у тому, який розміщено на вузлі, який несправний протягом понад 6 хвилин, не буде видалено його повʼязаний VolumeAttachment.

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

Що далі

Дізнайтеся більше про наступне:

Змінено August 15, 2024 at 4:40 PM PST: upstream sync (6ec9cfeefc)