Ця сторінка описує життєвий цикл Podʼа. Podʼи слідують визначеному життєвому циклу, починаючи з фази Pending, переходячи до фази Running, якщо принаймні один з його основних контейнерів запускається добре, а потім до фаз Succeeded або Failed, залежно від того, чи завершився будь-який контейнер у Pod з помилкою.
Podʼи, подібно окремим контейнерам застосунків, вважаються відносно ефемерними (а не постійними) обʼєктами. Podʼи створюються, отримують унікальний ідентифікатор (UID) і призначаються вузлам, де вони залишаються до моменту завершення (відповідно до політики перезапуску) або видалення. Якщо вузол зазнає збою, Podʼи, призначені до цього вузла, призначаються для видалення після періоду затримки.
Поки Pod працює, kubelet може перезапускати контейнери, щоб вирішити деякі види несправностей. У межах Podʼа Kubernetes відстежує різні стани контейнера і визначає дії, які слід вжити, щоб знову забезпечити справність Podʼів.
В API Kubernetes у Pod є як специфікація, так і фактичний стан. Стан для обʼєкта Pod складається з набору станів Podʼа. Ви також можете додавати власні дані готовності в стани для Podʼів, якщо це корисно для вашого застосунку.
Podʼи плануються лише один раз протягом свого життя; призначення Podʼа до певного вузла називається привʼязка, а процес вибору який вузол використовувати, називається плануванням. Після того, як Pod було заплановано і привʼязано до вузла, Kubernetes намагається запустити цей Pod на цьому вузлі. Pod працює на цьому вузлі, доки не зупиниться, або доки його не буде завершено; якщо Kubernetes не може запустити Pod на вибраному вузлі (наприклад, якщо вузол аварійно завершить роботу до запуску Podʼа), то цей конкретний Pod ніколи не запуститься.
Ви можете використати Готовність Podʼів до планування щоб затримати планування Podʼа, доки не буде видалено всі його scheduling gates. Наприклад, ви можете визначити набір 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, наприклад volume, це означає, що ця річ існує стільки часу, скільки існує цей конкретний Pod (з таким самим UID). Якщо цей Pod буде видалений з будь-якої причини, і навіть якщо буде створений ідентичний замінник, повʼязана річ (у цьому прикладі — том) також буде знищена і створена знову.
Багатоконтейнерний Pod, який містить механізм отримання файлів sidecar і веб-сервер. Pod використовує ефемерний том emptyDir для спільного сховища для контейнерів.
Поле status обʼєкта PodStatus Podʼа містить поле phase.
Фази Podʼа — це простий, високорівневий підсумок того, на якому етапі свого життєвого циклу знаходиться Pod. Фаза не призначена бути всеосяжним підсумком спостережень за станом контейнера чи Podʼа, і бути процесом за спостереженням стану.
Кількість та значення фаз Podʼа є строго прописаними. Крім того, що зазначено тут, не слід вважати, що щось відомо про Podʼи з певним значенням phase.
Ось можливі значення для phase:
| Значення | Опис |
|---|---|
Pending |
Pod прийнятий кластером Kubernetes, але один чи кілька контейнерів ще не було налаштовано та готові до запуску. Це включає час, який Pod витрачає на очікування планування, а також час, який витрачається на завантаження образів контейнерів з мережі. |
Running |
Pod привʼязаний до вузла, і всі контейнери створені. Принаймні один контейнер все ще працює або перебуває у процесі запуску чи перезапуску. |
Succeeded |
Всі контейнери в Podʼі завершили роботу успішно і не будуть перезапущені. |
Failed |
Всі контейнери в Podʼі завершили роботу, і принаймні один контейнер завершився з помилкою. Іншими словами, контейнер вийшов зі статусом, відмінним від нуля, або його роботу завершила система, і контейнер не налаштований на автоматичний перезапуск. |
Unknown |
З якоїсь причини не вдалося отримати стан Podʼа. Ця фаза, як правило, виникає через помилку в комунікації з вузлом, де повинен виконуватися Pod. |
Якщо Podʼу не вдається кілька разів підряд стартувати, у полі Status деяких команд kubectl може зʼявитися відмітка CrashLoopBackOff. Аналогічно, під час видалення Podʼа у полі Status деяких команд kubectl може зʼявитися відмітка Terminating.
Переконайтеся, що ви не плутаєте Status, поле відображення kubectl, призначене для інтуїтивного сприйняття користувача, з phase. Фаза тесту є явною частиною моделі даних Kubernetes і документації Pod API.
NAMESPACE NAME READY STATUS RESTARTS AGE
alessandras-namespace alessandras-pod 0/1 CrashLoopBackOff 200 2d9h
Pod отримує час на відповідне завершення, який типово становить 30 секунд. Ви можете використовувати прапорець --force для примусового завершення роботи Podʼа.
Починаючи з Kubernetes 1.27, kubelet переводить видалені Podʼи, крім статичних Podʼів та примусово видалених Podʼів без завершувача, в термінальну фазу (Failed або Succeeded залежно від статусів exit контейнерів Podʼа) перед їх видаленням із сервера API.
Якщо вузол вмирає або відключається від іншої частини кластера, Kubernetes застосовує політику встановлення phase всіх Podʼів на втраченому вузлі у Failed.
Окрім фаз Podʼа загалом Kubernetes відстежує стан кожного контейнера всередині Podʼа. Ви можете використовувати хуки життєвого циклу контейнера, щоб запускати події на певних етапах життєвого циклу контейнера.
Як тільки планувальник призначає Pod вузлу, kubelet починає створювати контейнери для цього Podʼа, використовуючи середовище виконання контейнерів. Існує три можливі стани контейнера: Waiting (Очікування), Running (Виконання) та Terminated (Завершено).
Щоб перевірити стан контейнерів Podʼа, ви можете використовувати kubectl describe 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.
Kubernetes порається з відмовами контейнерів в межах Podʼів за допомогою політики перезапуску, визначеної в spec Podʼа. Ця політика визначає, як Kubernetes реагує на виходи контейнерів через помилки або інші причини, які складаються з наступних етапів:
restartPolicy. Це запобігає швидким, повторним спробам перезапуску, що може перенавантажити систему.CrashLoopBackOff: Це означає, що механізм затримки працює для певного контейнера, який знаходиться в циклі збоїв, невдач і постійного перезапуску.На практиці, CrashLoopBackOff — це стан або подія, яку можна помітити у виводі команди kubectl, при отриманні опису або перегляді списку Podʼів, коли контейнер в Podʼі не запускається належним чином, а потім безперервно намагається запуститися, але безуспішно.
Іншими словами, коли контейнер увійшов у цикл збоїв, Kubernetes застосовує експоненційну затримку, про яку було згадано в політиці перезапуску контейнера. Цей механізм запобігає збійному контейнеру перевантажувати систему безперервними невдалими спробами запуску.
CrashLoopBackOff може бути спричинений проблемами, такими як:
Failure, як згадано у розділі про перевірки.Щоб розібратися у причинах проблеми CrashLoopBackOff, користувач може:
kubectl logs <name-of-pod>, щоб перевірити логи контейнера. Це часто є безпосереднім способом діагностики проблеми, що викликає збої.kubectl describe pod <name-of-pod> для перегляду подій для Podʼа, які можуть надати підказки про проблеми конфігурації або ресурсів.Коли контейнер у вашому Podʼі зупиняється або зазнає збою, Kubernetes може його перезапустити. Перезапуск не завжди є доречним; наприклад, init контейнери запускаються лише один раз (у разі успіху), під час запуску Podʼа.
Ви можете налаштувати перезапуски як політику, що застосовується до всіх Podʼів, або за допомогою конфігурації на рівні контейнера (наприклад, коли ви визначаєте sidecar контейнер) або визначаєте перевизначення на рівні контейнера.
Проєкт Kubernetes рекомендує дотримуватися принципів хмарних технологій, включаючи відмовостійкий дизайн, який враховує неоголошені або довільні перезапуски. Ви можете досягти цього, або зупинивши Pod і покладаючись на автоматичну заміну, або ви можете спроєктувати відмовостійкість на рівні контейнера. Обидва підходи допомагають забезпечити доступність вашого загального навантаження, незважаючи на часткові збої.
У полі spec Podʼа є поле restartPolicy із можливими значеннями Always, OnFailure та Never. Стандартне значення — Always.
restartPolicy для Podʼа застосовується до контейнерів застосунків в Podʼі та до звичайних контейнерів ініціалізації. Контейнери Sidecar не звертають уваги на поле restartPolicy на рівні Podʼа: в Kubernetes, sidecar визначається як запис всередині initContainers, який має свою політику перезапуску контейнера на рівні контейнера, встановлену на Always. Для контейнерів ініціалізації, які завершують роботу із помилкою, kubelet виконує їх перезапуск, якщо політика перезапуску Podʼа встановлена як OnFailure або Always:
Always: автоматично перезапускає контейнер після його завершення, незалежно від статусу завершення.OnFailure: перезапускає контейнер тільки після його завершення з помилкою (код виходу відмінний від нуля).Never: ніколи автоматично не перезапускає контейнер, що завершив роботу.Коли kubelet обробляє перезапуск контейнера згідно з налаштованою політикою перезапуску, це стосується лише перезапусків, які призводять до заміни контейнерів всередині того ж Podʼа та на тому ж вузлі. Після завершення контейнерів у Podʼі, kubelet перезапускає їх із затримкою, що зростає експоненційно (10 с, 20 с, 40 с, …), і обмеженою пʼятьма хвилинами (300 секунд). Якщо контейнер виконується протягом 10 хвилин без проблем, kubelet скидає таймер затримки перезапуску для цього контейнера. Дивіться документацію про Контейнери Sidecar та життєвий цикл Podʼа, де пояснюється поведінка контейнерів ініціалізації при вказанні поля restartPolicy для нього.
Kubernetes v1.35 [beta](стандартно увімкнено)Якщо ваш кластер має функціональну можливість ContainerRestartRules, ви можете вказати restartPolicy та restartPolicyRules для індивідуальних контейнерів, щоб перевизначити політику перезапуску Podʼа. Політика перезапуску контейнера та правила застосовуються до контейнерів застосунків в Podʼі та до звичайних контейнерів ініціалізації.
Контейнер Sidecar, що є нативним для Kubernetes, має свою політику перезапуску контейнера, встановлену на 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, який має контейнер ініціалізації, що виконується лише один раз. Якщо контейнер ініціалізації зазнає невдачі, Pod зазнає невдачі. Це дозволяє Podʼу зазнати невдачі, якщо ініціалізація не вдалася, але також продовжувати працювати, як тільки ініціалізація буде успішною:
apiVersion: v1
kind: Pod
metadata:
name: fail-pod-if-init-fails
spec:
restartPolicy: Always
initContainers:
- name: init-once # Цей контейнер ініціалізації буде запущено лише один раз. Якщо він зазнає невдачі, Pod зазнає невдачі.
registry.k8s.io/busybox:1.27.2
command: ['sh', '-c', 'echo "Failing initialization" && sleep 10 && exit 1']
restartPolicy: Never
containers:
- name: main-container # Цей контейнер буде перезапущено, як тільки ініціалізація буде успішною.
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, збір сміття контейнерів, проблеми з перебоями підключенням до панелі управління можуть призвести до втрати стану, і контейнери можуть бути повторно запущені, навіть якщо ви очікуєте, що контейнер не буде перезапущено.
Kubernetes v1.35 [alpha](стандартно вимкнено)Якщо у вашому кластері ввімкнено функцію RestartAllContainersOnContainerExits, ви можете вказати RestartAllContainers як дію в restartPolicyRules на рівні контейнера. Коли вихід контейнера відповідає правилу з цією дією, весь Pod припиняється і перезапускається на місці.
Таке перезавантаження «на місці» є більш ефективним способом скидання стану Podʼа порівняно з повним видаленням і повторним створенням. Це особливо цінно для робочих навантажень, де перепланування є дорогим, наприклад, для пакетних завдань або завдань навчання AI/ML.
Коли спрацьовує дія RestartAllContainers, kubelet виконує наступні кроки:
terminationGracePeriodSeconds не враховується, а налаштовані хуки preStop не виконуються. Це забезпечує швидке вимкнення.emptyDir та змонтовані томиPodRestartInPlace, встановленим на True. Це робить процес перезапуску спостережуваним.PodRestartInPlace встановлюється на False, і Pod починає стандартний процес запуску:
Ключовим аспектом цієї функції є те, що всі контейнери перезапускаються, включаючи ті, які раніше були успішно завершені або зазнали невдачі. Дія RestartAllContainers замінює будь-яку налаштовану політику перезапуску на рівні контейнера або restartPolicy Podʼа.
Цей механізм корисний у сценаріях, коли необхідне повне очищення всіх контейнерів, наприклад:
init налаштовує середовище, яке може бути пошкоджене, ця функція забезпечує повторне виконання процесу налаштування.Розглянемо робоче навантаження, де sidecar-спостерігач відповідає за перезапуск основного застосунку з відомого хорошого стану, якщо він зустрічає помилку. Спостерігач може вийти з певним кодом, щоб ініціювати повний перезапуск Podʼа-робітника на місці.
apiVersion: v1
kind: Pod
metadata:
name: ml-worker
spec:
restartPolicy: Never # Под сам по собі не повинен перезапускатися, якщо на це немає явного дозволу.
initContainers:
- name: setup-environment
image: registry.k8s.io/busybox:1.27.2
command: ['sh', '-c', 'echo "Setting up environment"']
# Цей контейнер ініціалізації запускається один раз для підготовки середовища.
# Він запуститься знову після дії RestartAllContainers.
- name: watcher-sidecar
image: registry.k8s.io/busybox:1.27.2
# У реальному сценарії це буде спеціальний образ спостерігача.
# Ця команда імітує вихід спостерігача зі спеціальним кодом.
command: ['sh', '-c', 'sleep 60; exit 88']
restartPolicy: Always
restartPolicyRules:
- action: RestartAllContainers
exitCodes:
# Код виходу 88 викликає повний перезапуск пода.
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']
У цьому прикладі:
Never.watcher-sidecar виконує команду, а потім завершується з кодом 88.RestartAllContainers.setup-environment і контейнер main-application, перезапускається на місці. Pod зберігає свій UID, пісочницю, IP-адресу та томи.Kubernetes v1.33 [alpha](стандартно вимкнено)З увімкненою альфа-функціональною можливістю ReduceDefaultCrashLoopBackOffDecay повторні спроби запуску контейнера у вашому кластері скорочуватимуться до 1 с (замість 10 с) і експоненціально збільшуватимуться у 2 рази при кожному перезапуску до максимальної затримки 60 с (замість 300 с, тобто 5 хвилин).
Якщо ви використовуєте цю можливість з альфа-можливістю KubeletCrashLoopBackOffMax (див нижче), окремі вузли можуть мати різні значення максимальної затримки.
Kubernetes v1.35 [beta](стандартно увімкнено)З увімкненою функціональною можливістю KubeletCrashLoopBackOffMax ви можете змінити максимальну затримку між повторними спробами запуску контейнера, яка стандартно становить 300 секунд (5 хвилин). Ця конфігурація встановлюється для кожного вузла за допомогою конфігурації kubelet. У вашій конфігурації kubelet у полі crashLoopBackOff встановіть значення поля maxContainerRestartPeriod між 1s і 300s. Як описано вище у Політиці перезапуску контейнерів, затримки на цьому вузлі все одно починатимуться з 10 секунд і збільшуватимуться експоненціально у 2 рази при кожному перезапуску, але тепер вони будуть обмежені вашим налаштованим максимумом. Якщо значення maxContainerRestartPeriod, яке ви налаштували, менше початкового стандартного значення у 10 секунд, початкова затримка буде встановлена на максимальне значення.
Дивіться наступні приклади налаштування kubelet:
# затримки перезапуску контейнерів починаються з 10 секунд і збільшуються
# в 2 рази при кожному перезапуску, максимум до 100с
kind: KubeletConfiguration
crashLoopBackOff:
maxContainerRestartPeriod: "100s"
# затримки між перезапусками контейнера завжди будуть дорівнювати 2s
kind: KubeletConfiguration
crashLoopBackOff:
maxContainerRestartPeriod: "2s"
Якщо ви використовуєте цей параметр разом з альфа-версією ReduceDefaultCrashLoopBackOffDecay (описано вище), стандартні значення кластера для початкового і максимального очікування повтору будуть не 10 і 300 секунд, а 1 і 60 секунд. Конфігурація для кожного вузла має пріоритет над стандартними значеннями, встановленими ReduceDefaultCrashLoopBackOffDecay, навіть якщо це призведе до того, що вузол матиме довший максимальний час очікування, ніж інші вузли у кластері.
У Podʼа є статус, який містить масив PodConditions, через які Pod проходить чи не проходить. Kubelet управляє наступними PodConditions:
PodScheduled: Pod був запланований на вузол.PodReadyToStartContainers: (бета-функція; типово увімкнено) Pod sandbox був успішно створений, і була налаштована мережа.ContainersReady: всі контейнери в Pod готові.Initialized: всі контейнери ініціалізації успішно завершили виконання.Ready: Pod може обслуговувати запити і його слід додати до балансування навантаження всіх відповідних Services.DisruptionTarget: роботу Podʼа скоро буде припинено через розлади (наприклад, переважне право, виселення або збирання сміття).PodResizePending: було запитано зміну розміру пода, але її неможливо застосувати. Див. розділ Стан зміни розміру Podʼа.PodResizeInProgress: Pod перебуває в процесі зміни розміру. Дивіться Стан зміни розміру Podʼа.| Назва поля | Опис |
|---|---|
type |
Імʼя цього стану Podʼа. |
status |
Вказує, чи застосовується цей стан, з можливими значеннями "True", "False" або "Unknown". |
lastProbeTime |
Відмітка часу останнього запиту стану Podʼа. |
lastTransitionTime |
Відмітка часу для останнього переходу Podʼа з одного статусу в інший. |
reason |
Машиночитаний текст у форматі UpperCamelCase, який вказує причину останньої зміни стану. |
message |
Повідомлення, яке вказує подробиці щодо останнього переходу стану, яке може розібрати людина. |
Kubernetes v1.14 [stable]
Ваш застосунок може внести додатковий зворотний звʼязок або сигнали в PodStatus: готовність Podʼа. Щоб використовувати це, встановіть readinessGates в spec Podʼа, щоб вказати список додаткових станів, які kubelet оцінює для готовності Podʼа.
Стани готовності визначаються поточним станом полів 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.
Команда kubectl patch не підтримує зміну статусу обʼєкта накладанням патчів. Щоб встановити ці status.conditions для Podʼа, застосунки та оператори повинні використовувати дію PATCH. Ви можете використовувати бібліотеку клієнтів Kubernetes для написання коду, який встановлює власні стани Podʼа для готовності Podʼа.
Для Podʼа, який використовує власні стани, Pod оцінюється як готовий тільки коли застосовуються обидва наступні твердження:
readinessGates, рівні True.Коли контейнери Podʼа готові, але принаймні один власний стан відсутній або False, kubelet встановлює стан Podʼа ContainersReady в True.
Kubernetes v1.29 [beta]
PodHasNetwork.Після того, як Pod отримує призначення на вузол, йому потрібно бути допущеним до kubelet та мати встановлені всі необхідні томи зберігання. Як тільки ці фази завершаться, kubelet співпрацює з середовищем виконання контейнерів (використовуючи Інтерфейс середовища виконання контейнера), щоб налаштувати ізольоване середовище виконання та налаштувати мережу для Podʼа. Якщо функціональну можливість PodReadyToStartContainersCondition увімкнено (є типово увімкненою для Kubernetes 1.35), стан PodReadyToStartContainers буде додано до поля status.conditions Podʼа.
Стан PodReadyToStartContainers встановлюється в False kubeletʼом, коли він виявляє, що у Podʼа немає ізольованого середовища виконання із налаштованою мережею. Це трапляється в
наступних випадках:
Стан PodReadyToStartContainers встановлюється в True kubelet після успішного завершення створення і налаштування ізольованого середовища виконання для Podʼа за допомогою втулка виконання. Kubelet може почати витягувати образ контейнера та створювати контейнери після встановлення стану PodReadyToStartContainers в True.
Для Podʼа з контейнерами ініціалізації kubelet встановлює стан Initialized в True після успішного завершення контейнерів ініціалізації (що відбувається після успішного створення sandbox та налаштування мережі контейнером втулка виконання). Для Podʼа без контейнерів ініціалізації kubelet встановлює стан Initialized в True перед початком створення sandbox та налаштування мережі.
Kubernetes v1.35 [stable](стандартно увімкнено)Kubernetes підтримує зміну ресурсів CPU та памʼяті, виділених для Podʼів після їх створення. (Для інших ресурсів інфраструктури потрібно використовувати інші методи, специфічні для цих ресурсів.) Існує два основні підходи до зміни розміру CPU та памʼяті:
Ви можете змінити розмір ресурсів CPU та памʼяті на рівні контейнера Podʼа без повторного створення Podʼа. Це також називається вертикальним масштабуванням Podʼа на місці. Це дозволяє вам регулювати розподіл ресурсів для запущених контейнерів, потенційно уникаючи перебоїв у роботі застосунків.
Щоб виконати зміну розміру на місці, оновлюйте бажаний стан Podʼа за допомогою субресурсу /resize. Kubelet спробує застосувати нові значення ресурсів до контейнерів, що працюють. Pod conditions PodResizePending та PodResizeInProgress (описані в Станах Podʼа) вказують на стан операції зміни розміру. Для отримання додаткової інформації про стан зміни розміру див. Стан зміни розміру контейнера.
Основні моменти, які слід враховувати при зміні розміру на місці:
resizePolicy у специфікації контейнера.Детальні інструкції щодо зміни розміру на місці див. Зміна розміру ресурсів процесора та пам'яті, призначених контейнерам.
Хмарний підхід до зміни ресурсів Podʼа полягає у використанні ресурсу робочого навантаження, який ним керує (наприклад, Deployment або StatefulSet). Коли ви оновлюєте специфікації ресурсів у шаблоні Podʼа, контролер робочого навантаження створює нові Podʼи з оновленими ресурсами та припиняє роботу старих Podʼів відповідно до своєї стратегії оновлення.
Цей підхід:
Ви також можете використовувати VerticalPodAutoscaler для автоматичного управління рекомендаціями та оновленнями ресурсів Podʼів.
Проба (probe) — це діагностика, яку періодично виконує kubelet для контейнера. Для виконання діагностики kubelet або виконує код всередині контейнера, або виконує мережевий запит.
Існує чотири різних способи перевірки контейнера за допомогою проб. Кожна проба повинна визначати один з чотирьох цих механізмів:
execgrpcstatus відповіді рівний SERVING.httpGetGET до IP-адреси Podʼа з вказаним портом та шляхом. Діагностика вважається успішною, якщо код стану відповіді більший або рівний 200 і менше ніж 400.tcpSocketexec передбачає створення/розгалуження кількох процесів при кожному виконанні. В результаті використання проб з exec на кластерах з високою щільністю Podʼів, низькими інтервалами initialDelaySeconds, periodSeconds, конфігурування будь-якої проби з механізмом exec, може призвести до надмірного навантаження на центральний процесор вузла. У таких сценаріях розгляньте можливість використання альтернативних механізмів проб, щоб уникнути надмірного навантаження.Кожна проба має один із трьох результатів:
SuccessFailureUnknownKubelet може опціонально виконувати та реагувати на три типи проб для робочих контейнерів:
livenessProbeSuccess.readinessProbeFailure. Якщо в контейнері не проваджено пробу готовності, стандартний стан — Success.startupProbeSuccess.Для отримання докладнішої інформації щодо налаштування проб життєздатності, готовності або запуску дивіться Налаштування проб життєздатності, готовності та запуску.
Якщо процес у вашому контейнері може аварійно завершитися, коли виникає проблема або він стає несправним, вам можливо не потрібна проба життєздатності; kubelet автоматично виконає правильну дію згідно з політикою перезапуску Podʼа.
Якщо ви хочете, щоб роботу вашого контейнера було припинено та він був перезапущений у разі невдачі проби, то вказуйте пробу життєздатності та встановлюйте restartPolicy на Always або OnFailure.
Якщо ви хочете розпочати надсилання трафіку до Podʼа лише після успішної проби, вказуйте пробу готовності. У цьому випадку проба готовності може бути такою самою, як і проба життєздатності, але наявність проби готовності в специфікації означає, що Pod розпочне роботу без отримання будь-якого трафіку і почне отримувати трафік лише після успішності проби.
Якщо ви хочете, щоб ваш контейнер міг вимкнутися для обслуговування, ви можете вказати пробу готовності, яка перевіряє конкретний endpoint для готовності, відмінний від проби життєздатності.
Якщо ваш застосунок залежить від бекенд сервісів, ви можете реалізувати як пробу життєздатності, так і пробу готовності. Проба життєздатності пройде, коли саме застосунок є справним, але проба готовності додатково перевірить, що кожен необхідний сервіс доступний. Це допомагає уникнути направлення трафіку до Podʼів, які можуть відповідати лише повідомленнями про помилки.
Якщо вашому контейнеру потрібно працювати з великими даними, файлами конфігурації або міграціями під час запуску, ви можете використовувати пробу запуску. Однак, якщо ви хочете виявити різницю між застосунком, який зазнав невдачі, і застосунком, який все ще обробляє дані запуску, вам може більше підійти проба готовності.
EndpointSlice оновить свій стан: стан ready точки доступу буде встановлено у значення false, тому балансувальники навантаження не будуть використовувати Pod для звичайного трафіку. Дивіться Завершення роботи Podʼа для отримання додаткової інформації про те, як kubelet обробляє видалення Podʼа.Проби запуску корисні для Podʼів, в яких контейнери потребують багато часу, щоб перейти в режим експлуатації. Замість встановлення довгого інтервалу життєздатності, ви можете налаштувати окрему конфігурацію для спостереження за контейнером при запуску, встановивши час, більший, ніж дозволяв би інтервал життєздатності.
Якщо ваш контейнер зазвичай запускається довше, ніж \( initialDelaySeconds + failureThreshold \times periodSeconds \), вам слід вказати пробу запуску, яка перевіряє ту саму точку доступу, що й проба життєздатності. Типово для periodSeconds — 10 секунд. Потім ви повинні встановити його failureThreshold настільки великим, щоб дозволити контейнеру запускатися, не змінюючи стандартних значень проби життєздатності. Це допомагає захиститись від блокування роботи.
Оскільки Podʼи представляють процеси, які виконуються на вузлах кластера, важливо дозволити цим процесам завершувати роботу відповідним чином, коли вони більше не потрібні (замість раптового зупинення за допомогою сигналу KILL і відсутності можливості завершити роботу).
Мета дизайну полягає в тому, щоб ви могли запитувати видалення і знати, коли процеси завершуються, а також мати можливість гарантувати, що видалення врешті-решт завершиться. Коли ви запитуєте видалення Podʼа, кластер реєструє та відстежує призначений строк належного припинення роботи до того, як буде дозволено примусово знищити Pod. З цим відстеженням примусового завершення, kubelet намагається виконати належне завершення роботи Podʼа.
Зазвичай, з цим належним завершенням роботи, kubelet робить запити до середовища виконання контейнера з метою спроби зупинити контейнери у Podʼі, спочатку надсилаючи сигнал TERM (також відомий як SIGTERM) основному процесу в кожному контейнері з таймаутом для належного завершення. Запити на зупинку контейнерів обробляються середовищем виконання контейнера асинхронно. Немає гарантії щодо порядку обробки цих запитів. Багато середовищ виконання контейнерів враховують значення STOPSIGNAL, визначене в образі контейнера і, якщо воно відрізняється, надсилають значення STOPSIGNAL, визначене в образі контейнера, замість TERM. Після закінчення строку належного завершення роботи сигнал KILL надсилається до будь-яких залишкових процесів, а потім Pod видаляється з API Server. Якщо kubelet або служба управління середовищем виконання перезапускається під час очікування завершення процесів, кластер повторює спробу спочатку, включаючи повний початковий строк належного завершення роботи.
Сигнал зупинки, який використовується для завершення роботи контейнера, може бути визначено в образі контейнера за допомогою інструкції STOPSIGNAL. Якщо в образі контейнера не визначено жодного сигналу зупинки, для завершення роботи контейнера буде використано стандартний сигнал середовища виконання контейнера (SIGTERM як для containerd, так і для CRI-O).
Kubernetes v1.33 [alpha](стандартно вимкнено)Якщо увімкнено функціональну можливість ContainerStopSignals, ви можете налаштувати власний сигнал зупинки для ваших контейнерів з життєвого циклу контейнера. Для визначення сигналів зупинки у життєвому циклі контейнера потрібно, щоб поле spec.os.name контейнера було присутнім як умова для визначення сигналів зупинки. Перелік допустимих сигналів залежить від ОС, на якій запланований Pod. Для Podʼів, запланованих на вузли Windows, ми підтримуємо тільки SIGTERM і SIGKILL як допустимі сигнали.
Ось приклад специфікації для Podʼів, що визначає власний сигнал зупинки:
spec:
os:
name: linux
containers:
- name: my-container
image: container-image:latest
lifecycle:
stopSignal: SIGUSR1
Якщо в життєвому циклі визначено сигнал зупинки, він замінить сигнал, визначений в образі контейнера. Якщо у специфікації контейнера не визначено жодного сигналу зупинки, контейнер повернеться до стандартної поведінки.
Припинення роботи Podʼа проілюстровано у наступному прикладі:
Ви використовуєте інструмент kubectl, щоб вручну видалити певний Pod, з типовим значення строку належного припинення роботи (30 секунд).
В Podʼі в API-сервері оновлюється час, поза яким Pod вважається "мертвим", разом із строком належного припинення роботи. Якщо ви використовуєте kubectl describe для перевірки Podʼа, який ви видаляєте, цей Pod показується як "Terminating". На вузлі, на якому виконується Pod: як тільки kubelet бачить, що Pod був позначений як такий, що закінчує роботу (встановлений строк для належного вимкнення), kubelet розпочинає локальний процес вимкнення Podʼа.
Якщо один із контейнерів Podʼа визначає preStop хук, і terminationGracePeriodSeconds в специфікації Podʼа не встановлено на 0, kubelet виконує цей хук всередині контейнера. Стандартно terminationGracePeriodSeconds встановлено на 30 секунд.
Якщо preStop хук все ще виконується після закінчення строку належного припинення роботи, kubelet запитує невелике подовження строку належного припинення роботи в розмірі 2 секунд.
preStop хук потребує більше часу для завершення, ніж дозволяє стандартний строк належного припинення роботи, вам слід змінити terminationGracePeriodSeconds відповідно до цього.Kubelet робить виклик до середовища виконання контейнера для надсилання сигналу TERM процесу 1 всередині кожного контейнера.
Є спеціальний порядок, якщо для Podʼа вказані будь-які контейнери sidecar. В іншому випадку контейнери в Podʼі отримують сигнал TERM у різний час і в довільному порядку. Якщо порядок завершення роботи має значення, розгляньте можливість використання хука preStop для синхронізації (або перейдіть на використання контейнерів sidecar).
У той же час, коли kubelet розпочинає належне вимкнення Podʼа, панель управління оцінює, чи слід вилучити цей Pod з обʼєктів EndpointSlice, де ці обʼєкти представляють Service із налаштованим селектором. ReplicaSets та інші ресурси робочого навантаження більше не розглядають такий Pod як дійсний.
Podʼи, які належним чином завершують роботу, не повинні продовжувати обслуговувати звичайний трафік і повинні почати процес завершення роботи та завершення обробки відкритих зʼєднань. Деякі застосунки потребують більше часу для належного завершення роботи, наприклад, сесії піготовки до обслуговування та завершення.
Будь-які точки доступу, які представляють Podʼи, що закінчують свою роботу, не вилучаються негайно з EndpointSlices, а статус, який вказує на стан завершення, експонується з EndpointSlice API. Точки доступу, які завершуть роботу, завжди мають статус ready як false (для сумісності з версіями до 1.26), тому балансувальники навантаження не будуть використовувати його для звичайного трафіку.
Якщо трафік на Podʼі, що завршеє свою роботу, ще потрібний, фактичну готовність можна перевірити як стан serving. Детальніше про те, як реалізувати очищення зʼєднань, можна знайти в розділі Порядок завершення роботи Podʼів та Endpointʼів
kubelet забезпечує завершення та вимкнення Podʼа.
SIGKILL всім процесам, які ще працюють у будь-якому контейнері в Podʼі. kubelet також очищає прихований контейнер pause, якщо цей контейнер використовується.Failed або Succeeded залежно від кінцевого стану його контейнерів).Типово всі видалення є належними протягом 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 (init-контейнерів з політикою перезапуску Always), kubelet затримає надсилання сигналу TERM цим контейнерам sidecar, доки останній основний контейнер повністю не завершить роботу. Контейнери sidecar будуть завершені у зворотному порядку, в якому вони визначені в специфікації Podʼа. Це забезпечує продовження обслуговування контейнерами sidecar інших контейнерів у Podʼі, доки вони не стануть непотрібними.
Це означає, що повільне завершення роботи основного контейнера також затримає завершення роботи контейнерів sidecar. Якщо період очікування закінчиться до закінчення процесу завершення роботи, Pod може перейти в стан примусового завершення. У цьому випадку всі залишкові контейнери в Podʼі будуть завершені одночасно з коротким періодом очікування.
Аналогічно, якщо Pod має хук preStop, який перевищує період очікування завершення, може статися аварійне завершення. Загалом, якщо ви використовували хуки preStop для керування порядком завершення без контейнерів sidecar, тепер ви можете видалити їх і дозволити kubelet автоматично керувати завершенням роботи контейнерів sidecar.
Для несправних Podʼів обʼєкти API залишаються в API кластера, поки людина чи контролер явно їх не видалять.
Збірник сміття Podʼів (PodGC), який є контролером панелі управління, прибирає завершені Podʼи (з фазою Succeeded або Failed), коли кількість Podʼів перевищує налаштований поріг (визначений параметром terminated-pod-gc-threshold в kube-controller-manager). Це запобігає витоку ресурсів при створенні та завершенні Podʼів з часом.
Крім того, PodGC очищує будь-які Podʼи, які відповідають одній з наступних умов:
node.kubernetes.io/out-of-service.Разом із прибиранням Podʼів, PodGC також позначає їх як несправнені, якщо вони перебувають в незавершеній фазі. Крім того, PodGC додає стан розладу Podʼа під час очищення осиротілого Podʼа. Див. стани розладу Podʼів для отримання докладніших відомостей.
Якщо ви перезапускаєте kubelet, Podʼи (та їхні контейнери) продовжують працювати навіть під час перезапуску. Коли на вузлі працюють Podʼи, зупинка або перезапуск kubelet на цьому вузлі не призводить до того, що kubelet зупиняє всі локальні Podʼи перед тим, як зупинитися сам. Щоб зупинити Podʼи на вузлі, ви можете використовувати kubectl drain.
Kubernetes v1.35 [deprecated](стандартно вимкнено)Коли kubelet запускається, він перевіряє, чи є вже вузол із привʼязаними Podʼами. Якщо стан Ready вузла залишається незмінним, тобто стан не змінився з true на false, Kubernetes виявляє це як перезапуск kubelet. (Можна перезапустити kubelet іншими способами, наприклад, щоб виправити помилку вузла, але в таких випадках Kubernetes вибирає безпечний варіант і розглядає це як зупинку kubelet, а потім його запуск).
Коли kubelet перезапускається, статуси контейнерів керуються різним чином залежно від налаштувань функціональної можливості:
Типово kubelet не змінює стан контейнерів після перезапуску. Контейнери, які були в стані ready: true, залишаються готовими.
Якщо ви зупините kubelet на достатньо довгий час, щоб він не пройшов серію перевірок node heartbeat, а потім зачекаєте, перш ніж знову запустити kubelet, Kubernetes може почати виселяти Podʼи з цього вузла. Однак, навіть якщо виселення Podʼів починається, Kubernetes не позначає окремі контейнери в цих Podʼах як ready: false. Виселення на рівні Podʼа відбувається після того, як панель управління позначає вузол як node.kubernetes.io/not-ready (через провал перевірок heartbeat)
У Kubernetes 1.35 ви можете вибрати стару поведінку, за якої kubelet завжди змінює значення контейнерів ready після перезапуску kubelet на false. Ця стара поведінка довгий час була стандартною, але спричиняла проблеми для користувачів Kubernetes, особливо у великих розгортаннях. Хоча функціональна можливість дозволяє тимчасово повернутися до цього старого режиму роботи, проєкт Kubernetes рекомендує подавати звіт про помилку, якщо ви зіткнулися з проблемами. Функціональну можливість ChangeContainerStatusOnKubeletRestart буде видалено в майбутньому.
Отримайте практичний досвід прикріплення обробників до подій життєвого циклу контейнера.
Отримайте практичний досвід налаштування проб Liveness, Readiness та Startup.
Дізнайтеся більше про обробники життєвого циклу контейнера.
Дізнайтеся більше про контейнери sidecar.
Для докладної інформації про статус Podʼа та контейнера в API, перегляньте документацію API, яка охоплює status для Podʼа.