Життєвий цикл Podʼа

Життєвий цикл Podʼа

Ця сторінка описує життєвий цикл Podʼа. Podʼи проходять визначений життєвий цикл, починаючи з фази Pending, переходячи до Running, якщо принаймні один з основних контейнерів успішно запускається, а потім до фази Succeeded або Failed, залежно від того, чи завершився будь-який контейнер у Podʼі зі збоєм.

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

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

Час життя Podʼа

Поки Pod працює, kubelet може перезапускати контейнери, щоб усунути певні види несправностей. У межах Podʼа Kubernetes відстежує різні стани контейнера і визначає, які дії вжити, щоб Pod знову став справним. Це робиться в циклі опитування, який періодично узгоджує бажаний стан (специфікацію Podʼа) з фактичним станом запущених контейнерів.

В API Kubernetes Pod має як специфікацію, так і фактичний статус. Статус обʼєкта Pod складається з набору станів Podʼа. Ви також можете додавати власні дані про готовність до даних станів Podʼа, якщо це корисно для вашого застосунку.

Podʼи плануються лише один раз за час свого життя; призначення Podʼа на певний вузол називається привʼязкою, а процес вибору вузла — плануванням. Після того, як Pod було заплановано і привʼязано до вузла, Kubernetes намагається запустити цей Pod на цьому вузлі. Pod працює на цьому вузлі, доки не зупиниться або доки його не буде завершено; якщо Kubernetes не може запустити Pod на вибраному вузлі (наприклад, якщо вузол аварійно завершить роботу до запуску Podʼа), то цей конкретний Pod ніколи не запуститься.

Ви можете використати готовність Podʼів до планування, щоб затримати планування Podʼа, доки не буде видалено всі його шлюзи планування (scheduling gates). Наприклад, ви можете визначити набір Podʼів, але запустити планування лише після того, як всі Podʼи будуть створені.

Podʼи та відновлення після збоїв

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

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

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

У Kubernetes використовується абстракція вищого рівня, яка називається контролер, яка виконує роботу з керування відносно одноразовими екземплярами Podʼів.

Конкретний Pod (визначений UID) ніколи не «переплановується» на інший вузол; натомість цей Pod може бути замінений новим, майже ідентичним Podʼом. Якщо ви створюєте Pod-замінник, він може навіть мати ту саму назву (як у .metadata.name), що й старий Pod, але замінник матиме інший .metadata.uid, ніж старий Pod.

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

Повʼязаний час життя

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

Багатоконтейнерний Pod, який містить sidecar-контейнер для завантаження файлів і вебсервер. Pod використовує ефемерний том emptyDir як спільне сховище для контейнерів.

Малюнок 1.

Багатоконтейнерний Pod, який містить sidecar-контейнер для завантаження файлів і вебсервер. Pod використовує ефемерний том emptyDir як спільне сховище для контейнерів.

Фаза Podʼа

Поле status Podʼа — це обʼєкт PodStatus, який має поле phase.

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

Кількість і значення фаз Podʼа суворо контролюються. Окрім того, що задокументовано тут, не слід нічого припускати про Podʼи з певним значенням phase.

Ось можливі значення для phase:

ЗначенняОпис
PendingPod прийнято кластером Kubernetes, але один чи кілька контейнерів ще не налаштовано й не підготовлено до запуску. Це включає час, який Pod витрачає на очікування планування, а також час, який витрачається на завантаження образів контейнерів з мережі.
RunningPod привʼязаний до вузла, і всі контейнери створені. Принаймні один контейнер все ще працює або перебуває у процесі запуску чи перезапуску.
SucceededВсі контейнери в Podʼі завершили роботу успішно і не будуть перезапущені.
FailedВсі контейнери в Podʼі завершили роботу, і принаймні один контейнер завершився зі збоєм. Іншими словами, контейнер вийшов зі статусом, відмінним від нуля, або його роботу завершила система, і контейнер не налаштований на автоматичний перезапуск.
UnknownЗ якоїсь причини не вдалося отримати стан Podʼа. Ця фаза, як правило, виникає через помилку у звʼязку з вузлом, де повинен виконуватися Pod.

Примітка:

Якщо Podʼу раз у раз не вдається запуститися, у полі Status деяких команд kubectl може зʼявитися CrashLoopBackOff. Аналогічно, під час видалення Podʼа у полі Status деяких команд kubectl може зʼявитися Terminating.

Не плутайте Status, поле відображення kubectl, призначене для зручності користувача, з phase Podʼа. Фаза Podʼа є явною частиною моделі даних Kubernetes і API Pod.

  NAMESPACE               NAME               READY   STATUS             RESTARTS   AGE
  alessandras-namespace   alessandras-pod    0/1     CrashLoopBackOff   200        2d9h

Pod отримує час на коректне завершення, який стандартно становить 30 секунд. Ви можете використовувати прапорець --force для примусового завершення роботи Podʼа.

Починаючи з Kubernetes 1.27, kubelet переводить видалені Podʼи в термінальну фазу (Failed або Succeeded залежно від статусів завершення роботи контейнерів Podʼа) перед їх видаленням з API-сервера, за винятком двох випадків:

Якщо вузол виходить з ладу або втрачає звʼязок з рештою кластера, Kubernetes застосовує політику встановлення phase всіх Podʼів на втраченому вузлі у Failed.

Стани контейнера

Окрім фази Podʼа загалом, Kubernetes відстежує стан кожного контейнера всередині Podʼа. Ви можете використовувати хуки життєвого циклу контейнера, щоб запускати події на певних етапах життєвого циклу контейнера.

Як тільки планувальник призначає Pod вузлу, kubelet починає створювати контейнери для цього Podʼа, використовуючи середовище виконання контейнерів. Існує три можливі стани контейнера: Waiting (Очікування), Running (Виконання) та Terminated (Завершено).

