Модуль 1.9: Основи налагодження (теорія)
Складність:
[ШВИДКИЙ]— мислення для швидкого сортування проблем у Kubernetes 1.35+Час на проходження: 35–45 хвилин
Передумови: Модулі 1.1–1.8, базовий доступ через
kubectlдо тренувального кластера та локальна звичка визначатиalias k=kubectlперед використанням коротких командkу цьому модулі
Результати навчання
Розділ «Результати навчання»Використовуйте наведені нижче результати як практичні орієнтири для своїх нотаток, лабораторних робіт і відповідей на тест упродовж усього модуля:
- Налагодити несправне робоче навантаження, дотримуючись повторюваного шляху сортування проблем у Kubernetes — від симптому до ймовірної першопричини.
- Проаналізувати фазу Pod’а, стан контейнера, умови (conditions), події та логи, щоб вирішити, який сигнал є найважливішим у сценарії збою.
- Порівняти збої завантаження образу, планування, циклу аварійних перезапусків, нестачі пам’яті та проб (probes) за їхніми спостережуваними доказами, а не за здогадками.
- Оцінити, до чого належить проблема — до застосунку, специфікації Pod’а, планувальника, ноди чи розгортання контролера.
- Спроєктувати контрольний список першого реагування, який зберігає докази, звужує область пошуку та не дає інциденту погіршитися.
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Пізно ввечері у четвер платіжна компанія викотила невеликий реліз оформлення замовлення, який змінив спосіб завантаження облікових даних бази даних її API. Старі Pod’и продовжували обслуговувати трафік, але новий ReplicaSet породжував Pod’и, що перезапускалися кожні кілька секунд, і Deployment застопорився, поки кошики клієнтів періодично давали збій. Згодом звіт про інцидент оцінив утрату понад $85 000 на покинутих транзакціях упродовж першої години, проте найдорожчою помилкою була не сама хибна конфігурація, а те, що перший фахівець, який реагував, видалив Pod’и та перезапустив розгортання ще до того, як хтось зафіксував логи попереднього контейнера, де було названо відсутню змінну середовища.
Така сцена є поширеною, бо збої Kubernetes надходять як стиснуті симптоми, а не як охайні пояснення. Одне-єдине слово на кшталт Pending, Running, CrashLoopBackOff чи ImagePullBackOff може представляти зовсім різні межі відповідальності, і фахівець, який надто рано вгадує, може півгодини ганятися за хибним компонентом. Основи налагодження дають вам дисциплінований спосіб запитати по черзі: чи зміг Kubernetes розмістити Pod, чи зміг kubelet його підготувати, чи запустився процес контейнера, чи залишився застосунок живим і чи стало робоче навантаження готовим приймати трафік.
KCNA не вимагає від вас розв’язувати кожен виробничий інцидент з пам’яті, але очікує, що ви розпізнаєте, де Kubernetes записує докази і чим рішення площини управління відрізняються від фактів на рівні ноди та застосунку. У цьому модулі ви потренуєтеся читати статус Pod’а як хронологію подій, використовувати describe, логи та події для їхніх окремих завдань і проєктувати контрольний список першого реагування, який звужує проблему ще до зміни кластера. Створіть короткий псевдонім командою alias k=kubectl; відтепер команди використовують k get, k describe та споріднені форми, бо саме таку звичку оператора ви побачите в реальних кластерах.
Частина 1: Налагодження — це збір доказів перед дією
Розділ «Частина 1: Налагодження — це збір доказів перед дією»Налагодження Kubernetes починається зі стриманості, бо перша команда може або зберегти докази, або стерти їх. Видалення Pod’а, перезапуск розгортання чи ручне редагування можуть тимчасово змінити видимий симптом, водночас приховавши початкову причину — особливо коли цикл аварійних перезапусків містить корисні попередні логи або коли короткочасні події застарівають. Досвідчені фахівці уповільнюються на кілька хвилин не тому, що їм подобається процедура, а тому, що кластер уже видає свідків: специфікація об’єкта каже, що було запрошено, планувальник каже, чи вдалося розміщення, kubelet каже, що сталося на ноді, а застосунок каже, чому його процес зазнав збою.
Уявіть кластер як кількох свідків, що описують той самий інцидент під різними кутами. Специфікації Deployment, ReplicaSet і Pod описують бажаний стан, зокрема назви образів, команди, запити ресурсів, проби, посилання на змінні середовища та томи. Планувальник пояснює, чому Pod отримав чи не отримав ноду, тоді як kubelet пояснює завантаження образів, створення контейнерів, збої проб, перезапуски та локальний тиск на ресурси. Логи застосунку — це ще один свідок, але вони існують лише після того, як процес справді запустився, ось чому логи потужні для циклів аварійних перезапусків і майже марні для Pod’ів, які так і не були заплановані.
KUBERNETES DEBUGGING WITNESSES
┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐│ Desired State │ │ Cluster Decisions │ │ Runtime Evidence ││ Deployment, Pod │────▶│ Scheduler, events │────▶│ Kubelet, logs ││ spec, probes, env │ │ placement, reasons │ │ exits, restarts │└────────────────────┘ └────────────────────┘ └────────────────────┘ │ │ │ ▼ ▼ ▼ "What did we ask for?" "What did Kubernetes try?" "What actually ran?"Перше класифікаційне запитання — не «Яке виправлення мені спробувати?», а «Яка частина системи вже діяла?». Якщо Pod не має призначеної ноди, головним свідком досі є планувальник, тож читати логи застосунку передчасно. Якщо Pod має ноду, але образ не вдається завантажити, kubelet розповідає вам про докази щодо реєстру, автентифікації, тегу чи мережі ще до того, як контейнер існує. Якщо контейнер запустився та завершився, центральними стають попередні логи й останній стан, а якщо процес живий, але не готовий, події проб і ендпоінти Сервісу зазвичай пояснюють, чому трафік стримується.
THE FIRST RESPONSE LOOP
┌───────────────┐│ 1. Scope │ k get pods -A -o wide│ problem size │ One pod, one node, one namespace, or many?└───────┬───────┘ │ ▼┌───────────────┐│ 2. Describe │ k describe pod <pod> -n <namespace>│ object story │ Conditions, container states, events, mounts, probes└───────┬───────┘ │ ▼┌───────────────┐│ 3. Read logs │ k logs <pod> -n <namespace> [-p] [-c <container>]│ app witness │ Current or previous container output└───────┬───────┘ │ ▼┌───────────────┐│ 4. Widen view │ k get events -n <namespace> --sort-by=.lastTimestamp│ timeline │ Related failures from scheduler, kubelet, and controllers└───────────────┘Цей цикл навмисно простий, бо тиск інциденту карає за дотепну, але непослідовну поведінку. Спершу йде визначення області, щоб ви знали, чи дивитеся на один Pod, один простір імен, одну ноду, одне розгортання чи на ширший збій кластера. describe йде рано, бо він поєднує бажаний стан, поточний статус, стан контейнера, умови та події в одному поданні. Логи йдуть після того, як ви знаєте, що контейнер запускався, а події розширюють хронологію, коли вам потрібні повідомлення планувальника, kubelet чи контролера, яких немає у виводі застосунку.
Зупиніться та спрогнозуйте: колега каже: «Pod зламаний, тож я видалю його і дам Kubernetes створити заново». Перш ніж читати далі, визначте, коли ця дія може бути безпечною, а коли вона може знищити найкращу підказку, яку ви маєте.
Видалення Pod’а, керованого Deployment, може бути розумним кроком відновлення після того, як докази зібрано, бо контролер створить заміну з того самого шаблону. Це поганий перший крок, коли попередній екземпляр мав єдиний корисний стек викликів, коли важливий порядок подій або коли вам ще потрібно з’ясувати, що зазнало збою першим — планувальник, kubelet чи застосунок. Безпечніша звичка — зафіксувати статус, попередні логи та події, сформулювати гіпотезу, а потім вирішити, чи відповідає доказам перезапуск, відкат, виправлення Secret, зміна ресурсів або коригування проби.
Корисний спосіб тренувати стриманість — описати збій у термінах відповідальності перш ніж щось чіпати. «Планувальник не призначив ноду» спрямовує вас до ресурсів, taint’ів, affinity, топології чи прив’язки сховища. «kubelet не може завантажити образ» спрямовує до тегів, облікових даних реєстру та доступності мережі. «Застосунок запустився та завершився з відсутнім налаштуванням» спрямовує до конфігурації та відповідальності за реліз. Така мова відповідальності запобігає класичній помилці початківця — вважати кожен червоний Pod помилкою застосунку чи кожну помилку застосунку помилкою Kubernetes. Назвавши власника вголос ще до першої команди, ви також полегшуєте собі вибір правильного джерела доказів, бо кожен власник має свого свідка: планувальник, kubelet чи сам процес застосунку.
Частина 2: Читайте стан Pod’а як хронологію
Розділ «Частина 2: Читайте стан Pod’а як хронологію»Рядок статусу Pod’а — це стиснута хронологія, а не остаточний діагноз. STATUS у k get pods часто показує причину з боку контейнера, вибрану для зручності читання людиною, тоді як фаза Pod’а — це ширша категорія життєвого циклу, як-от Pending, Running, Succeeded, Failed чи Unknown. Ця різниця важлива, бо Pod може бути у фазі Running, поки один контейнер не готовий, і Pod може здаватися Pending тому, що його не заплановано, або тому, що його вже призначено ноді, поки kubelet готує образи й томи.
k get pods -n default -o wideNAME READY STATUS RESTARTS AGE IP NODEapi-6d8b7c9f5c-f2mzp 0/1 CrashLoopBackOff 9 18m 10.244.1.8 worker-aweb-76bc6c9d7b-9nq5p 1/1 Running 0 42m 10.244.2.4 worker-breport-5d9c997d8d-xr2hg 0/1 Pending 0 11m <none> <none>Стовпець READY каже вам, скільки звичайних контейнерів готові порівняно з тим, скільки їх визначає Pod. Стовпець STATUS подає стислу причину, що часто походить від найважливішого поточного чи нещодавнього стану контейнера, тоді як RESTARTS каже вам, чи kubelet неодноразово запускав контейнер після завершення. Стовпець NODE не менш важливий за драматичніший текст статусу, бо відсутня нода означає, що планувальник не розмістив Pod, а названа нода означає, що розслідування перейшло до доказів kubelet, образу, тому, проби, ресурсів чи застосунку.
POD LIFECYCLE STATE DIAGRAM
┌──────────┐ Pod created │ │ ────────────▶│ Pending │──── Scheduler cannot place pod │ │ because resources, taints, └────┬─────┘ affinity, or volumes block it │ │ Scheduled to a node ▼ ┌──────────┐ │ Waiting │──── Kubelet is preparing containers, │ │ pulling images, or mounting volumes └────┬─────┘ │ │ Containers started ▼ ┌──────────┐ ┌────────────┐ │ Running │────▶│ Terminated │ │ │ │ │ └────┬─────┘ └─────┬──────┘ │ │ │ ▼ │ ┌──────────────┐ │ │ Restarted or │ │ │ stays failed │ │ └──────────────┘ ▼ ┌───────────┐ │ Succeeded │──── Normal for Jobs when all containers exit 0 └───────────┘
Special: Unknown means the control plane cannot determine pod state from the node.Перекладіть кожен видимий статус у сфокусоване запитання. Pending запитує, чи призначив планувальник ноду, а якщо ні — яке правило планування заблокувало розміщення. ImagePullBackOff запитує, чи може kubelet дістатися реєстру й автентифікуватися в ньому та чи існує згаданий образ. CrashLoopBackOff запитує, що надрукував чи з яким кодом завершився попередній екземпляр контейнера, тоді як Running із готовністю 0/1 запитує, яка умова чи проба заважає трафіку Сервісу. Такий переклад утримує вас від запуску знайомих команд, що не відповідають стадії збою.
| Сигнал | Найкорисніше перше запитання | Найкращі перші докази |
|---|---|---|
Pending без ноди | Чому планувальник не зміг розмістити цей Pod? | Розділ Events у k describe pod |
ImagePullBackOff | Яку саме помилку завантаження образу повідомив kubelet? | Події Pod’а з k describe pod |
CrashLoopBackOff | Чому завершився попередній контейнер? | k logs <pod> -p та Last State |
Running, але не Ready | Яка умова готовності чи проба зазнає збою? | Умови Pod’а, ендпоінти та події проб |
OOMKilled | Чи перевищив контейнер свій ліміт пам’яті? | Причина Last State, код виходу, ліміти ресурсів |
Unknown | Чи нода недосяжна або несправна? | Умови ноди та події ноди |
Умови Pod’а дають структурованіше подання, ніж однорядковий статус, бо вони показують, які віхи життєвого циклу є істинними чи хибними. PodScheduled означає, що планувальник призначив ноду, Initialized означає, що init-контейнери завершилися, ContainersReady означає, що всі контейнери застосунку звітують про готовність, а Ready означає, що Pod має приймати трафік через Сервіси, які його обирають. Pod може бути живим, але некорисним, якщо Ready хибний, і саме тому Kubernetes відокремлює існування процесу від придатності приймати трафік.
| Умова | Що вона означає | Інтерпретація для налагодження |
|---|---|---|
PodScheduled | Pod призначено ноді. | Якщо хибна, зосередьтеся на подіях планувальника, ресурсах, taint’ах, affinity та томах. |
Initialized | init-контейнери успішно завершилися. | Якщо хибна, перевірте логи init-контейнерів та налаштування томів чи дозволів. |
ContainersReady | Усі контейнери застосунку звітують про готовність. | Якщо хибна, перевірте стани контейнерів, проби готовності та помилки залежностей. |
Ready | Pod має приймати трафік Сервісу. | Якщо хибна, трафік не слід маршрутизувати до цього Pod’а, навіть якщо він запущений. |
Стани контейнерів конкретніші за умови Pod’а, бо кожен звичайний, init- чи sidecar-контейнер може окремо перебувати у стані очікування, виконання чи завершення. У багатоконтейнерному Pod’і логувальний sidecar може бути справним, поки головний API дає збій, або init-контейнер може блокувати весь Pod ще до запуску образу застосунку. Завжди називайте контейнер через -c <container>, коли логи чи стан неоднозначні, і використовуйте поточний стан разом з останнім станом, щоб зрозуміти і те, що відбувається зараз, і те, що сталося під час попередньої спроби.
| Стан контейнера | Значення | Що перевірити |
|---|---|---|
Waiting | Контейнер не запустився або відкочується перед наступною спробою запуску. | Поле reason, як-от ImagePullBackOff, ContainerCreating чи CrashLoopBackOff. |
Running | Процес наразі виконується всередині контейнера. | Час запуску, готовність, проби та чи були нещодавно перезапуски. |
Terminated | Процес завершився або був завершений примусово. | Код виходу, причина, час завершення та попередні логи з k logs -p. |
Що сталося б, якби ви подивилися лише на
k get pods, побачилиRunningі сказали команді, що сервіс справний? Поясніть, чому це може бути хибним, коли стовпецьREADYпоказує0/1.
Зріле прочитання стану Pod’а уникає двох пасток, що трапляються і на іспитах, і на реальних чергуваннях. Перша пастка — вважати стовпець STATUS людським діагнозом, тоді як це лише підказка, згенерована зі стану життєвого циклу в один момент. Друга пастка — припускати, що всі збої є збоями застосунку; Kubernetes може бути не в змозі запланувати Pod, змонтувати том, завантажити образ, задовольнити пробу чи утримати ноду на зв’язку, навіть коли код застосунку правильний. Уникнути обох пасток допомагає одна проста дисципліна: ставтеся до кожного значення статусу як до запитання, на яке ще треба відповісти, а не як до готового вердикту, і завжди звіряйте його з іншим джерелом доказів, перш ніж діяти.
Частина 3: Використовуйте describe, логи та події, не змішуючи їхніх завдань
Розділ «Частина 3: Використовуйте describe, логи та події, не змішуючи їхніх завдань»k describe pod — найкращий міст між бажаним станом і поведінкою кластера. Він показує ідентичність, мітки, посилання на власників, призначення ноди, IP-адреси, умови, змонтовані томи, посилання на змінні середовища, стани контейнерів, запити й ліміти ресурсів, проби та нещодавні події в одній команді. Така широта корисна, бо реальні інциденти часто містять суперечності — як-от контейнер, що успішно запускається, але провалює готовність, Pod, який заплановано, але заблоковано монтуванням тому, або Deployment, чиї нові Pod’и всі дають збій, поки старий ReplicaSet лишається справним.
k describe pod api-6d8b7c9f5c-f2mzp -n defaultЧитаючи describe, дотримуйтеся послідовного порядку, щоб ваші очі не стрибали хаотично виводом. Спершу підтвердьте простір імен, ім’я, мітки та власника, бо налагодження не того об’єкта трапляється частіше, ніж люди визнають. Потім перевірте ноду, фазу, умови та стан контейнера, приділяючи пильну увагу останньому стану, лічильнику перезапусків, ресурсам, команді, аргументам і пробам. Нарешті, читайте розділ Events від найстаршого доречного рядка до найновішого доречного рядка, бо нижня частина часто каже вам, що kubelet чи планувальник наразі повторно намагається зробити.
HOW TO READ kubectl describe pod
┌──────────────────────────────┐│ Identity │ Name, namespace, labels, owner, node├──────────────────────────────┤│ Status and Conditions │ Phase, Ready, ContainersReady, Scheduled├──────────────────────────────┤│ Container Details │ Image, ports, command, state, last state├──────────────────────────────┤│ Configuration References │ Env, ConfigMaps, Secrets, volumes, probes├──────────────────────────────┤│ Events │ Scheduler and kubelet timeline of actions└──────────────────────────────┘Логи відповідають на вужче запитання: що процес контейнера записав у стандартний вивід і стандартний потік помилок. Вони центральні, коли процес запустився та завершився, але вони не пояснюють незапланований Pod, тег образу, який не вдається отримати, або PersistentVolumeClaim, який не може прив’язатися. Для циклів аварійних перезапусків прапорець -p зазвичай є різницею між тим, щоб побачити справжній збій запуску, і тим, щоб не побачити нічого корисного з поточної спроби очікування.
k logs api-6d8b7c9f5c-f2mzp -n defaultk logs api-6d8b7c9f5c-f2mzp -n default -pk logs api-6d8b7c9f5c-f2mzp -n default -c apiПодії відповідають на те, що компоненти Kubernetes намагалися зробити і чому ці спроби вдалися чи провалилися. Події планувальника пояснюють збої розміщення, події kubelet пояснюють завантаження образів, життєвий цикл контейнера, результати проб і збої монтування, а події контролера можуть пояснити перебіг розгортання. Події в більшості кластерів обмежені в часі, тож вони не є заміною централізованих логів і метрик, але вони часто є найсвіжішими й найзрозумілішими доказами, поки початківець вчиться, як компоненти кластера звітують про роботу.
k get events -n default --sort-by=.lastTimestampПрактичне правило — не перетинати потоки доказів надто рано. Якщо подія каже 0/3 nodes are available: 3 Insufficient memory, код застосунку не є вашим першим напрямком розслідування, бо контейнер ніколи не мав місця для запуску. Якщо попередні логи кажуть FATAL: missing DB_PASSWORD, описувати кожну ноду в кластері — це відволікання, бо застосунок уже назвав залежність запуску. Найшвидші оператори — не ті, хто знає найдовший список команд; це ті, хто дозволяє кожному сигналу обирати наступну команду.
Компроміс полягає в тому, що жодне джерело доказів не є повним. describe може показати лаконічну подію, якій потрібен контекст з маніфесту, логи можуть показати помилку застосунку, не доводячи, як було змонтовано змінну середовища, а події можуть підсумувати повторюваний збій, не зберігаючи кожну історичну спробу. Ви розв’язуєте це, поєднуючи джерела в хронологію: бажаний стан запросив X, Kubernetes спробував Y, нода повідомила Z, а застосунок або запустився, або ні. Така хронологія дає вам обґрунтовану наступну дію замість здогадки.
Ще одна корисна звичка — записати, чого кожне джерело доказів не може вам сказати. Статус Pod’а не може довести, чому застосунок аварійно завершився. Логи не можуть довести, що Сервіс маршрутизує трафік. Події не можуть довести, що виправлена конфігурація досягла кожного нового Pod’а. Цей негативний простір важливий, бо він утримує вас від переоцінки однієї підказки і природно вказує на наступну команду, яка має підтвердити чи відкинути вашу гіпотезу.
В командних інцидентах така чіткість також покращує комунікацію. Сказати «Pod у статусі Pending, бо планувальник повідомляє про нестачу пам’яті» значно корисніше, ніж сказати «Pod зламаний». Сказати «контейнер запустився та завершився, повідомивши про відсутній ключ Secret» дає власнику застосунку чи платформи точну передачу. Хороша мова налагодження описує спостережувану стадію, джерело доказів і наступну безпечну дію, щоб інший інженер міг проаудитувати ваші міркування, не переграючи кожну команду. Така точність також пришвидшує передачу між змінами: фахівець, який заступає на чергування, одразу бачить, що вже перевірено, яка гіпотеза наразі активна та яка дія чекає на підтвердження, замість того щоб починати розслідування з нуля.
Частина 4: Робочий приклад — діагностуйте, перш ніж виправляти
Розділ «Частина 4: Робочий приклад — діагностуйте, перш ніж виправляти»Припустімо, команда розгортає версію 1.8.2 API, і розгортання застопорюється. Старі Pod’и продовжують обслуговувати трафік, але новий ReplicaSet створює Pod’и, які так і не стають готовими, і релізний менеджер запитує, чи це поганий образ, проблема планування чи проблема застосунку. Дисциплінований фахівець спершу визначає область збою, бо патерн «старі Pod’и справні, а нові несправні» вказує на новий шаблон, новий образ чи конфігурацію, яку використовує лише нова версія.
k get pods -n shop -o wideNAME READY STATUS RESTARTS AGE NODEapi-58c7d5f9b6-m2q8x 1/1 Running 0 2d worker-aapi-58c7d5f9b6-r6ndk 1/1 Running 0 2d worker-bapi-7b9c6d4f78-jk2tp 0/1 CrashLoopBackOff 6 9m worker-aЦей вивід уже виключає кілька можливостей. Новий Pod має ноду, тож планувальник його розмістив. Це не збій завантаження образу, бо статус — це цикл аварійних перезапусків, а не причина завантаження образу, і лічильник перезапусків доводить, що процес контейнера запускався більш ніж один раз. Отже, найвагоміші перші докази — це попередні логи нового Pod’а, бо процес, імовірно, надрукував свій збій запуску перед завершенням.
k logs api-7b9c6d4f78-jk2tp -n shop -p2026-04-26T09:15:12Z starting api service2026-04-26T09:15:12Z loading configuration from environment2026-04-26T09:15:12Z FATAL missing required environment variable: DB_PASSWORDПовідомлення логу вагоме, але старший фахівець усе одно перевіряє, як Kubernetes попросили надати це налаштування. Застосунок каже, що йому потрібен DB_PASSWORD; describe може показати, чи це значення береться з Secret, чи має контейнер останній стан і код виходу, що відповідають збою, і чи показують події kubelet повторюваний відкат. Така перевірка запобігає надто швидкому висновку на кшталт «база даних не працює», коли справжній збій — це відсутня конфігурація.
k describe pod api-7b9c6d4f78-jk2tp -n shopState: Waiting Reason: CrashLoopBackOffLast State: Terminated Reason: Error Exit Code: 1Environment: DB_HOST: postgres.shop.svc.cluster.local DB_PASSWORD: <set to the key 'password' in secret 'api-db'>Events: Warning BackOff kubelet Back-off restarting failed container apiЙмовірна першопричина тепер достатньо конкретна, щоб безпечно її перевірити: новий Pod очікує ключ Secret, який відсутній, перейменований, порожній або відсутній у просторі імен shop. Наступні перевірки мають оглянути об’єкт Secret, а потім розгортання Deployment, а не видаляти випадкові Pod’и чи редагувати живий Pod. Якщо Secret виправлено або шаблон Deployment вилікувано, фахівець має переконатися, що розгортання просувається, новий Pod стає готовим (Ready), а старі Pod’и замінюються відповідно до стратегії Deployment.
k get secret api-db -n shopk describe secret api-db -n shopk rollout status deployment/api -n shopЦей робочий приклад показує різницю між збором доказів і збором команд. CrashLoopBackOff обрав попередні логи, попередні логи обрали конфігурацію, describe пов’язав цю конфігурацію з посиланням на Secret, а статус розгортання перевірив, чи контролер відновився після виправлення основної проблеми. Той самий патерн працює, коли симптом змінюється: почніть зі стадії збою, оберіть свідка для цієї стадії і лише потім обирайте дію. Якби симптомом натомість був Pending, ланцюжок доказів почався б з подій планувальника, а не з логів; якби це був ImagePullBackOff, він почався б з повідомлення kubelet про завантаження. Стадія завжди обирає свідка, а свідок завжди обирає наступну команду.
Зверніть увагу, що приклад жодного разу не потребував привілейованого доступу до ноди чи глибокого знання коду застосунку. Саме тому ці основи належать до раннього етапу навчального плану Kubernetes. Часто можна звести інцидент від «розгортання дає збій» до «новий шаблон посилається на конфігурацію, яку застосунок не може прочитати» за допомогою звичайних команд читання. Це зведення не розв’язує кожну проблему, але перетворює паніку на сфокусований запит до власника, який може внести справжню зміну. Саме в цьому й полягає цінність основ: вони не роблять вас експертом з кожної підсистеми, але дають надійний спосіб швидко визначити, до кого з експертів звертатися далі.
Частина 5: Патерни збоїв, які ви маєте розпізнавати
Розділ «Частина 5: Патерни збоїв, які ви маєте розпізнавати»Найпоширеніші збої Kubernetes впізнавані, бо кожен має інший перший корисний сигнал. Вам не потрібно запам’ятовувати кожне можливе повідомлення події, але ви маєте знати, яке джерело доказів володіє проблемою і які виправлення належать цьому джерелу. Проблема планувальника з’являється в подіях планування, проблема образу — у подіях завантаження kubelet, проблема запуску — у попередніх логах і останньому стані, завершення через нестачу пам’яті — у причині завершення та лімітах ресурсів, а проблема трафіку часто з’являється в умовах готовності та ендпоінтах Сервісу.
Ці патерни також допомагають уникати хибних подібностей. CrashLoopBackOff та ImagePullBackOff обидва виглядають тривожно у стовпці статусу, але один означає, що процес запустився, а інший — що процес навіть не вдалося створити. Pending і Running з готовністю 0/1 обидва можуть блокувати розгортання, але один належить до розміщення, а інший — до запуску чи справності. Коли два симптоми виглядають здалеку схожими, спершу порівняйте стадію життєвого циклу, а потім порівняйте докази.
5.1 CrashLoopBackOff
Розділ «5.1 CrashLoopBackOff»CrashLoopBackOff означає, що контейнер запустився, завершився, а тепер перезапускається із затримкою. Kubernetes не каже, чому застосунок зазнав збою; він каже, що kubelet відкочується перед наступною спробою. Причиною може бути погана команда, відсутня змінна середовища, виняток застосунку, невдала залежність, неправильний дозвіл на файл, неможлива міграція при запуску чи проба життєздатності (liveness), яка вбиває процес після його запуску. Оскільки процес уже запускався, попередні логи та останній стан — це ваші найефективніші перші докази.
k logs <pod-name> -n <namespace> -pk describe pod <pod-name> -n <namespace>Цей патерн важливий, бо початківці часто оглядають лише поточні логи й пропускають корисний збій із завершеного екземпляра. У щільному циклі перезапусків поточний контейнер може очікувати, запускатися чи ще не дійти до точки збою, тоді як -p запитує вивід останнього завершеного контейнера. Якщо кожна репліка того самого Deployment аварійно завершується однаково, підозрюйте спільний образ, команду, конфігурацію, Secret, ConfigMap, пробу чи залежність, перш ніж винуватити одну ноду.
5.2 ImagePullBackOff та ErrImagePull
Розділ «5.2 ImagePullBackOff та ErrImagePull»ErrImagePull та ImagePullBackOff означають, що kubelet не може отримати образ контейнера. Код застосунку ще не запускався, тож логи зазвичай порожні чи недоступні, а exec неможливий, бо немає створеного контейнера, у який можна зайти. Повідомлення події — це головна підказка, бо воно може відрізнити тег, який ніколи не публікувався, від збою автентифікації реєстру, відмови в доступі на завантаження, неправильного шляху до репозиторію, збою DNS, тайм-ауту мережі чи відключення реєстру.
k describe pod <pod-name> -n <namespace>Шукайте фрази в подіях на кшталт manifest unknown, not found, pull access denied, unauthorized чи помилки тайм-ауту, а потім підбирайте виправлення до того точного формулювання. Образ із правильним на вигляд ім’ям усе одно може дати збій, якщо CI-конвеєр опублікував інший тег, простору імен бракує посилання imagePullSecrets, шлях реєстру змінився чи нода не може дістатися реєстру. Зміна проб чи конфігурації застосунку не може допомогти, доки kubelet не зможе завантажити та створити контейнер.
5.3 Pending та FailedScheduling
Розділ «5.3 Pending та FailedScheduling»Pod у статусі Pending без призначеної ноди — це проблема планувальника, доки не доведено інше. Планувальник порівнює запити Pod’а, селектори нод, правила affinity, taint’и, толерантності, обмеження поширення за топологією та вимоги до томів з доступними нодами. Якщо жодна нода не задовольняє повний набір, Pod лишається незапланованим, а події FailedScheduling пояснюють, які обмеження відхилили доступні ноди.
k describe pod <pod-name> -n <namespace>k get nodes -o wideПоширені повідомлення включають нестачу CPU, нестачу пам’яті, taint’и, які Pod не толерує, невідповідність node affinity, несумісні правила топології чи непов’язані PersistentVolumeClaim. Правильна відповідь — не перезапускати Pod, бо він не запускався. Ви або змінюєте вимоги Pod’а до планування, або зменшуєте запити ресурсів, коли це чесно, або забезпечуєте додаткову ємність, або виправляєте прив’язку сховища, або навмисно додаєте толерантність після підтвердження, що цільові ноди є доречними.
5.4 OOMKilled
Розділ «5.4 OOMKilled»OOMKilled означає, що процес перевищив свій ліміт пам’яті, і ядро його вбило. Kubernetes записує це в останній стан контейнера, і код виходу часто 137, бо процес отримав примусовий сигнал завершення. Pod потім може увійти в CrashLoopBackOff, якщо політика перезапуску чи контролер-власник продовжують запускати той самий ненажерливий до пам’яті процес під тим самим лімітом.
k describe pod <pod-name> -n <namespace>Безпосереднє порівняння — між лімітом пам’яті контейнера та фактичною поведінкою пам’яті застосунку. Збільшення ліміту може бути слушним пом’якшенням, коли початковий ліміт був нереалістичним, але це не завжди повне виправлення. Витік пам’яті, необмежений кеш, випадкове велике пакетне завантаження чи налаштування купи (heap) середовища виконання можуть зрештою спожити будь-який більший ліміт, тож хороше налагодження відрізняє невідповідність ємності від зростання, яке слід виправити в застосунку.
5.5 Збої проб і Pod’и, що працюють, але не готові
Розділ «5.5 Збої проб і Pod’и, що працюють, але не готові»Pod може працювати, але не отримувати трафіку Сервісу, бо провалилася готовність. Збої життєздатності (liveness) перезапускають контейнер, збої готовності (readiness) видаляють Pod з ендпоінтів, а проби запуску (startup) дають повільним застосункам час до того, як почнеться liveness. Збої проб поширені після зміни порту, шляху, схеми, тривалості запуску, поведінки автентифікації чи залежності, і їх особливо легко неправильно прочитати, бо STATUS може досі казати Running.
k describe pod <pod-name> -n <namespace>k get endpoints <service-name> -n <namespace>Небезпечна помилка початківця — побачити Running і припустити, що користувачі можуть дістатися робочого навантаження. Завжди порівнюйте STATUS із READY, а потім оглядайте події на повідомлення на кшталт Readiness probe failed чи Liveness probe failed. Якщо застосунок справний, але проба вказує на неправильний шлях чи порт, виправте пробу. Якщо проба правильна, а застосунок не може її задовольнити, виправте застосунок чи залежність, яку готовність точно викриває.
Є ще один клас збоїв, який варто тримати на думці: невідповідність контролера. Іноді симптом на рівні Pod’а реальний, але причина, чому він постійно повертається, у тому, що контролер-власник постійно створює нові Pod’и з незмінного шаблону. Пряме редагування Pod’а може на мить здаватися робочим, а потім зникнути, коли Deployment замінить Pod. Коли збій прив’язаний до розгортання, завжди пов’язуйте докази Pod’а назад з Deployment, ReplicaSet, Job, StatefulSet чи DaemonSet, який ним володіє.
| Патерн | Головний сигнал | Перша команда | Ймовірна область виправлення |
|---|---|---|---|
| Цикл аварійних перезапусків | CrashLoopBackOff, зростання перезапусків | k logs <pod> -p | Запуск застосунку, команда, конфіг, залежність, проба |
| Завантаження образу | ImagePullBackOff, ErrImagePull | k describe pod <pod> | Посилання на образ, автентифікація реєстру, доступність реєстру/мережі |
| Планування | Pending, нода не призначена | k describe pod <pod> | Запити, taint’и, affinity, PVC, ємність ноди |
| Завершення через пам’ять | OOMKilled, код виходу 137 | k describe pod <pod> | Ліміт пам’яті, витік, розмір купи, форма навантаження |
| Збій готовності | Running з готовністю 0/1 | k describe pod <pod> | Шлях проби, порт, час запуску, справність залежності |
| Проблема ноди | Багато Pod’ів дають збій на одній ноді | k describe node <node> | Тиск на ноду, kubelet, мережа, диск, taint’и |
Перш ніж запускати наступну команду, вирішіть, який рядок таблиці відповідає вашому симптому, і назвіть докази, які ви очікуєте побачити. Якщо докази не з’являються, перегляньте класифікацію замість того, щоб силувати початкову теорію.
Частина 6: Побудуйте контрольний список першого реагування
Розділ «Частина 6: Побудуйте контрольний список першого реагування»Контрольний список налагодження цінний, бо інциденти змушують людей пропускати кроки. Мета — не перетворити вас на робота; мета — захистити вашу увагу, коли кілька людей чекають на відповідь, а кожне повідомлення в чаті пропонує інше виправлення. Використовуйте контрольний список як цикл: підтвердьте контекст, визначте область впливу, класифікуйте стадію збою, огляньте правильні докази, сформулюйте гіпотезу, дійте щодо найімовірнішого власника та перевірте відновлення на рівні контролера й трафіку.
FIRST-RESPONSE CHECKLIST
┌───────────────────────┐│ 1. Confirm Context │ Correct cluster, namespace, workload, time window└───────────┬───────────┘ ▼┌───────────────────────┐│ 2. Scope Impact │ One pod, many pods, one node, all namespaces└───────────┬───────────┘ ▼┌───────────────────────┐│ 3. Classify Failure │ Scheduling, image, runtime, readiness, node└───────────┬───────────┘ ▼┌───────────────────────┐│ 4. Inspect Evidence │ Describe, logs, previous logs, events, nodes└───────────┬───────────┘ ▼┌───────────────────────┐│ 5. Choose Action │ Roll back, fix config, scale, adjust resources└───────────┬───────────┘ ▼┌───────────────────────┐│ 6. Verify Recovery │ Rollout status, readiness, events, endpoints└───────────────────────┘Починайте кожну сесію з підтвердження контексту, бо налагодження не того простору імен марнує час і може спричинити випадкові зміни. k config current-context та k get pods -A — це прості запобіжники, особливо в навчальних кластерах, де кілька просторів імен можуть містити робочі навантаження зі схожими назвами. У виробництві команди часто додають підказки в оболонці, конвенції kubeconfig та типові налаштування лише для читання з тієї самої причини: перший крок налагодження — це довести, що ви дивитеся на потрібний кластер і робоче навантаження.
k config current-contextk get pods -A -o wideПісля контексту й області оберіть найвужчу команду доказів, що відповідає стадії збою. Використовуйте describe для повідомлень про планування, завантаження образу, пробу, том і життєвий цикл kubelet. Використовуйте logs -p для попередніх аварійно завершених контейнерів і додавайте -c, коли Pod містить кілька контейнерів. Використовуйте команди ноди, коли багато незв’язаних Pod’ів дають збій на одній ноді або коли статус Pod’а Unknown. Використовуйте команди розгортання, коли старі та нові ReplicaSet поводяться по-різному, бо подання контролера каже вам, чи ізольований збій до нового шаблону.
k rollout status deployment/<deployment-name> -n <namespace>k get rs -n <namespace>k describe node <node-name>Перевірка важлива, бо «виправлення», яке змінює статус одного Pod’а, може не відновити робоче навантаження. Для Deployment перевірте статус розгортання, готовність Pod’ів, лічильники перезапусків та ендпоінти для Сервісів, що обирають ці Pod’и. Для виправлень планування перевірте, що Pod отримує ноду, а потім проходить завантаження образу й запуск контейнера. Для виправлень проб перевірте, що Pod стає готовим (Ready) і що список ендпоінтів Сервісу включає його, бо користувачам важлива придатність приймати трафік, а не саме лише існування процесу.
Контрольний список має лишати невеликий аудиторський слід навіть у тренувальному середовищі. Зафіксуйте видимий симптом, перші корисні докази, ймовірного власника, вжиту дію та перевірку відновлення. Це може бути повідомлення в чаті, нотатка про інцидент чи особистий чернетковий запис. Формат має менше значення, ніж дисципліна записувати твердження, яке інший інженер міг би оскаржити, бо налагодження вдосконалюється найшвидше, коли ваші міркування видимі.
Набираючись досвіду, ви додаватимете специфічні для середовища кроки до того самого каркаса. Керований кластер може вимагати перевірки справності хмарного балансувальника навантаження, сервісна сітка може вимагати огляду готовності sidecar’ів, а регульоване середовище може вимагати збереження додаткових логів перед очищенням. Ці доповнення не замінюють основ. Вони розширюють ту саму послідовність: визначити область, класифікувати, оглянути, діяти та перевірити.
Патерни та антипатерни
Розділ «Патерни та антипатерни»Хороші патерни налагодження Kubernetes — це маленькі звички, що масштабуються від лабораторного кластера до виробничого інциденту. Спільна нитка в тому, що кожен патерн захищає докази, звужує відповідальність і лишає чітке пояснення для наступного фахівця. Антипатерни роблять протилежне: вони змінюють стан до класифікації, змішують джерела доказів або перетворюють конкретний симптом на туманне переконання, що «Kubernetes зламаний».
| Патерн | Коли використовувати | Чому це працює | Міркування щодо масштабування |
|---|---|---|---|
| Визначення області перед виправленням | Будь-яке несправне навантаження, особливо під час розгортань | Відокремлює збої одного Pod’а від патернів ноди, простору імен чи кластера | Використовуйте мітки та власників, щоб швидко порівняти репліки між просторами імен |
| Читання попередніх логів для циклів перезапусків | Контейнери з перезапусками чи CrashLoopBackOff | Захоплює вивід невдалого процесу до того, як наступна спроба його приховає | Централізоване логування все одно потрібне, коли Pod’и швидко змінюються |
| Дотримання посилань на власників | Pod’и, створені Deployment, Job, StatefulSet чи DaemonSet | Запобігає прямим редагуванням Pod’а, які контролери перезаписують | Виправляйте шаблон чи джерело контролера, щоб заміни успадкували зміну |
| Перевірка придатності до трафіку | Pod’и у статусі Running, що не обслуговують користувачів | Готовність і ендпоінти вирішують маршрутизацію Сервісу | Перевіряйте зрізи ендпоінтів (endpoint slices) чи бекенди Сервісу у більших кластерах |
| Антипатерн | Що йде не так | Краща альтернатива |
|---|---|---|
| Налагодження «спершу перезапуск» | Перезапуски стирають хронометраж, попередні логи й іноді єдиний несправний екземпляр | Зафіксуйте статус, попередні логи та події перед зміною стану |
| Сприйняття кожної проблеми Pod’а як коду застосунку | Збої планувальника, образу, тому, проби та ноди хибно приписуються | Класифікуйте стадію збою перед вибором власника |
| Редагування живого Pod’а | Контролери відтворюють Pod’и з початкового шаблону, тож виправлення зникає | Змініть Deployment, StatefulSet, Job чи вихідний маніфест |
| Оголошення перемоги за одним зеленим Pod’ом | Розгортання, готовність чи ендпоінти можуть досі бути несправними | Перевіряйте перебіг контролера й шлях трафіку, а не лише один об’єкт |
Ці патерни навмисно скромні, бо основи налагодження мають бути надійними під тиском. Фахівець, який завжди визначає область впливу, читає правильного свідка та перевіряє результат на рівні контролера, перевершить того, хто знає багато складних команд, але застосовує їх безсистемно. Практикуючись, зосереджуйтесь менше на запам’ятовуванні точного виводу і більше на розпізнаванні, який компонент міг породити кожну підказку.
Патерни — це також спосіб захистити команду від місцевого фольклору. У багатьох команд є улюблене виправлення — як-от перезапуск Pod’ів, збільшення пам’яті чи негайний відкат, — бо ця дія колись розв’язала пам’ятний інцидент. Патерн сильніший за фольклор, бо він каже, коли дія застосовна, чому вона працює і які докази мають існувати спершу. Це полегшує повторення хорошої частини досвіду без копіювання випадкової частини.
Коли це використовувати, а коли — альтернативи
Розділ «Коли це використовувати, а коли — альтернативи»Використовуйте цей базовий цикл сортування, коли стикаєтеся зі свіжим збоєм робочого навантаження й маєте вирішити, до чого належить проблема. Він особливо корисний для інцидентів рівня KCNA — як-от Pod’и, що застрягли у статусі Pending, образи, які не вдається завантажити, контейнери, що аварійно завершуються під час запуску, Pod’и, які працюють, але провалюють готовність, і розгортання, що застопорюються. Він дає вам швидкий шлях від симптому до ймовірного власника, не вимагаючи глибокого знання внутрішнього устрою кластера, кастомної спостережуваності чи привілейованого доступу до ноди.
| Ситуація | Використовуйте базовий цикл сортування | Використовуйте глибший інструментарій |
|---|---|---|
| Один новий Pod дає збій після розгортання | Так, порівняйте старі та нові Pod’и, логи, події й статус розгортання | Пізніше, якщо потрібні трейси чи метрики застосунку |
| Багато незв’язаних Pod’ів дають збій на одній ноді | Так, визначте область за нодою й огляньте умови ноди | Використовуйте логи ноди та інфраструктурні інструменти, якщо справність ноди незрозуміла |
| Запит повільний, але всі Pod’и готові (Ready) | Частково, спершу перевірте розгортання та перезапуски | Використовуйте метрики застосунку, трейсинг і налагодження Сервісу/мережі |
| Загальнокластерний збій впливає на доступ до API | Обмежено, бо команди k можуть давати збій | Використовуйте діагностику площини управління, хмари та інфраструктури |
Головний компроміс у тому, що базове сортування чудово локалізує першу очевидну межу збою, але не завжди достатнє, щоб пояснити глибоку поведінку продуктивності чи мережі. Pod може бути готовим (Ready), поки затримка застосунку неприйнятна, а Сервіс може мати ендпоінти, поки проблема NetworkPolicy чи DNS ламає конкретний шлях запиту. Звичка все одно допомагає, бо вона усуває поширені збої життєвого циклу навантаження, перш ніж ви перейдете до агрегації логів, дашбордів метрик, розподілених трейсів, захоплення пакетів чи діагностики хмарного провайдера.
Коли ви все ж переходите до глибшого інструментарію, несіть із собою ту саму дисципліну доказів. Дашборд метрик має відповідати на конкретне запитання, порушене хронологією Pod’а, — як-от чи зростала пам’ять перед OOM-завершенням чи чи змінилася затримка запитів після розгортання. Трейс має відповідати на запитання щодо шляху запиту, а не замінювати базові перевірки готовності. Складні інструменти найкорисніші, коли просте життєво-циклове свідчення вже звузило пошук.
Отже, межа між базовим і складним налагодженням — це передача, а не стіна. Базове сортування має породжувати речення на кшталт: «Pod готовий, ендпоінти його включають, а перезапуски стабільні, тож наступне запитання — затримка запиту крізь шлях Сервісу». Це речення каже наступному інструменту, що довести. Воно також не дає команді знову відкривати розв’язані життєво-циклові запитання, поки починається глибше дослідження мережі, трейсингу чи продуктивності застосунку. Чітко сформульована передача економить найдорожчий ресурс під час інциденту — час кількох людей, які інакше повторювали б ту саму роботу й доходили б до тих самих висновків паралельно.
Чи знали ви?
Розділ «Чи знали ви?»-
Події — це тимчасові докази: багато кластерів зберігають події обмежений час, тож свіжі дані інциденту можуть зникнути ще до пізнішого розбору. Виробничі команди зазвичай поєднують події з централізованими логами та метриками, бо вбудований потік подій — це короткостроковий інструмент налагодження.
-
Running— це не те саме, щоReady: процес контейнера може бути живим, поки готовність хибна, і Сервіси мають уникати маршрутизації трафіку до такого Pod’а. Ця відмінність пояснює багато сценаріїв «Pod працює, але користувачі все одно отримують збій». -
Попередні логи часто корисніші за поточні: у циклі аварійних перезапусків поточний контейнер може очікувати, запускатися чи ще не дійти до точки збою.
k logs -pзапитує логи останнього завершеного екземпляра, який часто містить справжню помилку. -
Код виходу
137зазвичай вказує на примусове завершення: він поширено з’являється, коли контейнерOOMKilled, хоча вам слід перевіряти полеreason, а не покладатися лише на число. Поєднання коду виходу, причини та ліміту пам’яті розповідає переконливішу історію, ніж будь-яке окреме поле.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому це стається | Як це виправити |
|---|---|---|
| Видалення несправного Pod’а до огляду | Заміна може приховати попередні логи, хронометраж і події, водночас відтворивши той самий збій. | Спершу прочитайте describe, попередні логи та події, а потім перезапускайте лише якщо докази це підтверджують. |
Сприйняття Running як справного | Процес існує, але готовність може бути хибною, а трафік Сервісу досі заблокованим. | Порівняйте READY, умови, події проб та ендпоінти Сервісу, перш ніж оголошувати відновлення. |
| Читання логів застосунку для незапланованого Pod’а | Знайома команда логів здається налагодженням, але жоден контейнер ще не запускався. | Прочитайте події Pod’а та обмеження планування за допомогою k describe pod. |
| Ігнорування простору імен і контексту | Схожі назви навантажень у різних просторах імен ведуть до хибних висновків чи небезпечних змін. | Підтвердьте k config current-context і свідомо використовуйте -n <namespace>. |
| Виправлення живого Pod’а замість шаблону контролера | Контролер відтворює Pod’и зі старого шаблону, тож прямі редагування Pod’а не зберігаються. | Змініть Deployment, StatefulSet, Job чи вихідний маніфест, який володіє Pod’ом. |
| Збільшення лімітів пам’яті без перевірки поведінки | Більший ліміт може відстрочити витік пам’яті, а не розв’язати його. | Порівняйте ліміти з очікуваним використанням, огляньте поведінку пам’яті застосунку та за потреби налаштуйте середовище виконання. |
| Припущення, що всі збої реплік — це збої ноди | Однаковий збій на всіх репліках часто вказує на спільну конфігурацію, образ чи залежність. | Порівняйте розміщення на нодах, а потім огляньте спільний шаблон Pod’а та попередні логи. |
| Пропуск перевірки після зміни | Один Pod може відновитися, поки розгортання, готовність чи ендпоінти лишаються несправними. | Перевіряйте статус розгортання, готовність Pod’а, лічильники перезапусків, події та ендпоінти Сервісу. |
Тест
Розділ «Тест»Ваша команда розгортає нову версію API, і всі нові Pod'и показують `CrashLoopBackOff`, тоді як старі Pod'и лишаються готовими (Ready). Які докази слід зібрати першими і яку першопричину ви перевіряєте?
Почніть з k logs <new-pod> -n <namespace> -p, бо контейнер уже запускався та аварійно завершився, і попередній екземпляр зазвичай містить справжню помилку запуску. Потім використайте k describe pod <new-pod> -n <namespace>, щоб підтвердити останній стан, код виходу, посилання на змінні середовища, проби та події. Оскільки кожна нова репліка дає збій, поки старі репліки працюють, ви перевіряєте проблему спільного нового шаблону — як-от поведінку образу, команду чи аргументи, конфігурацію, посилання на Secret чи ConfigMap або залежність, потрібну під час запуску. Це шлях налагодження несправного навантаження, бо він дотримується спостережуваних доказів замість здогадок.
Pod перебуває у статусі `Pending` кілька хвилин, не має призначеної ноди, а `k logs` повертає помилку, бо контейнер недоступний. Що слід перевірити далі й чому?
Запустіть k describe pod <pod> -n <namespace> і прочитайте розділ Events. Pod без призначеної ноди не досяг точки, де можуть існувати логи застосунку, тож повідомлення подій планувальника — це головні докази. Імовірні причини включають нестачу CPU чи пам’яті, taint’и, які Pod не толерує, невідповідність affinity чи селекторів нод, обмеження топології або непов’язаний PersistentVolumeClaim. Це аналізує фазу Pod’а та докази планувальника перед тим, як дивитися на стан контейнера.
Сервіс не отримує трафіку для нового Pod'а, хоча `k get pods` показує Pod як `Running` із нульовими перезапусками. Стовпець `READY` показує `0/1`. Як налагоджувати, не даючи фазі `Running` ввести вас в оману?
Розглядайте це як проблему готовності, доки докази не скажуть інше. Використайте k describe pod <pod> -n <namespace>, щоб оглянути умови та події проб, а потім перевірте, чи готовність провалюється через неправильний шлях, порт, схему, затримку запуску, тайм-аут чи залежність. Ви також можете оглянути k get endpoints <service> -n <namespace>, щоб перевірити, чи виключено Pod з маршрутизації Сервісу. Ключ — відокремити фазу Pod’а від готовності до трафіку, бо Running не означає, що навантаження придатне до використання.
Контейнер неодноразово завершується з причиною `OOMKilled`, і команда пропонує перезапуск розгортання. Чому це навряд чи буде повним виправленням і що слід оцінити натомість?
Перезапуск розгортання запускає той самий процес під тим самим лімітом пам’яті, тож він зазвичай відтворює те саме завершення після того, як використання пам’яті знову зросте. Вам слід оглянути ліміт пам’яті Pod’а в k describe pod, порівняти його з очікуваними потребами застосунку в пам’яті й оцінити, чи ліміт занизький, чи застосунок має витік пам’яті, чи купа (heap) середовища виконання хибно налаштована, чи навантаження завантажує забагато даних. Збільшення ліміту може бути пом’якшенням, але воно має відповідати доказам, а не здогадкам. Це порівнює докази OOM з доказами збою та розгортання, щоб дія була спрямована на правильного власника.
Посилання на образ виглядає правильним у маніфесті, але Pod показує `ImagePullBackOff`. Ваш колега хоче зайти (exec) в Pod, щоб перевірити доступ до реєстру. Що не так із цим планом і що слід зробити натомість?
Ви не можете зайти (exec) в контейнер, який не було створено, а збій завантаження образу означає, що процес застосунку ніколи не запускався. Використайте k describe pod <pod> -n <namespace> і прочитайте повідомлення подій kubelet щодо точного збою завантаження. Повідомлення має вказувати на відсутній тег, збій автентифікації реєстру, проблему з дозволами, тайм-аут DNS чи мережі або неправильний шлях реєстру. Це порівнює збої завантаження образу зі збоями виконання, запитуючи, які докази існують на цій стадії життєвого циклу.
Три незв'язані навантаження стають несправними приблизно одночасно, і всі уражені Pod'и перебувають на `worker-b`. Pod'и тих самих Deployment на інших нодах лишаються справними. Як розширити розслідування?
Цей патерн вказує на проблему рівня ноди, а не на три незалежні помилки застосунків. Використайте k get pods -A -o wide, щоб підтвердити розміщення, а потім огляньте k describe node worker-b на умови на кшталт тиску пам’яті, тиску диска, тиску PID, недоступності мережі, taint’ів і нещодавніх подій ноди. Вам усе одно слід зберегти докази рівня Pod’а, але спільна нода — найвагоміша підказка. Це оцінює, чи належить проблема ноді, а не застосунку, специфікації Pod’а, планувальнику чи розгортанню контролера.
Розгортання застопорилося: два старі Pod'и готові (Ready), а один новий — `Pending`. Власник продукту запитує, чи користувачі недоступні. Що ви перевіряєте і як пояснюєте ризик?
Перевірте k rollout status deployment/<name> -n <namespace>, k get pods -n <namespace> -o wide та k describe pod <pending-new-pod> -n <namespace>. Якщо старі Pod’и лишаються готовими (Ready) й обираються Сервісом, користувачів усе ще можуть обслуговувати, але розгортання заблоковане, а ємність чи резервування можуть бути зменшені. Події Pending-Pod’а пояснять, чи ресурси, taint’и, affinity чи томи заважають новій версії запланувати. Це оцінює розгортання контролера окремо від збою планування Pod’а та живого шляху трафіку.
Практична вправа
Розділ «Практична вправа»У цій вправі ви створите три невеликі сценарії збоїв у тренувальному просторі імен, класифікуєте кожен збій і зберете правильні докази перед очищенням. Використовуйте одноразовий локальний чи лабораторний кластер, а не виробничий, бо ресурси навмисно зламані й генеруватимуть події чи перезапуски. Команди припускають, що ви вже виконали alias k=kubectl; якщо ваша оболонка не зберігає псевдоніми між сесіями, визначте його знову перед початком.
Крок 1: Створіть ізольований простір імен
Розділ «Крок 1: Створіть ізольований простір імен»Створіть простір імен, щоб ресурси вправи було легко знайти й видалити. Це тримає тренувальні збої осторонь від інших навантажень і дає вам чисту хронологію подій. Простори імен — це також корисна звичка безпеки, бо вони змушують вас передавати -n kcna-debug і пам’ятати про область, яку ви оглядаєте.
k create namespace kcna-debugk get namespace kcna-debug- Простір імен
kcna-debugіснує й видимий уk get namespace. - Ви можете виконувати команди з
-n kcna-debugбез зміни типового простору імен.
Крок 2: Створіть збій завантаження образу
Розділ «Крок 2: Створіть збій завантаження образу»Застосуйте Pod, який посилається на тег образу, що не повинен існувати. Мета — довести, що збої завантаження образу діагностуються з подій, а не з логів застосунку, бо процес застосунку не може писати логи, доки kubelet не завантажить образ і не створить контейнер.
k apply -n kcna-debug -f - <<'EOF'apiVersion: v1kind: Podmetadata: name: bad-imagespec: restartPolicy: Never containers: - name: app image: nginx:no-such-kcna-debug-tag ports: - containerPort: 80EOFЗачекайте трохи, потім огляньте статус і події. Зверніть увагу на порядок команд: статус каже вам видимий симптом, describe каже вам про збій завантаження з боку kubelet, а логи демонструють, чому звичайний шлях налагодження застосунку не є корисним для цієї конкретної стадії.
k get pod bad-image -n kcna-debugk describe pod bad-image -n kcna-debugk logs bad-image -n kcna-debug- Pod показує
ErrImagePullчиImagePullBackOffпісля того, як kubelet намагається завантаження. - Вивід
describeмістить подію, що пояснює збій завантаження образу. - Ви можете пояснити, чому
k logsне є правильним джерелом доказів для цього сценарію.
Крок 3: Створіть збій циклу аварійних перезапусків
Розділ «Крок 3: Створіть збій циклу аварійних перезапусків»Застосуйте Pod, чий контейнер запускається, друкує повідомлення та завершується з ненульовим кодом. Цей сценарій навмисно відрізняється від збою завантаження образу, бо контейнер таки запускається, що означає, що попередні логи й останній стан стають корисними доказами. Мета — натренувати ваше око переходити від статусу до попередніх логів, а не ставитися до кожного збою однаково.
k apply -n kcna-debug -f - <<'EOF'apiVersion: v1kind: Podmetadata: name: crash-demospec: containers: - name: app image: busybox:1.36 command: - /bin/sh - -c - echo "starting demo"; echo "missing required setting"; exit 1EOFПоспостерігайте, як він перезапускається, потім прочитайте і стан Pod’а, і попередні логи. Якщо ваша перша спроба k logs -p виконається до того, як контейнер перезапуститься, зачекайте кілька митей і спробуйте знову; важливий урок у тому, що попередній завершений екземпляр часто є найзрозумілішим свідком у циклі аварійних перезапусків.
k get pod crash-demo -n kcna-debugk logs crash-demo -n kcna-debug -pk describe pod crash-demo -n kcna-debug- Pod досягає
CrashLoopBackOffчи показує повторювані перезапуски за кілька митей. -
k logs -pпоказує повідомлення з попереднього невдалого екземпляра контейнера. -
k describe podпоказує завершений останній стан чи докази перезапуску, що відповідають виводу логу.
Крок 4: Створіть збій планування
Розділ «Крок 4: Створіть збій планування»Застосуйте Pod із навмисно нереалістичним запитом пам’яті. Цей сценарій має лишитися незапланованим на звичайних тренувальних кластерах, що означає, що події планувальника — це правильні докази, а логів застосунку не повинно існувати. Якщо ваш кластер незвично великий і Pod планується, збільшіть запит у своїй чернетковій копії, а не змінюйте висновок уроку.
k apply -n kcna-debug -f - <<'EOF'apiVersion: v1kind: Podmetadata: name: too-largespec: containers: - name: app image: busybox:1.36 command: - /bin/sh - -c - sleep 3600 resources: requests: memory: "1000Gi" cpu: "1"EOFОгляньте розміщення й повідомлення планувальника. Важлива деталь — відсутня нода у виводі з прапорцем wide і подія FailedScheduling у describe, бо разом вони показують, що Pod так і не досяг запуску контейнера в kubelet.
k get pod too-large -n kcna-debug -o widek describe pod too-large -n kcna-debug- Pod лишається
Pendingі не має призначеної ноди вk get pod -o wide. - Розділ Events пояснює, чому планувальник не зміг розмістити Pod.
- Ви можете пояснити, чому перезапуск цього Pod’а не розв’язав би збій планування.
Крок 5: Складіть односторінкову нотатку сортування
Розділ «Крок 5: Складіть односторінкову нотатку сортування»Напишіть коротку нотатку для кожного несправного Pod’а за тією самою структурою: видимий симптом, перші корисні докази, ймовірний власник і наступна безпечна дія. Нотатка може бути у вашому редакторі, чернетковому файлі в терміналі чи командному шаблоні інциденту; важлива частина — це міркування, а не формат. Це перетворює вивід команд на контрольний список першого реагування, що зберігає докази й звужує область до дії.
Pod:Visible symptom:First useful evidence:Likely owner:Next safe action:-
bad-imageкласифіковано як збій завантаження образу з подіями kubelet як першими корисними доказами. -
crash-demoкласифіковано як збій під час виконання з попередніми логами як першими корисними доказами. -
too-largeкласифіковано як збій планування з подіями планувальника як першими корисними доказами. - Кожна наступна дія зберігає докази й націлена на ймовірну першопричину замість випадкового перезапуску ресурсів.
- Ваш контрольний список першого реагування явно охоплює рішення щодо налагодження, аналізу, порівняння, оцінки та проєктування з результатів навчання.
Крок 6: Очистіть тренувальний простір імен
Розділ «Крок 6: Очистіть тренувальний простір імен»Видаліть простір імен після завершення, щоб навмисно зламані ресурси не продовжували генерувати події чи перезапуски. Очищення — це частина дисципліни налагодження, бо лабораторний збій, залишений по собі, може заплутати майбутню практику, а в спільних кластерах він може марнувати ресурси чи відволікати іншого учня.
k delete namespace kcna-debug-
k get namespace kcna-debugбільше не показує простір імен після завершення видалення. - Ви можете пояснити три різні класи збоїв, не звертаючись до команд.
Джерела
Розділ «Джерела»- Kubernetes: Debug Applications
- Kubernetes: Debug Clusters
- Kubernetes: Pod Lifecycle
- Kubernetes: Resource Management for Pods and Containers
- Kubernetes: Pod Quality of Service Classes
- Kubernetes: Configure Liveness, Readiness and Startup Probes
- Kubernetes: kube-scheduler
- Kubernetes: Taints and Tolerations
- Kubernetes: Deployments
- kubectl logs reference
- kubectl describe reference
- kubectl get reference
- kubernetes.io: pod condition — Документація Pod Conditions визначає ці вбудовані умови й стверджує, що не-
ReadyPod’и видаляються з відповідних пулів балансування навантаження Сервісу. - kubernetes.io: kube apiserver — Довідник kube-apiserver документує налаштування зберігання
--event-ttlта його типове значення, що підтверджує операційну тезу про те, що події не зберігаються безстроково. - kubernetes.io: assign memory resource — Офіційне завдання щодо ресурсу пам’яті містить конкретний приклад OOMKilled, що показує
reason: OOMKilledпоряд зexitCode: 137. - Kubernetes Docs: Images — Охоплює поведінку завантаження образів,
ImagePullBackOff, контекст автентифікації реєстру та чому збої образів стаються до того, як починають існувати логи застосунку.
Наступний модуль
Розділ «Наступний модуль»Перейдіть до Частина 2: Оркестрація контейнерів — Модуль 2.1: Планування, щоб дізнатися, як Kubernetes вирішує, де розмістити ваші Pod’и.