Примусове видалення Podʼів StatefulSet

Примусове видалення Podʼів StatefulSet

На цій сторінці показано, як видаляти Podʼи, що є частиною StatefulSet, і пояснено, що слід враховувати під час цього.

Перш ніж ви розпочнете

  • Це досить складне завдання, яке може порушити деякі властивості, притаманні StatefulSet.
  • Перш ніж продовжити, ознайомтеся з наведеними нижче міркуваннями.

Міркування щодо StatefulSet

Під час нормальної роботи StatefulSet ніколи немає потреби примусово видаляти Pod StatefulSet. Контролер StatefulSet відповідає за створення, масштабування й видалення членів StatefulSet. Він намагається забезпечити, щоб зазначена кількість Podʼів із порядковими номерами від 0 до N-1 працювала й була готовою. StatefulSet гарантує, що в будь-який момент часу в кластері працює не більше одного Podʼа із заданою ідентичністю. Це називається семантикою щонайбільше один, яку забезпечує StatefulSet.

Примусове видалення вручну слід виконувати обережно, оскільки воно може порушити семантику «щонайбільше один», притаманну StatefulSet. StatefulSets можуть використовуватися для запуску розподілених і кластерних застосунків, яким потрібна стабільна мережева ідентичність і стабільне сховище. Ці застосунки часто мають конфігурацію, що ґрунтується на ансамблі з фіксованої кількості членів із фіксованими ідентичностями. Наявність кількох членів з однаковою ідентичністю може мати катастрофічні наслідки й призвести до втрати даних (наприклад, у сценарії split brain у системах на основі кворуму).

Видалення Podʼів

Ви можете виконати коректне видалення Podʼа за допомогою такої команди:

kubectl delete pods <pod>

Щоб таке видалення призвело до коректного завершення, Pod не повинен задавати pod.Spec.TerminationGracePeriodSeconds зі значенням 0. Практика встановлення pod.Spec.TerminationGracePeriodSeconds на 0 секунд є небезпечною й категорично не рекомендована для Podʼів StatefulSet. Коректне видалення безпечне й гарантує, що Pod коректно завершить роботу до того, як kubelet видалить його назву з API-сервера.

Pod не видаляється автоматично, коли вузол недоступний. Podʼи, що працюють на недоступному вузлі, переходять у стан 'Terminating' або 'Unknown' після тайм-ауту. Podʼи також можуть переходити в ці стани, коли користувач намагається коректно видалити Pod на недоступному вузлі. Pod у такому стані можна вилучити з API-сервера лише такими способами:

  • Обʼєкт Node видаляється (вами або контролером вузлів).
  • kubelet на вузлі, що не відповідає, знову починає відповідати, завершує Pod і вилучає запис з API-сервера.
  • Примусове видалення Podʼа користувачем.

Рекомендована практика — використовувати перший або другий підхід. Якщо підтверджено, що вузол не працює (наприклад, постійно відключений від мережі, вимкнений тощо), видаліть обʼєкт Node. Якщо вузол зазнає розділення мережі, спробуйте усунути проблему або дочекайтеся її усунення. Коли мережу буде відновлено, kubelet завершить видалення Podʼа й звільнить його назву в API-сервері.

Зазвичай система завершує видалення, щойно Pod більше не працює на вузлі або адміністратор видаляє вузол. Ви можете перевизначити це, примусово видаливши Pod.

Примусове видалення

Примусове видалення не чекає від kubelet підтвердження, що Pod завершено. Незалежно від того, чи вдасться примусовому видаленню завершити Pod, воно негайно звільняє його назву в API-сервері. Це дає контролеру StatefulSet змогу створити Pod на заміну з тією самою ідентичністю; це може призвести до дублювання Podʼа, який усе ще працює, і якщо цей Pod усе ще може спілкуватися з іншими членами StatefulSet, це порушить семантику «щонайбільше один», яку StatefulSet має гарантувати.

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

Якщо ви хочете примусово видалити Pod за допомогою kubectl версії >= 1.5, виконайте таке:

kubectl delete pods <pod> --grace-period=0 --force

Якщо ви використовуєте будь-яку версію kubectl <= 1.4, пропустіть параметр --force і використайте:

kubectl delete pods <pod> --grace-period=0

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

kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'

Завжди виконуйте примусове видалення Podʼів StatefulSet обережно та з повним розумінням ризиків, повʼязаних із цим.

Що далі

Дізнайтеся більше про налагодження StatefulSet.