Щоб перевірити стан контейнерів Podʼа, ви можете використовувати kubectl describe pod <name-of-pod>. Вивід показує стан для кожного контейнера в межах цього Podʼа.

Кожен стан має конкретне значення:

Waiting

Якщо контейнер не перебуває ні в стані Running, ні в стані Terminated, то він перебуває в стані Waiting. Контейнер у стані Waiting усе ще виконує операції, необхідні для завершення запуску: наприклад, завантажує образ контейнера з реєстру образів контейнерів або застосовує дані Secret. Коли ви використовуєте kubectl для опитування Podʼа із контейнером, який перебуває в стані Waiting, ви також бачите поле Reason, яке стисло пояснює, чому контейнер перебуває в цьому стані.

Running

Статус Running вказує на те, що виконання контейнера відбувається без проблем. Якщо було налаштовано хук postStart, він уже виконався і завершився. Коли ви використовуєте kubectl для опитування Podʼа із контейнером, який перебуває в стані Running, ви також бачите інформацію про те, коли контейнер перейшов у стан Running.

Terminated

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

Якщо у контейнера є налаштований хук preStop, цей хук запускається перед тим, як контейнер перейде в стан Terminated.

Як Podʼи вирішують проблеми з контейнерами

Kubernetes обробляє збої контейнерів у межах Podʼів за допомогою політики restartPolicy, визначеної в spec Podʼа. Ця політика визначає, як Kubernetes реагує на завершення контейнерів через помилки або з інших причин, у такій послідовності:

  1. Початковий збій: Kubernetes намагається негайно перезапустити контейнер на основі restartPolicy Podʼа.
  2. Повторні збої: Після початкового збою Kubernetes застосовує експоненційну затримку для наступних перезапусків, описану в restartPolicy. Це запобігає перевантаженню системи швидкими повторними спробами перезапуску.
  3. Стан CrashLoopBackOff: Це означає, що для певного контейнера зараз діє механізм затримки, бо цей контейнер перебуває в циклі збоїв: він раз у раз зазнає збою та перезапускається.
  4. Скидання затримки: Якщо контейнер успішно працює протягом певного часу (наприклад, 10 хвилин), Kubernetes скидає затримку, розглядаючи будь-який новий збій як перший.

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

Іншими словами, коли контейнер потрапляє в цикл збоїв, Kubernetes застосовує експоненційну затримку, про яку було згадано в політиці перезапуску контейнера. Цей механізм не дає несправному контейнеру перевантажувати систему безперервними невдалими спробами запуску.

CrashLoopBackOff може бути спричинений такими проблемами:

  • Помилки застосунків, які призводять до завершення контейнера.
  • Помилки конфігурації, такі як неправильні змінні середовища або відсутність конфігураційних файлів.
  • Обмеження ресурсів, коли контейнеру може бракувати памʼяті або CPU для правильного запуску.
  • Невдалі перевірки справності, якщо застосунок не починає обслуговувати запити у передбачений час.
  • Проби життєздатності або проби запуску контейнера, що повертають результат Failure, як зазначено в розділі про проби.

Щоб розібратися у причинах проблеми CrashLoopBackOff, користувач може:

  1. Перевірити логи: Використовуйте kubectl logs <name-of-pod>, щоб перевірити логи контейнера. Часто це найпряміший спосіб діагностики проблеми, що спричиняє збої.
  2. Перевірити події: Використовуйте kubectl describe pod <name-of-pod> для перегляду подій для Podʼа, які можуть надати підказки про проблеми конфігурації або ресурсів.
  3. Перевірити конфігурацію: Переконайтеся, що конфігурація Podʼа, включаючи змінні середовища та змонтовані томи, є правильною і що всі необхідні зовнішні ресурси доступні.
  4. Перевірити обмеження ресурсів: Переконайтеся, що контейнеру виділено достатньо CPU та памʼяті. Іноді збільшення ресурсів у визначенні Podʼа може вирішити проблему.
  5. Налагодити застосунок: У коді застосунку можуть бути помилки або неправильні налаштування. Запуск цього образу контейнера локально або в середовищі розробки може допомогти діагностувати проблеми, специфічні для застосунку.

Перезапуск контейнера

Коли контейнер у вашому Podʼі зупиняється або зазнає збою, Kubernetes може його перезапустити. Перезапуск не завжди є доречним; наприклад, init-контейнери запускаються лише один раз (у разі успіху), під час запуску Podʼа. Ви можете налаштувати перезапуски як політику, що застосовується до всіх Podʼів, або за допомогою конфігурації на рівні контейнера (наприклад, коли ви визначаєте sidecar-контейнер), або задати перевизначення на рівні контейнера.

Перезапуск контейнера та відмовостійкість

Проєкт Kubernetes рекомендує дотримуватися принципів cloud native, включаючи відмовостійкий дизайн, який враховує неоголошені або довільні перезапуски. Ви можете досягти цього або завершивши Pod зі збоєм і покладаючись на автоматичну заміну, або спроєктувавши відмовостійкість на рівні контейнера. Обидва підходи допомагають забезпечити доступність вашого робочого навантаження загалом, незважаючи на часткові збої.

Політика перезапуску контейнера на рівні Podʼа

spec Podʼа має поле restartPolicy із можливими значеннями Always, OnFailure та Never. Стандартне значення — Always.

restartPolicy для Podʼа застосовується до контейнерів застосунків в Podʼі та до звичайних init-контейнерів. Sidecar-контейнери не враховують поле restartPolicy на рівні Podʼа: у Kubernetes sidecar визначається як запис всередині initContainers, у якого restartPolicy на рівні контейнера встановлено в Always. Для init-контейнерів, які завершують роботу з помилкою, kubelet виконує їх перезапуск, якщо restartPolicy на рівні Podʼа — OnFailure або Always:

  • Always: автоматично перезапускає контейнер після будь-якого завершення.
  • OnFailure: перезапускає контейнер тільки після його завершення з помилкою (код виходу відмінний від нуля).
  • Never: ніколи автоматично не перезапускає контейнер, що завершив роботу.
Порівняння поведінки перезапуску

Наступна таблиця показує, як контейнери поводяться за різних політик перезапуску та кодів виходу:

Код виходуrestartPolicy: AlwaysrestartPolicy: OnFailurerestartPolicy: NeverSidecar-контейнери
0 (Успіх)ПерезапускаєтьсяНе перезапускаєтьсяНе перезапускаєтьсяЗавжди перезапускається
Ненульовий (Збій)ПерезапускаєтьсяПерезапускаєтьсяНе перезапускаєтьсяЗавжди перезапускається

Примітка:

Поведінка перезапуску особливо важлива під час вибору між Deployments та Jobs:

  • Deployments зазвичай використовують restartPolicy: Always (єдине дозволене значення) для безперервної роботи застосунків.
  • Jobs зазвичай використовують restartPolicy: OnFailure або restartPolicy: Never для належного оброблення завдань пакетної обробки.
  • Sidecar-контейнери є init-контейнерами, які завжди перезапускаються незалежно від restartPolicy Podʼа, оскільки вони мають власну політику перезапуску на рівні контейнера restartPolicy: Always.
Приклади сценаріїв

Ось конкретні приклади, що демонструють різну поведінку перезапуску:

Приклад 1: Вебсервер з restartPolicy: Always (типово для Deployments)

apiVersion: v1
kind: Pod
metadata:
  name: web-server
spec:
  restartPolicy: Always  # Контейнер перезапускається незалежно від коду виходу
  containers:
  - name: nginx
    image: nginx:1.14.2
    # Якщо цей контейнер аварійно завершить роботу або завершиться з будь-якої причини, його буде перезапущено

Приклад 2: Завдання пакетної обробки з restartPolicy: OnFailure

apiVersion: batch/v1
kind: Job
metadata:
  name: data-processor
spec:
  template:
    spec:
      restartPolicy: OnFailure  # Перезапускається лише за ненульового коду виходу
      containers:
      - name: processor
        image: busybox:1.28
        command: ['sh', '-c', 'echo "Processing data..."; exit 0']
        # Код виходу 0: Job успішно завершено, перезапуск не відбувається
        # Код виходу 1+: Контейнер перезапускається для повторної спроби завдання

Приклад 3: Одноразове завдання з restartPolicy: Never

apiVersion: v1
kind: Pod
metadata:
  name: migration-task
spec:
  restartPolicy: Never  # Ніколи не перезапускається, незалежно від коду виходу
  containers:
  - name: migrate
    image: busybox:1.28
    command: ['sh', '-c', 'echo "Running migration..."; exit 1']
    # Навіть із кодом виходу 1 (збій) контейнер не буде перезапущено
    # Pod залишиться в стані Failed
Sidecar-контейнери та політики перезапуску

Sidecar-контейнери мають особливу поведінку перезапуску, яка відрізняється від звичайних контейнерів застосунків:

  • Sidecar-контейнери ігнорують restartPolicy на рівні Podʼа: Вони використовують власне поле restartPolicy на рівні контейнера, яке завжди встановлено в Always
  • Незалежний життєвий цикл: Sidecar-контейнери можуть перезапускатися незалежно від основного контейнера застосунку
  • Постійна робота: Sidecar-контейнери продовжують працювати протягом усього часу життя Podʼа, надаючи допоміжні сервіси

Приклад: Pod із sidecar-контейнером

apiVersion: v1
kind: Pod
metadata:
  name: app-with-sidecar
spec:
  restartPolicy: OnFailure  # Застосовується лише до основного контейнера
  initContainers:
  - name: logging-sidecar    # Це sidecar-контейнер
    image: fluent/fluent-bit:1.8
    restartPolicy: Always    # Sidecar завжди перезапускається незалежно від коду виходу
    # Надає сервіси логування протягом усього часу життя Podʼа
  containers:
  - name: main-app          # Дотримується політики перезапуску на рівні Podʼа
    image: nginx:1.14.2
    # Перезапускається лише у разі помилки (ненульовий код виходу) через політику OnFailure Podʼа

Примітка:

Хоча основний контейнер застосунку дотримується політики restartPolicy: OnFailure на рівні Podʼа, sidecar-контейнер буде перезапущений незалежно від його коду виходу, оскільки sidecar-контейнери завжди мають restartPolicy: Always на рівні контейнера.

Коли kubelet обробляє перезапуск контейнера згідно з налаштованою політикою перезапуску, це стосується лише перезапусків, які призводять до заміни контейнерів всередині того ж Podʼа та на тому ж вузлі. Після завершення контейнерів у Podʼі kubelet перезапускає їх із затримкою, що зростає експоненційно (10 с, 20 с, 40 с, …), і обмеженою пʼятьма хвилинами (300 секунд). Якщо контейнер виконується протягом 10 хвилин без проблем, kubelet скидає таймер затримки перезапуску для цього контейнера. У розділі Sidecar-контейнери та життєвий цикл Podʼа пояснюється поведінка init containers, коли для них вказано поле restartPolicy.

Політика та правила перезапуску окремих контейнерів

СТАН ФУНКЦІОНАЛУ: Beta since Kubernetes v1.35; (стандартно увімкнено)

Якщо у вашому кластері увімкнено функціональну можливість ContainerRestartRules, ви можете вказати restartPolicy та restartPolicyRules для окремих контейнерів, щоб перевизначити політику перезапуску Podʼа. Політика перезапуску контейнера та правила застосовуються до контейнерів застосунків в Podʼі та до звичайних init-контейнерів.

Нативний для Kubernetes sidecar-контейнер має restartPolicy на рівні контейнера, встановлену в Always.

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

  • Always: автоматично перезапускає контейнер після будь-якого завершення.
  • OnFailure: перезапускає контейнер тільки після його завершення з помилкою (код виходу відмінний від нуля).
  • Never: ніколи автоматично не перезапускає контейнер, що завершив роботу.

Крім того, для окремих контейнерів можна вказати restartPolicyRules. Якщо вказано поле restartPolicyRules, то також повинно бути вказано restartPolicy контейнера. restartPolicyRules визначають список правил, які застосовуються під час завершення контейнера. Кожне правило складатиметься з умови та дії. Підтримувана умова — exitCodes, яка порівнює код виходу контейнера зі списком заданих значень. Підтримувана дія — Restart, що означає, що контейнер буде перезапущено. Правила будуть оцінюватися по порядку. За першого збігу буде застосовано дію. Якщо жодна з умов правил не збіглася, Kubernetes повернеться до налаштованої restartPolicy контейнера.

Наприклад, Pod з політикою перезапуску OnFailure, який має контейнер try-once. Це дозволяє Podʼу перезапускати лише певні контейнери:

apiVersion: v1
kind: Pod
metadata:
  name: on-failure-pod
spec:
  restartPolicy: OnFailure
  containers:
  - name: try-once-container    # Цей контейнер буде запущено лише один раз, оскільки політика перезапуску — Never.
    image: registry.k8s.io/busybox:1.27.2
    command: ['sh', '-c', 'echo "Only running once" && sleep 10 && exit 1']
    restartPolicy: Never
  - name: on-failure-container  # Цей контейнер буде перезапущено у разі збою.
    image: registry.k8s.io/busybox:1.27.2
    command: ['sh', '-c', 'echo "Keep restarting" && sleep 1800 && exit 1']

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

apiVersion: v1
kind: Pod
metadata:
  name: fail-pod-if-init-fails
spec:
  restartPolicy: Always
  initContainers:
  - name: init-once      # Цей init-контейнер спробує запуститися лише один раз. Якщо він зазнає збою, Pod зазнає збою.
    image: registry.k8s.io/busybox:1.27.2
    command: ['sh', '-c', 'echo "Failing initialization" && sleep 10 && exit 1']
    restartPolicy: Never
  containers:
  - name: main-container # Цей контейнер завжди перезапускатиметься після успішної ініціалізації.
    image: registry.k8s.io/busybox:1.27.2
    command: ['sh', '-c', 'sleep 1800 && exit 0']

Pod з політикою перезапуску Never, який має контейнер, що ігнорує одні коди виходу та перезапускається на конкретних кодах виходу. Це корисно для розрізнення між помилками, після яких контейнер можна перезапустити, і тими, які не дозволяють зробити перезапуск:

apiVersion: v1
kind: Pod
metadata:
  name: restart-on-exit-codes
spec:
  restartPolicy: Never
  containers:
  - name: restart-on-exit-codes
    image: registry.k8s.io/busybox:1.27.2
    command: ['sh', '-c', 'sleep 60 && exit 0']
    restartPolicy: Never     # Політика перезапуску контейнера повинна бути вказана, якщо вказані правила
    restartPolicyRules:      # Перезапускати контейнер, лише якщо він завершується з кодом 42
    - action: Restart
      exitCodes:
        operator: In
        values: [42]

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

Перезапуск усіх контейнерів

СТАН ФУНКЦІОНАЛУ: Beta since Kubernetes v1.36; (стандартно увімкнено)

Якщо у вашому кластері увімкнено функціональну можливість RestartAllContainersOnContainerExits, ви можете вказати RestartAllContainers як дію в restartPolicyRules на рівні контейнера. Коли завершення контейнера відповідає правилу з цією дією, весь Pod завершується і перезапускається на місці.

Такий перезапуск «на місці» є ефективнішим способом скидання стану Podʼа порівняно з повним видаленням і повторним створенням. Це особливо цінно для робочих навантажень, де перепланування є дорогим, наприклад, для пакетних завдань або завдань навчання AI/ML.

Як працюють перезапуски Podʼів на місці

Коли спрацьовує дія RestartAllContainers, kubelet виконує такі кроки:

  1. Швидке завершення: Усі запущені контейнери в Podʼі завершуються. Налаштований параметр terminationGracePeriodSeconds не враховується, а налаштовані хуки preStop не виконуються. Це забезпечує швидке вимкнення.
  2. Збереження ресурсів Podʼа: Основні ресурси Podʼа зберігаються:
    • UID Podʼа, IP-адреса та мережевий простір імен
    • Пісочниця Podʼа та будь-які підключені пристрої
    • Усі томи, включаючи томи emptyDir та змонтовані томи
  3. Оновлення статусу Podʼа: Статус Podʼа оновлюється: стан PodRestartInPlace встановлюється в True. Це робить процес перезапуску спостережуваним.
  4. Повна послідовність перезапуску: Після завершення роботи всіх контейнерів стан PodRestartInPlace встановлюється в False, і Pod починає стандартний процес запуску:
    • Init-контейнери запускаються повторно по черзі.
    • Запускаються sidecar-контейнери та звичайні контейнери.

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

Цей механізм корисний у сценаріях, коли всім контейнерам потрібно почати з чистого аркуша, наприклад:

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

Розглянемо робоче навантаження, де sidecar-спостерігач відповідає за перезапуск основного застосунку з відомого справного стану, якщо той натрапляє на помилку. Спостерігач може завершитися з певним кодом, щоб ініціювати повний перезапуск робочого Podʼа на місці.

apiVersion: v1
kind: Pod
metadata:
  name: ml-worker
spec:
  restartPolicy: Never # The pod itself should not restart unless explicitly told to.
  initContainers:
  - name: setup-environment
    image: registry.k8s.io/busybox:1.27.2
    command: ['sh', '-c', 'echo "Setting up environment"']
    # This init container runs once to prepare the environment.
    # It will run again after a RestartAllContainers action.
  - name: watcher-sidecar
    image: registry.k8s.io/busybox:1.27.2
    # In a real-world scenario, this would be a dedicated watcher image.
    # This command simulates the watcher exiting with a special code.
    command: ['sh', '-c', 'sleep 60; exit 88']
    restartPolicy: Always
    restartPolicyRules:
    - action: RestartAllContainers
      exitCodes:
        # Exit code 88 triggers a full pod restart.
        operator: In
        values: [88]
  containers:
  - name: main-application
    image: registry.k8s.io/busybox:1.27.2
    command: ['sh', '-c', 'echo "Application is running"; sleep 3600']

У цьому прикладі:

  • Загальна політика перезапуску Podʼа — Never.
  • watcher-sidecar виконує команду, а потім завершується з кодом 88.
  • Код завершення відповідає правилу, що запускає дію RestartAllContainers.
  • Потім весь Pod, включаючи init-контейнер setup-environment і контейнер main-application, перезапускається на місці. Pod зберігає свій UID, пісочницю, IP-адресу та томи.

Зменшена затримка перезапуску контейнера

СТАН ФУНКЦІОНАЛУ: Alpha since Kubernetes v1.33; (стандартно вимкнено)
More information about this feature

To use this feature, you (or a cluster administrator) will need to enable the ReduceDefaultCrashLoopBackOffDecay feature gate for all relevant components in your cluster.

See Enable Or Disable Feature Gates for more information.

З увімкненою альфа-функціональною можливістю ReduceDefaultCrashLoopBackOffDecay затримка повторних спроб запуску контейнера у вашому кластері починатиметься з 1 с (замість 10 с) і експоненційно зростатиме у 2 рази з кожним перезапуском до максимальної затримки 60 с (замість 300 с, тобто 5 хвилин).

Якщо ви використовуєте цю можливість з альфа-можливістю KubeletCrashLoopBackOffMax (описано нижче), окремі вузли можуть мати різні значення максимальної затримки.

Налаштовувана затримка перезапуску контейнера

СТАН ФУНКЦІОНАЛУ: Beta since Kubernetes v1.35; (стандартно увімкнено)

З увімкненою функціональною можливістю KubeletCrashLoopBackOffMax ви можете змінити максимальну затримку між повторними спробами запуску контейнера, яка стандартно становить 300 секунд (5 хвилин). Ця конфігурація встановлюється для кожного вузла за допомогою конфігурації kubelet. У вашій конфігурації kubelet у полі crashLoopBackOff встановіть значення поля maxContainerRestartPeriod між "1s" і "300s". Як описано вище у Політиці перезапуску контейнерів, затримки на цьому вузлі все одно починатимуться з 10 секунд і збільшуватимуться експоненційно у 2 рази з кожним перезапуском, але тепер вони будуть обмежені вашим налаштованим максимумом. Якщо значення maxContainerRestartPeriod, яке ви налаштували, менше початкового стандартного значення у 10 секунд, початкову затримку буде встановлено на налаштоване максимальне значення.

Дивіться такі приклади налаштування kubelet:

# затримки перезапуску контейнерів починаються з 10 секунд і збільшуються
# у 2 рази з кожним перезапуском, максимум до 100 с
kind: KubeletConfiguration
crashLoopBackOff:
    maxContainerRestartPeriod: "100s"
# затримки між перезапусками контейнера завжди будуть дорівнювати 2 с
kind: KubeletConfiguration
crashLoopBackOff:
    maxContainerRestartPeriod: "2s"

Якщо ви використовуєте цю можливість разом з альфа-можливістю ReduceDefaultCrashLoopBackOffDecay (описано вище), стандартні значення кластера для початкової та максимальної затримки будуть уже не 10 і 300 секунд, а 1 і 60 секунд. Конфігурація для кожного вузла має пріоритет над стандартними значеннями, встановленими ReduceDefaultCrashLoopBackOffDecay, навіть якщо це призведе до того, що вузол матиме довшу максимальну затримку, ніж інші вузли у кластері.

Стани Podʼа

Pod має PodStatus, який містить масив PodConditions, через які Pod пройшов або не пройшов. Kubelet керує такими PodConditions:

  • PodScheduled: Pod заплановано на вузол.
  • PodReadyToStartContainers: пісочницю Podʼа успішно створено, мережу налаштовано, томи зберігання змонтовано, а будь-які динамічні ресурси (якщо їх запитано) виділено.
  • ContainersReady: всі контейнери в Podʼі готові.
  • Initialized: всі init-контейнери успішно завершили виконання.
  • Ready: Pod може обслуговувати запити і його слід додати до пулів балансування навантаження всіх відповідних Services.
  • DisruptionTarget: Pod скоро буде завершено через переривання роботи (наприклад, витіснення, виселення або збір сміття).
  • PodResizePending: було запитано зміну розміру Podʼа, але її неможливо застосувати. Дивіться Статус зміни розміру Podʼа.
  • PodResizeInProgress: Pod перебуває в процесі зміни розміру. Дивіться Статус зміни розміру Podʼа.
Назва поляОпис
typeНазва цього стану Podʼа.
statusВказує, чи застосовується цей стан, з можливими значеннями "True", "False" або "Unknown".
lastProbeTimeМітка часу останньої перевірки стану Podʼа.
lastTransitionTimeМітка часу останнього переходу Podʼа з одного статусу в інший.
reasonМашиночитаний текст у форматі UpperCamelCase, який вказує причину останнього переходу стану.
messageЗрозуміле людині повідомлення з подробицями щодо останнього переходу статусу.

Готовність Podʼа

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

Ваш застосунок може внести додатковий зворотний звʼязок або сигнали в PodStatus: готовність Podʼа. Щоб використовувати це, встановіть readinessGates в spec Podʼа, щоб вказати список додаткових станів, які kubelet оцінює для визначення готовності Podʼа.

Шлюзи готовності (readiness gates) визначаються поточним станом полів status.condition Podʼа. Якщо Kubernetes не може знайти такий стан у полі status.conditions Podʼа, статус цього стану стандартно вважається "False".

Наприклад:

kind: Pod
...
spec:
  readinessGates:
    - conditionType: "www.example.com/feature-1"
status:
  conditions:
    - type: Ready                              # вбудований стан Podʼа
      status: "False"
      lastProbeTime: null
      lastTransitionTime: 2018-01-01T00:00:00Z
    - type: "www.example.com/feature-1"        # додатковий стан Podʼа
      status: "False"
      lastProbeTime: null
      lastTransitionTime: 2018-01-01T00:00:00Z
  containerStatuses:
    - containerID: docker://abcd...
      ready: true
...

Стани Podʼа, які ви додаєте, повинні мати назви, що відповідають формату ключа міток Kubernetes.

Статус для готовності Podʼа

Команда kubectl patch не підтримує зміну статусу обʼєкта накладанням патчів. Щоб встановити ці status.conditions для Podʼа, застосунки та оператори повинні використовувати дію PATCH. Ви можете використовувати клієнтську бібліотеку Kubernetes для написання коду, який встановлює власні стани Podʼа для готовності Podʼа.

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

  • Всі контейнери в Podʼі готові.
  • Усі стани, вказані в readinessGates, мають значення True.

Коли контейнери Podʼа перебувають у стані Ready, але принаймні один власний стан відсутній або має значення False, kubelet встановлює стан Podʼа в ContainersReady.

Готовність Podʼа до запуску контейнерів

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

Примітка:

На ранніх етапах розробки цей стан називали PodHasNetwork.

Після того, як Pod заплановано на вузол, kubelet має його допустити, а всі необхідні томи зберігання мають бути змонтовані. Щойно ці фази завершаться, kubelet працює із середовищем виконання контейнерів (використовуючи Container Runtime Interface (CRI)), щоб налаштувати пісочницю середовища виконання та мережу для Podʼа. Якщо Pod використовує Динамічне виділення ресурсів, ці ресурси також виділяються під час цієї фази. Стан PodReadyToStartContainers додається до поля status.conditions Podʼа.

Kubelet встановлює цей стан в False, коли виявляє, що Pod не має пісочниці середовища виконання з налаштованою мережею. Це трапляється в таких випадках:

  • На початковому етапі життєвого циклу Podʼа, коли kubelet ще не почав налаштовувати пісочницю для Podʼа за допомогою середовища виконання контейнерів.
  • Пізніше в життєвому циклі Podʼа, коли пісочницю Podʼа було знищено через:
    • перезавантаження вузла без виселення Podʼа
    • для середовищ виконання контейнерів, які використовують віртуальні машини для ізоляції, — перезавантаження віртуальної машини пісочниці Podʼа, що потім вимагає створення нової пісочниці та нової конфігурації мережі контейнера.

Після створення пісочниці, налаштування мережі, монтування томів та (якщо запитано) динамічного виділення ресурсів kubelet встановлює стан PodReadyToStartContainers в True. Завантаження образу та створення контейнера відбуваються після цього.

Для Podʼа з init-контейнерами kubelet встановлює стан Initialized в True після успішного завершення init-контейнерів (що відбувається після успішного створення пісочниці та налаштування мережі втулком середовища виконання). Для Podʼа без init-контейнерів kubelet встановлює стан Initialized в True перед початком створення пісочниці та налаштування мережі.

Зміна розміру Podʼів

СТАН ФУНКЦІОНАЛУ: GA since Kubernetes v1.35
More information about this feature

This is a stable feature in Kubernetes, and has been since version v1.35. It was first available in the v1.27 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate InPlacePodVerticalScaling, Kubernetes ignores it but does not report any error.

СТАН ФУНКЦІОНАЛУ: Beta since Kubernetes v1.36; (стандартно увімкнено)

Kubernetes підтримує зміну ресурсів CPU та памʼяті, виділених для Podʼів, після їх створення. (Для інших ресурсів інфраструктури потрібно використовувати інші методи, специфічні для цих ресурсів.) Існує два основні підходи до зміни розміру CPU та памʼяті:

Зміна розміру Podʼа на місці

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

Якщо ви вказали ресурси на рівні Podʼа, ви також можете змінювати їх на місці. Для отримання додаткової інформації див. Зміна розміру CPU та памʼяті, призначених Podʼам.

Щоб виконати зміну розміру на місці, оновіть бажаний стан Podʼа за допомогою субресурсу /resize. Kubelet спробує застосувати нові значення ресурсів до контейнерів, що працюють. Стани Podʼа PodResizePending та PodResizeInProgress (описані в розділі Стани Podʼа) вказують на статус операції зміни розміру. Для отримання додаткової інформації про статус зміни розміру див. Статус зміни розміру контейнера.

Основні моменти, які слід враховувати під час зміни розміру на місці:

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

Детальні інструкції щодо зміни розміру на місці див. Зміна розміру CPU та памʼяті, призначених контейнерам.

Зміна розміру шляхом запуску Podʼів-замінників

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

Цей підхід:

  • Працює з будь-якою версією Kubernetes.
  • Може змінювати будь-яку специфікацію Podʼа, а не тільки ресурси.
  • Призводить до заміни Podʼа, тому вам слід спроєктувати робоче навантаження таким чином, щоб воно могло обробляти заплановані переривання роботи. Розгляньте можливість використання PodDisruptionBudget для контролю доступності.
  • Вимагає, щоб вашими Podʼами керував ресурс робочого навантаження.

Ви також можете використовувати VerticalPodAutoscaler для автоматичного керування рекомендаціями та оновленнями ресурсів Podʼів.

Проби контейнерів

Kubernetes дозволяє визначати проби для безперервного моніторингу стану контейнерів у Podʼі. Проба — це діагностика, яку періодично виконує kubelet для контейнера. Для виконання діагностики kubelet або виконує код всередині контейнера, або виконує мережевий запит.

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

Kubelet може за бажанням виконувати три типи проб для запущених контейнерів і реагувати на них, кожен із цих типів має своє призначення. Для механізмів проб (exec, grpc, httpGet, tcpSocket), полів конфігурації та детальних рекомендацій щодо використання дивіться Проби життєздатності, готовності та запуску.

Проба запуску

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

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

Якщо проба запуску не вдається, kubelet завершує контейнер, і до контейнера застосовується його політика перезапуску.

Проба життєздатності

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

Якщо контейнер не проходить пробу життєздатності більше разів, ніж дозволено налаштуваннями, kubelet перезапускає цей контейнер. Проби життєздатності не чекають успіху проб готовності. Якщо ви хочете почекати перед виконанням проби життєздатності, ви можете або визначити initialDelaySeconds, або використовувати пробу запуску.

Проба готовності

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

Якщо проба готовності повертає невдалий результат, контролер EndpointSlice видаляє IP-адресу Podʼа з EndpointSlices усіх Services, які відповідають Podʼу.

Проби готовності виконуються в контейнері протягом усього його життєвого циклу.

Завершення роботи Podʼів

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

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

Зазвичай під час такого коректного завершення роботи Podʼа kubelet надсилає запити до середовища виконання контейнерів, щоб спробувати зупинити контейнери в Podʼі, спочатку надсилаючи сигнал TERM (також відомий як SIGTERM) основному процесу в кожному контейнері з тайм-аутом періоду коректного завершення. Запити на зупинку контейнерів обробляються середовищем виконання контейнерів асинхронно. Порядок обробки цих запитів не гарантується. Багато середовищ виконання контейнерів враховують значення STOPSIGNAL, визначене в образі контейнера і, якщо воно відрізняється, надсилають значення STOPSIGNAL, визначене в образі контейнера, замість TERM. Після закінчення періоду коректного завершення сигнал KILL надсилається всім залишковим процесам, а потім Pod видаляється з API-сервера. Якщо kubelet або сервіс керування середовищем виконання контейнерів перезапускається під час очікування завершення процесів, кластер повторює спробу спочатку, включаючи повний початковий період коректного завершення.

Сигнали зупинки

Сигнал зупинки, який використовується для завершення роботи контейнера, може бути визначено в образі контейнера за допомогою інструкції STOPSIGNAL. Якщо в образі контейнера не визначено жодного сигналу зупинки, для завершення роботи контейнера буде використано стандартний сигнал середовища виконання контейнерів (SIGTERM як для containerd, так і для CRI-O).

Визначення власних сигналів зупинки

СТАН ФУНКЦІОНАЛУ: Alpha since Kubernetes v1.33; (стандартно вимкнено)
More information about this feature

To use this feature, you (or a cluster administrator) will need to enable the ContainerStopSignals feature gate for all relevant components in your cluster.

See Enable Or Disable Feature Gates for more information.

Якщо увімкнено функціональну можливість ContainerStopSignals, ви можете налаштувати власний сигнал зупинки для ваших контейнерів з життєвого циклу контейнера. Щоб визначати сигнали зупинки в життєвому циклі контейнера, поле spec.os.name Podʼа має бути заданим. Перелік допустимих сигналів залежить від ОС, на яку заплановано Pod. Для Podʼів, запланованих на вузли Windows, ми підтримуємо тільки SIGTERM і SIGKILL як допустимі сигнали.

Ось приклад специфікації Podʼа, що визначає власний сигнал зупинки:

spec:
  os:
    name: linux
  containers:
    - name: my-container
      image: container-image:latest
      lifecycle:
        stopSignal: SIGUSR1

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

Порядок завершення роботи Podʼа

Порядок завершення роботи Podʼа на прикладі:

  1. Ви використовуєте інструмент kubectl, щоб вручну видалити певний Pod, зі стандартним періодом коректного завершення (30 секунд).

  2. Pod в API-сервері оновлюється: записується час, після якого Pod вважається «мертвим», разом із періодом коректного завершення. Якщо ви використовуєте kubectl describe для перевірки Podʼа, який ви видаляєте, цей Pod показується як «Terminating». На вузлі, де працює Pod: щойно kubelet бачить, що Pod позначено як такий, що завершує роботу (встановлено тривалість коректного вимкнення), kubelet розпочинає локальний процес вимкнення Podʼа.

    1. Якщо один із контейнерів Podʼа має визначений хук preStop і terminationGracePeriodSeconds у специфікації Podʼа не встановлено в 0, kubelet виконує цей хук всередині контейнера. Стандартне значення terminationGracePeriodSeconds — 30 секунд.

      Якщо хук preStop все ще виконується після закінчення періоду коректного завершення, kubelet запитує невелике одноразове подовження цього періоду на 2 секунди.

      Примітка:

      Якщо хуку preStop потрібно більше часу для завершення, ніж дозволяє стандартний період коректного завершення, вам слід змінити terminationGracePeriodSeconds відповідно до цього.
    2. Kubelet ініціює надсилання середовищем виконання контейнерів сигналу TERM процесу 1 всередині кожного контейнера.

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

  3. Одночасно з тим, як kubelet розпочинає коректне вимкнення Podʼа, панель управління оцінює, чи слід вилучити цей Pod, що вимикається, з обʼєктів EndpointSlice, де ці обʼєкти представляють Service із налаштованим селектором. ReplicaSets та інші ресурси робочого навантаження більше не вважають такий Pod дійсною реплікою, що обслуговує запити.

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

    Будь-які точки доступу, які представляють Podʼи, що завершують роботу, не вилучаються негайно з EndpointSlices, а статус, який вказує на стан завершення, надається через API EndpointSlice. Точки доступу, що завершують роботу, завжди мають статус ready зі значенням false (для зворотної сумісності з версіями до 1.26), тому балансувальники навантаження не використовуватимуть їх для звичайного трафіку.

    Якщо потрібне очищення трафіку на Podʼі, що завершує роботу, фактичну готовність можна перевірити за станом serving. Докладніше про те, як реалізувати очищення зʼєднань, можна дізнатися в навчальному матеріалі Порядок завершення роботи Podʼів та Endpointʼів

  4. kubelet забезпечує завершення та вимкнення Podʼа.

    1. Коли період коректного завершення спливає, а в Podʼі все ще працює якийсь контейнер, kubelet ініціює примусове вимкнення. Середовище виконання контейнерів надсилає SIGKILL усім процесам, які ще працюють у будь-якому контейнері в Podʼі. Kubelet також прибирає прихований контейнер pause, якщо це середовище виконання контейнерів його використовує.
    2. kubelet переводить Pod у термінальну фазу (Failed або Succeeded залежно від кінцевого стану його контейнерів).
    3. kubelet ініціює примусове видалення обʼєкта Pod з API-сервера, встановлюючи період коректного завершення в 0 (негайне видалення).
    4. API-сервер видаляє API-обʼєкт Podʼа, який після цього більше не видимий для жодного клієнта.

Примусове завершення Podʼів

Увага:

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

Стандартно всі видалення є коректними протягом 30 секунд. Команда kubectl delete підтримує опцію --grace-period=<seconds>, яка дозволяє перевизначити стандартне значення власним.

Встановлення періоду коректного завершення в 0 примусово та негайно видаляє Pod з API-сервера. Якщо Pod все ще працював на вузлі, це примусове видалення змушує kubelet негайно розпочати прибирання.

Використовуючи kubectl, ви повинні вказати додатковий прапорець --force разом із --grace-period=0, щоб виконати примусове видалення.

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

Увага:

Негайне видалення не чекає підтвердження того, що запущений ресурс було завершено. Ресурс може продовжувати працювати в кластері нескінченно.

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

Завершення роботи Podʼа та sidecar-контейнери

Якщо ваш Pod містить один або більше sidecar-контейнерів (init-контейнерів з політикою перезапуску Always), kubelet затримає надсилання сигналу TERM цим sidecar-контейнерам, доки останній основний контейнер повністю не завершить роботу. Sidecar-контейнери будуть завершені у зворотному порядку, в якому вони визначені в специфікації Podʼа. Це забезпечує продовження обслуговування sidecar-контейнерами інших контейнерів у Podʼі, доки вони не стануть непотрібними.

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

Аналогічно, якщо Pod має хук preStop, який перевищує період коректного завершення, може статися аварійне завершення. Загалом, якщо ви використовували хуки preStop для керування порядком завершення без sidecar-контейнерів, тепер ви можете видалити їх і дозволити kubelet автоматично керувати завершенням роботи sidecar-контейнерів.

Збір сміття Podʼів

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

Збирач сміття Podʼів (PodGC), який є контролером панелі управління, прибирає завершені Podʼи (з фазою Succeeded або Failed), коли кількість Podʼів перевищує налаштований поріг (визначений параметром terminated-pod-gc-threshold в kube-controller-manager). Це запобігає витоку ресурсів під час створення та завершення Podʼів з часом.

Крім того, PodGC очищує будь-які Podʼи, які відповідають одній з таких умов:

  1. є осиротілими Podʼами — привʼязаними до вузла, якого вже не існує,
  2. є незапланованими Podʼами у стані завершення,
  3. є Podʼами у стані завершення, привʼязаними до неготового вузла з taint node.kubernetes.io/out-of-service.

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

Поведінка Podʼа під час перезапуску kubelet

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

Виявлення перезапусків kubelet

СТАН ФУНКЦІОНАЛУ: Deprecated since Kubernetes v1.35; (стандартно вимкнено)
More information about this feature

To use this feature, you (or a cluster administrator) will need to enable the ChangeContainerStatusOnKubeletRestart feature gate for all relevant components in your cluster.

See Enable Or Disable Feature Gates for more information.

Коли kubelet запускається, він перевіряє, чи є вже вузол із привʼязаними Podʼами. Якщо стан Ready вузла залишається незмінним, тобто стан не змінився з true на false, Kubernetes виявляє це як перезапуск kubelet. (Можна перезапустити kubelet іншими способами, наприклад, щоб виправити помилку вузла, але в таких випадках Kubernetes вибирає безпечний варіант і розглядає це як зупинку kubelet, а потім його запуск).

Коли kubelet перезапускається, статусами контейнерів керують по-різному залежно від налаштування функціональної можливості:

  • Стандартно kubelet не змінює статуси контейнерів після перезапуску. Контейнери, для яких було встановлено ready: true, залишаються готовими.

    Якщо ви зупините kubelet на достатньо довгий час, щоб він не пройшов серію перевірок пульсу вузла, а потім зачекаєте, перш ніж знову запустити kubelet, Kubernetes може почати виселяти Podʼи з цього вузла. Однак, навіть якщо виселення Podʼів починається, Kubernetes не позначає окремі контейнери в цих Podʼах як ready: false. Виселення на рівні Podʼа відбувається після того, як панель управління додає вузлу taint node.kubernetes.io/not-ready (через провал перевірок пульсу).

  • У Kubernetes 1.37 ви можете вибрати стару поведінку, за якої kubelet завжди змінює значення контейнерів ready після перезапуску kubelet на false.

    Ця стара поведінка довгий час була стандартною, але спричиняла проблеми для користувачів Kubernetes, особливо у великих розгортаннях. Хоча функціональна можливість дозволяє тимчасово повернутися до цієї старої поведінки, проєкт Kubernetes рекомендує подавати звіт про помилку, якщо ви зіткнулися з проблемами. Функціональну можливість ChangeContainerStatusOnKubeletRestart буде видалено в майбутньому.

Що далі

Змінено November 01, 2026 at 11:34 AM PST: [uk] Use «стан» for condition (061a68c3f7)