Перейти до вмісту

Модуль 5.1: Методологія усунення несправностей

Складність: [СЕРЕДНЯ] — основа для кожного завдання з усунення несправностей на CKA та для реальної роботи з реагування на інциденти у продакшені

Час на проходження: 50-65 хвилин

Передумови: завершені Частини 1-4, зокрема архітектура кластера, робочі навантаження, мережа, сховище та впевнене володіння kubectl


Результати навчання

Розділ «Результати навчання»

Після цього модуля ви зможете:

  • Застосовувати систематичний цикл усунення несправностей, який рухається від фіксації симптому до перевірки гіпотез, ремонту й валідації без хаотичних змін.
  • Діагностувати збої Kubernetes, визначаючи, чи є першим зламаним рівнем застосунок, контейнер, под, сервіс, нода, сховище, мережа чи площина управління.
  • Оцінювати діагностичні докази з describe, подій (Events), логів, статусу ресурсів, YAML об’єкта та умов ноди, щоб обрати наступний крок розслідування.
  • Порівнювати схожі на вигляд стани збою, як-от Pending, ContainerCreating, CrashLoopBackOff, Running, але не Ready та Сервіс не має ендпоїнтів.
  • Розробляти короткий екзаменаційний план усунення несправностей, який береже час, зберігає докази та доводить виправлення перед переходом до наступного завдання.

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

Платформна інженерка на ім’я Міра чергує на виклику, коли під час релізу платіжного сервісу починає падати викочування. Дашборд повідомляє, що рівень помилок зростає, контролер деплойменту каже, що прогрес зупинився, а троє колег уже пропонують у чаті свої виправлення. Одна людина хоче перезапустити кожен под, інша хоче негайно відкотитися, а ще одна каже, що проблема має бути в DNS, бо саме це був останній інцидент, який вона пам’ятає. Якщо Міра піде за найгучнішим здогадом, вона може стерти докази, розширити збій і все одно не дізнатися, що насправді зламалося.

Усунення несправностей у Kubernetes винагороджує дисципліновану допитливість більше, ніж запам’ятовування команд. Кластер постійно узгоджує бажаний стан з фактичним, тож кожен збій залишає підказки в різних місцях: події планувальника, події kubelet, логи контейнерів, об’єкти ендпоїнтів, умови нод, статус контролерів, а іноді й сиру специфікацію об’єкта. Завдання оператора — прочитати ці підказки в правильному порядку, сформувати невелику гіпотезу, перевірити її та змінити лише те, що підтверджується доказами.

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

Аналогія з відділенням невідкладної допомоги

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

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

Terminal window
kubectl version --client

Частина 1: Думайте як слідчий, перш ніж думати як оператор

Розділ «Частина 1: Думайте як слідчий, перш ніж думати як оператор»

Усунення несправностей починається ще до першої команди, бо найдорожчі помилки зазвичай є помилками мислення. Учень, який знає двадцять команд kubectl, але не має процесу, часто метатиметься між логами, YAML, перезапусками й редагуваннями, не знаючи, яка підказка важлива. Дисциплінований оператор спершу вирішує, який саме доказ відокремив би одну можливу причину від іншої.

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

┌──────────────────────────────────────────────────────────────────────────────┐
│ TROUBLESHOOTING FRAMEWORK │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 1. OBSERVE │──▶│ 2. ISOLATE │──▶│ 3. INSPECT │──▶│ 4. REPAIR │ │
│ │ symptom and │ │ failing │ │ evidence and │ │ smallest │ │
│ │ blast radius │ │ layer │ │ test cause │ │ confirmed fix│ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ 5. VALIDATE │ │
│ │ workload and │ │
│ │ user path │ │
│ └──────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘

Стара чотирикрокова версія цього процесу казала: ідентифікувати, ізолювати, діагностувати й виправити. Це досі корисно, але доданий крок валідації запобігає поширеному продакшен-збою: зупинці, коли под позеленів, хоча сервіс досі не має ендпоїнтів або застосунок досі повертає помилки. Об’єкт Kubernetes може виглядати здоровим в одному поданні, тоді як повний шлях запиту все ще зламаний.

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

1.1 Спостерігайте симптом, не мутуючи кластер

Розділ «1.1 Спостерігайте симптом, не мутуючи кластер»

Перший прохід спостереження має бути широким, швидким і лише для читання. Ви хочете дізнатися, чи проблема ізольована в одному просторі імен, одному робочому навантаженні, одній ноді чи зачіпає весь кластер. Цей прохід не повинен містити delete, edit, rollout restart чи будь-якої команди, що змінює стан, бо такі команди можуть приховати початковий збій.

Terminal window
kubectl get nodes -o wide
kubectl get pods -A -o wide
kubectl get events -A --sort-by='.lastTimestamp' | tail -30
kubectl -n kube-system get pods -o wide

Вивід цих команд дає вам приблизну карту. Якщо в кожному просторі імен поди застрягли в Pending, можливо, причетні планувальник або місткість кластера. Якщо падає лише один деплоймент, перший зламаний рівень, найімовірніше, специфічний для робочого навантаження. Якщо багато подів на одній ноді мають стан Unknown або ContainerStatusUnknown, то шлях «нода — площина управління» заслуговує на увагу раніше, ніж ви інспектуватимете логи застосунку.

СпостереженняНа що вказуєБезпечніший наступний крок
Один новий под у стані ImagePullBackOffПроблема з іменем образу, тегом, реєстром або pull-секретомkubectl describe pod <pod> -n <ns>
Багато подів у Pending у різних просторах іменПроблема з місткістю, taint-ами, планувальником або доступністю нодkubectl describe pod <pod> -n <ns> та kubectl describe node <node>
Поди на одній ноді в стані UnknownПроблема з kubelet, мережею ноди, середовищем виконання або справністю нодиkubectl describe node <node> перед перезапуском навантажень
Сервіс повертає connection refusedПроблема з ендпоїнтом, цільовим портом, готовністю чи слухачем застосункуkubectl get endpointslices -n <ns> -l kubernetes.io/service-name=<svc>
kubectl повільний або відвалюється за тайм-аутомПроблема з API-сервером, etcd, площиною управління або мережевим шляхомkubectl get --raw='/readyz?verbose', якщо API відповідає

Точний симптом цінніший за драматичний. «Застосунок не працює» — надто широко, щоб це перевірити. «Запити до checkout.default.svc.cluster.local:8080 відвалюються за тайм-аутом із фронтенд-пода, тоді як прямі запити до IP пода checkout успішні» — достатньо конкретно, щоб відокремити маршрутизацію сервісу від справності застосунку.

1.2 Активне навчання: оберіть першу команду лише для читання

Розділ «1.2 Активне навчання: оберіть першу команду лише для читання»

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

Запишіть першу команду лише для читання, яку ви виконали б для кожного симптому, перш ніж читати відповіді. Для CrashLoopBackOff найсильніша перша команда — зазвичай kubectl describe pod <pod> -n <namespace>, бо події та стан контейнера підкажуть вам, чи крах — це насправді вихід застосунку, збій проби чи проблема конфігурації. Для «Сервіс не має трафіку» найсильніша перша команда — зазвичай kubectl get endpointslices або kubectl get endpoints для сервісу, бо сервіс без ендпоїнтів не може маршрутизувати, навіть якщо об’єкт сервісу існує.

1.3 Ізолюйте за рівнем, а не за здогадом

Розділ «1.3 Ізолюйте за рівнем, а не за здогадом»

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

┌──────────────────────────────────────────────────────────────────────────────┐
│ ISOLATION LAYERS │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ CLUSTER: API server, scheduler, controller manager, etcd, admission │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ NODE: kubelet, container runtime, CNI, kube-proxy, local pressure │ │ │
│ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ POD: scheduling, volumes, image pulls, probes, conditions │ │ │ │
│ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ │
│ │ │ │ │ CONTAINER: process, command, env, filesystem, limits │ │ │ │ │
│ │ │ │ │ ┌────────────────────────────────────────────────┐ │ │ │ │ │
│ │ │ │ │ │ APPLICATION: config, dependency, protocol, bug │ │ │ │ │ │
│ │ │ │ │ └────────────────────────────────────────────────┘ │ │ │ │ │
│ │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ │
│ │ │ └────────────────────────────────────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ Start with the widest observed symptom, then drill down only where evidence │
│ points. Do not inspect application logs for a pod that has never scheduled. │
└──────────────────────────────────────────────────────────────────────────────┘

Модель рівнів запобігає марним командам. Якщо под усе ще в Pending, спершу інспектуйте describe та події, бо контейнер застосунку, можливо, ще не запустився, тож логи можуть бути відсутні або поки що некорисні. Якщо сервіс не має ендпоїнтів, перевірка DNS першою може довести лише те, що DNS розв’язує ім’я сервісу, а не те, що сервіс може кудись надсилати трафік. Якщо API-сервер періодично недоступний, редагування YAML деплойменту може бути нерелевантним, бо сама площина управління може бути першим збоєм.

Рівень збоюТипові доказиКоманди, що зазвичай допомагають
ЗастосунокПроцес виходить, HTTP-помилки, збої залежностей, погані значення конфігураціїkubectl logs, kubectl exec, перевірки health-ендпоїнта застосунку
КонтейнерПогана команда, відсутній бінарник, неправильне середовище, OOM-вбивствоkubectl describe pod, kubectl logs --previous, статус через JSONPath
ПодЗавантаження образу, монтування тому, збій проби, відсутній ConfigMap чи Secretkubectl describe pod, kubectl get pod -o yaml
СервісНемає ендпоїнтів, неправильний селектор, неправильний targetPort, виключені неготові подиkubectl get svc, kubectl get endpointslices, порівняння міток
НодаNotReady, умови тиску, збій kubelet або середовища виконанняkubectl describe node, journalctl -u kubelet, статус середовища виконання
КластерТайм-аут API, збій планувальника, цикли контролерів, які не узгоджуютьсяkubectl get --raw='/readyz?verbose', логи подів kube-system

1.4 Інспектуйте докази в порядку, що відповідає життєвому циклу

Розділ «1.4 Інспектуйте докази в порядку, що відповідає життєвому циклу»

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

┌──────────────────────────────────────────────────────────────────────────────┐
│ POD LIFECYCLE DIAGNOSTIC ORDER │
│ │
│ YAML accepted ─▶ scheduled ─▶ volumes ready ─▶ image pulled ─▶ process starts │
│ │ │ │ │ │ │
│ ▼ ▼ ▼ ▼ ▼ │
│ API errors FailedScheduling FailedMount ErrImagePull CrashLoop │
│ admission taints/resources missing PVC auth or tag app/probe │
│ │
│ Ready for service traffic happens later, after readiness probes and endpoint │
│ publication succeed. A Running pod can still be excluded from a Service. │
└──────────────────────────────────────────────────────────────────────────────┘

Порядок життєвого циклу — це причина, чому describe настільки потужний. Він поєднує події планування, події kubelet, стан контейнера, інформацію про томи, умови та нещодавні попередження в одному місці. Логи досі необхідні, але логи відповідають на питання «що сказав процес контейнера?». Вони не відповідають на «чому под так і не змонтував свій секрет?» чи «чому планувальник відхилив кожну ноду?».

1.5 Ремонтуйте найменшу підтверджену причину

Розділ «1.5 Ремонтуйте найменшу підтверджену причину»

Найкращий ремонт — це найменша зміна, яка прямо усуває підтверджену причину. Якщо деплоймент посилається на nginx:latestt, встановіть образу коректний тег; не перебудовуйте деплоймент з пам’яті. Якщо селектор сервісу — app: api, тоді як поди мають мітку app: backend, навмисно змініть один бік; не пересоздавайте простір імен. Малі ремонти зменшують ризик, спрощують валідацію та зберігають ланцюг міркувань для перегляду.

Terminal window
kubectl set image deployment/web -n prod app=nginx:1.27
kubectl patch service web -n prod --type='merge' -p '{"spec":{"selector":{"app":"web"}}}'
kubectl create configmap app-config -n prod --from-literal=MODE=production

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

1.6 Валідуйте шлях робочого навантаження, а не лише статус об’єкта

Розділ «1.6 Валідуйте шлях робочого навантаження, а не лише статус об’єкта»

Валідація має відповідати початковому симптому. Якщо симптом був «фронтенд не може звернутися до бекенду», то побачити бекенд-под у стані Running недостатньо. Вам потрібно протестувати з аналогічного вихідного пода, через те саме ім’я сервісу, порт і протокол, які відмовили. Якщо симптом був «викочування деплойменту зупинилося», то kubectl rollout status — краща команда валідації, ніж одноразовий kubectl get pods.

Terminal window
kubectl rollout status deployment/backend -n prod --timeout=90s
kubectl get pods -n prod -l app=backend -o wide
kubectl get endpointslices -n prod -l kubernetes.io/service-name=backend
kubectl exec -n prod deploy/frontend -- wget -qO- http://backend:8080/healthz

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


Частина 2: Карта компонентів Kubernetes

Розділ «Частина 2: Карта компонентів Kubernetes»

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

┌──────────────────────────────────────────────────────────────────────────────┐
│ COMPONENT FAILURE MAP │
│ │
│ SYMPTOM OR OBSERVATION CHECK THESE COMPONENTS FIRST │
│ ───────────────────────────────────────────────────────────────────────── │
│ │
│ Pods not scheduling → kube-scheduler, node resources │
│ Pods stuck Pending → scheduler, taints, affinity, quotas │
│ Pods stuck ContainerCreating → kubelet, image pull, volumes, CSI │
│ Pods CrashLoopBackOff → container process, probes, app config │
│ Pods Running but not Ready → readiness probe, app listener, deps │
│ Pods cannot communicate → CNI, NetworkPolicy, DNS, routes │
│ Services have no endpoints → selectors, readiness, pod labels │
│ Services route to wrong pods → selector too broad or stale labels │
│ kubectl times out → API server, etcd, control plane path │
│ Node NotReady → kubelet, runtime, network, pressure │
│ Persistent volume issues → PVC, PV, StorageClass, CSI driver │
│ │
└──────────────────────────────────────────────────────────────────────────────┘

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

2.1 Компоненти площини управління та форми їхніх збоїв

Розділ «2.1 Компоненти площини управління та форми їхніх збоїв»

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

КомпонентЧим володієФорма збоюКорисний перший доказ
kube-apiserverAPI Kubernetes, допуск, автентифікація, записи об’єктівТайм-аути kubectl, помилки чи невдале створення об’єктівkubectl get --raw='/readyz?verbose'
etcdДовговічний стан кластера для об’єктів APIПомилки API, застарілі читання, невдалі записи, нестабільність площини управлінняЛоги API-сервера та вивід готовності
kube-schedulerПризначення незапланованих подів на нодиПоди залишаються в Pending з подіями плануванняkubectl describe pod <pod>
kube-controller-managerУзгодження для деплойментів, джобів, ендпоїнтів, нодБажаний стан перестає сходитися після прийняття об’єктівЛоги подів kube-system та статус об’єктів
cloud-controller-managerХмарні балансувальники, маршрути, інтеграція хмарних нодLoadBalancer у стані pending, відсутні хмарні маршрутиЛоги cloud-controller та події сервісу

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

2.2 Компоненти ноди та форми їхніх збоїв

Розділ «2.2 Компоненти ноди та форми їхніх збоїв»

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

КомпонентЧим володієФорма збоюКорисний перший доказ
kubeletЖиттєвий цикл подів на ноді, звітування про статус, проби, налаштування томівНода NotReady, поди застрягли на створенні, події пробkubectl describe node <node> та логи kubelet
середовище виконання контейнерівЗавантаження образів, запуск контейнерів, виходи контейнерівImagePullBackOff, збої запуску, помилки середовища виконанняПодії пода та статус сервісу середовища виконання
плагін CNIНалаштування мережевого інтерфейсу та маршрутизації подаПоди не можуть отримати мережу, міжподовий трафік відмовляєПодії kubelet та логи подів CNI
kube-proxy або dataplane сервісівМаршрутизація віртуального IP сервісуСервіс досяжний з одних шляхів, але не з іншихЕндпоїнти, логи dataplane ноди, тести сервісу
вузловий плагін CSIМонтування та підключення сховища на нодіFailedMount, події підключення чи монтування PVCПодії пода, статус PVC/PV, логи CSI

Корисне питання про ноду: «той самий шаблон пода відмовляє на кожній ноді чи лише на цій ноді?» Якщо лише одна нода показує збій, інспектуйте умови ноди та локальні компоненти. Якщо той самий збій слідує за робочим навантаженням між нодами, інспектуйте специфікацію навантаження, зовнішні залежності або спільні сервіси кластера.

2.3 Контролери робочих навантажень як докази, а не лише контейнери

Розділ «2.3 Контролери робочих навантажень як докази, а не лише контейнери»

Деплойменти, ReplicaSet-и, StatefulSet-и, DaemonSet-и та джоби кожен додає власний статус і слід подій. Крах пода часто видно на рівні пода, але збій викочування видно на рівні деплойменту. Збій джоба може потребувати погляду на завершені чи невдалі поди, які контролер створив раніше. Проблема зі сховищем StatefulSet-а може проявлятися в PVC так само, як у подіях пода.

Terminal window
kubectl describe deployment <name> -n <namespace>
kubectl rollout status deployment/<name> -n <namespace> --timeout=90s
kubectl get rs -n <namespace> -l app=<label> -o wide
kubectl get jobs -n <namespace>
kubectl describe job <name> -n <namespace>

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

2.4 Активне навчання: слідуйте за межею володіння

Розділ «2.4 Активне навчання: слідуйте за межею володіння»

Уявіть, що існує сервіс на ім’я checkout, DNS розв’язує checkout.default.svc.cluster.local, але запити зависають, доки не відваляться за тайм-аутом. Бекенд-поди в стані Running, проте kubectl get endpoints checkout не повертає жодних адрес. Перш ніж перевіряти логи CoreDNS, поясніть, чому порожній об’єкт ендпоїнтів є сильнішим доказом, ніж успішний DNS-запит.

Відповідь полягає в тому, що DNS лише доводить, що ім’я сервісу розв’язується у віртуальний IP сервісу. Він не доводить, що Kubernetes має будь-які готові бекенд-поди, обрані для цього сервісу. Порожні ендпоїнти вказують на невідповідність селектора, збій readiness-проби або поди, що не збігаються з простором імен та мітками сервісу, тож наступні перевірки мають порівняти селектори сервісу з мітками подів та умовами готовності.


Частина 3: Драбина діагностичних команд

Розділ «Частина 3: Драбина діагностичних команд»

Драбина команд — це навмисний порядок, а не глосарій команд. Кожна сходинка відповідає на інше питання й має впливати на наступну сходинку. Ви підіймаєтеся лише настільки, наскільки потрібно, і не стрибаєте до високоризикових чи дуже детальних команд, перш ніж простіші докази звузять шлях.

┌──────────────────────────────────────────────────────────────────────────────┐
│ COMMAND LADDER │
│ │
│ 1. OVERVIEW kubectl get pods -A What is affected and where? │
│ 2. EVENTS describe / get events What did Kubernetes report? │
│ 3. STATUS get -o yaml/jsonpath What state does the API store? │
│ 4. LOGS kubectl logs --previous What did the process say? │
│ 5. IN-POD TEST kubectl exec What happens from inside path? │
│ 6. NODE TEST journalctl / systemctl Is the local agent healthy? │
│ 7. CONTROL PLANE readyz / kube-system logs Are shared components healthy? │
│ │
└──────────────────────────────────────────────────────────────────────────────┘

Драбина також береже екзаменаційний час. Багато завдань CKA з усунення несправностей ви можете розв’язати першими чотирма сходинками: get, describe, logs та цілеспрямоване виправлення. Перевірки ноди та площини управління важливі, але вони мають слідувати за доказами, а не заміняти базову інспекцію робочого навантаження.

Команди огляду відповідають на «що зламано?» та «наскільки воно широке?». Вони мають бути достатньо швидкими, щоб ви могли виконати їх, не втрачаючи темпу. Використовуйте простори імен і мітки, коли ви їх знаєте, але починайте ширше, коли симптом неясний.

Terminal window
kubectl get pods -A -o wide
kubectl get nodes -o wide
kubectl get deploy,rs,pods -n <namespace>
kubectl get svc,endpoints,endpointslices -n <namespace>
kubectl get events -A --sort-by='.lastTimestamp' | tail -30

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

3.2 Describe перед логами

Розділ «3.2 Describe перед логами»

describe зазвичай найкраща друга команда, бо містить власне пояснення Kubernetes щодо нещодавніх збоїв. Він показує події, обрану ноду, томи, стан контейнера, стан останнього завершення, готовність, лічильник перезапусків та повідомлення проб. Логи можуть пояснити запущений процес, але вони не можуть пояснити, чому процес так і не запустився.

Terminal window
kubectl describe pod <pod-name> -n <namespace>
kubectl describe deployment <deployment-name> -n <namespace>
kubectl describe node <node-name>
kubectl describe pvc <claim-name> -n <namespace>

Сильний оператор читає describe і згори, і знизу. Верх каже вам поточний стан і зв’язки об’єктів. Розділ Events унизу каже вам, що планувальник, kubelet та контролери намагалися зробити й чому зазнали невдачі. У багатьох збоях розділ Events — найкоротший шлях до першопричини.

┌──────────────────────────────────────────────────────────────────────────────┐
│ DESCRIBE OUTPUT SECTIONS │
│ │
│ SECTION WHAT TO LOOK FOR │
│ ───────────────────────────────────────────────────────────────────────── │
│ │
│ Name / Namespace Confirm you are inspecting the intended object │
│ Node See whether the pod was scheduled and where it landed │
│ Status Current phase, but not the full health story │
│ IP / Controlled By Pod address and owning controller │
│ Containers State, Ready, Restart Count, Last State, image │
│ Conditions PodScheduled, Initialized, Ready, ContainersReady │
│ Volumes ConfigMaps, Secrets, PVCs, projected service account │
│ QoS Class Resource request and limit class affecting eviction │
│ Events Scheduler, kubelet, mount, image, probe, and warnings │
│ │
│ The Events section is often the highest-value evidence, but it is not the │
│ only section. Container state and conditions tell you whether the event is │
│ current, historical, or already resolved. │
└──────────────────────────────────────────────────────────────────────────────┘

3.3 Логи та попередні логи

Розділ «3.3 Логи та попередні логи»

Логи відповідають на те, що процес контейнера записав у stdout і stderr — стандартний шлях логування застосунку, який очікує Kubernetes. Для пода, який перезапустився, поточні логи можуть показувати лише новий екземпляр контейнера, що може приховати фактичний крах. Використовуйте --previous, коли лічильник перезапусків більший за нуль або коли розділ Events каже, що контейнер завершився.

Terminal window
kubectl logs <pod-name> -n <namespace>
kubectl logs <pod-name> -n <namespace> --previous
kubectl logs <pod-name> -n <namespace> -c <container-name>
kubectl logs deployment/<deployment-name> -n <namespace> --tail=100

Багатоконтейнерні поди вимагають явного вибору контейнера. Sidecar може виглядати справним, тоді як контейнер застосунку падає, тож завжди визначайте імена контейнерів, перш ніж дійти висновку, що логи чисті. Специфікація пода та JSONPath можуть швидко перелічити контейнери.

Terminal window
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.containers[*].name}{"\n"}'
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[*].name}{"\n"}'

3.4 YAML і JSONPath для точних доказів

Розділ «3.4 YAML і JSONPath для точних доказів»

Коли describe підсумовує забагато, читайте збережений об’єкт API напряму. YAML корисний для порівняння селекторів, міток, проб, ресурсів, монтувань, толерувань та посилань на середовище. JSONPath корисний, коли вам потрібне одне точне поле під час екзамену або коли ви хочете уникнути візуального перегляду великого об’єкта.

Terminal window
kubectl get pod <pod-name> -n <namespace> -o yaml
kubectl get svc <service-name> -n <namespace> -o yaml
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.phase}{"\n"}'
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[0].restartCount}{"\n"}'
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}{"\n"}'

YAML — це також місце, де ви ловите тонкі проблеми невідповідності. Селектор сервісу app: web не обере поди з міткою app.kubernetes.io/name: web. Том, що посилається на configMap.name: app-config, відмовить, якщо ConfigMap існує в іншому просторі імен, бо посилання в межах простору імен не перетинають його меж.

3.5 Події як упорядковані за часом докази

Розділ «3.5 Події як упорядковані за часом докази»

Події Kubernetes — це короткочасні сигнали, що їх видають контролери та агенти нод. Вони не є повноцінною системою логування, але вони часто є найкращим безпосереднім доказом для збоїв планування, завантаження образу, монтування та проб. Сортуйте їх за міткою часу, коли простір імен має багато об’єктів.

Terminal window
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
kubectl get events -A --field-selector type=Warning --sort-by='.lastTimestamp'
kubectl get events -n <namespace> --field-selector involvedObject.name=<pod-name>

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

3.6 Внутрішньоподові мережеві та DNS-тести

Розділ «3.6 Внутрішньоподові мережеві та DNS-тести»

Мережеві тести мають сенс лише тоді, коли їх запускають з правильного місця. Тестування сервісу з вашого ноутбука — це не те саме, що тестування його з пода в тому самому просторі імен і контексті політик. Для збоїв усередині кластера запустіть тимчасовий под або зайдіть через exec у споріднений под і протестуйте те саме DNS-ім’я, порт і протокол, які використовує застосунок.

Terminal window
kubectl run netcheck -n <namespace> --image=busybox:1.36 --restart=Never -- sleep 3600
kubectl exec -n <namespace> netcheck -- nslookup kubernetes.default.svc.cluster.local
kubectl exec -n <namespace> netcheck -- wget -qO- http://<service-name>:<port>/healthz
kubectl delete pod netcheck -n <namespace>

Якщо образ вашого кластера не містить wget чи nslookup, оберіть налагоджувальний образ, доступний у середовищі. У обмеженому середовищі мінімального налагоджувального образу часто достатньо для DNS та простих HTTP-перевірок. Важлива звичка — узгоджувати джерело й шлях призначення, а не тестувати з місця, яке обходить збій.

3.7 Перевірки ноди та площини управління

Розділ «3.7 Перевірки ноди та площини управління»

Перевірки ноди стають доречними, коли докази вказують нижче специфікації пода. Под, застряглий у ContainerCreating з повторюваними помилками середовища виконання, багато подів, що падають на одній ноді, чи нода, позначена NotReady, — усе це виправдовує перехід до доказів рівня ноди. На екзаменаційних кластерах у стилі kubeadm компоненти площини управління часто працюють як статичні поди в kube-system, тоді як kubelet працює як системний сервіс на ноді.

Terminal window
kubectl describe node <node-name>
kubectl -n kube-system get pods -o wide
kubectl -n kube-system logs <control-plane-pod-name> --tail=100
ssh <node-name> "systemctl status kubelet --no-pager"
ssh <node-name> "journalctl -u kubelet --no-pager -n 100"
ssh <node-name> "systemctl status containerd --no-pager"

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


Частина 4: Читання статусу пода, не даючи себе обдурити

Розділ «Частина 4: Читання статусу пода, не даючи себе обдурити»

Статус пода — корисний сигнал, але це не повний вердикт про справність. Running означає, що принаймні один контейнер запущений або був запущений, а не те, що застосунок готовий обслуговувати трафік. Pending може означати, що планувальник не розмістив под, але також може охоплювати час до підготовки образів і томів. Ви маєте поєднати фазу, умови, стан контейнера, лічильник перезапусків та події.

┌──────────────────────────────────────────────────────────────────────────────┐
│ POD PHASES │
│ │
│ ┌────────────┐ │
│ │ Pending │ │
│ │ scheduling │ │
│ │ or setup │ │
│ └─────┬──────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ all app containers exit 0 │
│ │ Running │───────────────────────────────┐ │
│ │ process or │ ▼ │
│ │ containers │ ┌────────────┐ │
│ └─────┬──────┘ │ Succeeded │ │
│ │ one container exits non-zero │ completed │ │
│ ▼ └────────────┘ │
│ ┌────────────┐ │
│ │ Failed │ │
│ │ terminal │ │
│ └────────────┘ │
│ │
│ ┌────────────┐ │
│ │ Unknown │ node communication lost or status unavailable│
│ └────────────┘ │
│ │
│ Phase is broad. Conditions and container states explain readiness, restarts, │
│ scheduling, image pulls, probe failures, and last termination reason. │
└──────────────────────────────────────────────────────────────────────────────┘

Под може мати фазу Running, тоді як умова Ready=False. Це трапляється, коли процес контейнера живий, але readiness-проби не проходять, sidecar не готовий або застосунок не слухає на очікуваному порту. Сервіси зазвичай маршрутизують лише до готових ендпоїнтів, тож поди в стані Running все одно можуть не отримувати трафіку.

4.1 Поширені стани подів та їхня перша корисна перевірка

Розділ «4.1 Поширені стани подів та їхня перша корисна перевірка»

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

Видимий статусЩо це зазвичай означаєПерша корисна перевіркаЩо ви намагаєтеся довести
PendingПод не запланований або очікує налаштуванняkubectl describe podРесурси, taint-и, спорідненість, квота чи відхилення планування
ContainerCreatingПризначений ноді, kubelet готує контейнерkubectl describe podЗавантаження образу, монтування тому, CNI чи посилання на Secret/ConfigMap
ImagePullBackOffЗавантаження образу не вдалося, kubelet робить відкатkubectl describe podПоганий образ, поганий тег, автентифікація реєстру чи недосяжний реєстр
CreateContainerConfigErrorНе вдається сконструювати конфігурацію контейнераkubectl describe podВідсутній ConfigMap, Secret, ключ чи невалідне посилання на env
CrashLoopBackOffКонтейнер неодноразово виходить після запускуkubectl describe pod, потім kubectl logs --previousЗбій проби, помилка застосунку, погана команда, OOM чи збій залежності
Running, але Ready=FalseПроцес запустився, але непридатний для сервісуkubectl describe pod та деталі готовностіЗбій readiness-проби, неправильний порт, залежність чи повільний старт
EvictedKubelet видалив под через тиск на ноді чи політикуkubectl describe pod та kubectl describe nodeТиск пам’яті, диска, PID, пріоритет чи запити ресурсів
UnknownПлощина управління не може отримати поточний статус з нодиkubectl describe nodeKubelet, мережа ноди, середовище виконання чи доступність ноди

4.2 Розбір прикладу CrashLoopBackOff

Розділ «4.2 Розбір прикладу CrashLoopBackOff»

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

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

Terminal window
kubectl create ns method-demo
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: crash-demo
namespace: method-demo
spec:
containers:
- name: app
image: busybox:1.36
command:
- sh
- -c
- echo "starting demo"; sleep 2; echo "failing now"; exit 1
EOF

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

Terminal window
kubectl get pod crash-demo -n method-demo

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

Terminal window
kubectl describe pod crash-demo -n method-demo

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

Terminal window
kubectl logs crash-demo -n method-demo --previous

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

Terminal window
kubectl get pod crash-demo -n method-demo -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}{"\n"}'

Відремонтуйте под, замінивши падаючу команду на довготривалу. У звичайній продакшен-роботі ви редагували б версійовані маніфести чи оновлювали шаблон деплойменту, але окремий практичний под можна замінити напряму.

Terminal window
kubectl delete pod crash-demo -n method-demo
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: crash-demo
namespace: method-demo
spec:
containers:
- name: app
image: busybox:1.36
command:
- sh
- -c
- echo "starting demo"; sleep 3600
EOF

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

Terminal window
kubectl get pod crash-demo -n method-demo
kubectl logs crash-demo -n method-demo

Урок з цього прикладу — у послідовності. describe довів, що контейнер запустився й перезапустився. logs --previous розкрив, що записав завершений процес. JSONPath підтвердив код виходу. Ремонт змінив лише підтверджену падаючу команду. Валідація перевірила той самий об’єкт і симптом, які були зламані спочатку.

4.3 Коди виходу та причини завершення

Розділ «4.3 Коди виходу та причини завершення»

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

Вихід або причинаІмовірне значенняПідтвердьте черезТиповий напрямок ремонту
Код виходу 1Застосунок повернув загальну помилкуkubectl logs --previousВиправте команду, конфігурацію, залежність чи баг застосунку
Код виходу 126Команда знайдена, але не виконуванаОбраз контейнера та поле командиВиправте права файлу чи шлях команди
Код виходу 127Команда не знайденаКоманда в специфікації пода та вміст образуВикористайте правильний бінарник чи образ
Код виходу 137SIGKILL, часто OOMKilledLast State, ліміти пода, тиск нодиСкоригуйте пам’ять, виправте витік, налаштуйте запити й ліміти
Код виходу 143SIGTERM, часто плавна зупинкаПодії, викочування, виселення, час завершенняПеревірте дію контролера чи поведінку завершення
Причина OOMKilledКонтейнер перевищив ліміт пам’яті або тиск ноди вбив йогоkubectl describe pod та метрикиЗбільшуйте ліміт лише після розуміння використання
Причина ErrorПроцес вийшов із ненульовим кодомЛоги та конфігурація застосункуВиправте причину рівня застосунку
Причина Completed у довготривалому подіПроцес несподівано вийшов із нулем для цього типу навантаженняКоманда, аргументи, тип контролераВикористайте правильний контролер чи довготривалу команду

Поширена помилка — сприймати OOMKilled просто як «збільшити пам’ять». Іноді це правильно, але не завжди. Якщо застосунок раптом використовує вдесятеро більше пам’яті після релізу, підвищення лімітів може приховати регресію. Якщо под не має запиту пам’яті й потрапляє на перевантажену ноду, встановлення відповідних запитів може бути так само важливим, як і зміна ліміту.

4.4 Running не означає Ready

Розділ «4.4 Running не означає Ready»

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

Terminal window
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}{"\n"}'
kubectl describe pod <pod-name> -n <namespace> | sed -n '/Readiness/,/Environment/p'
kubectl get endpointslices -n <namespace> -l kubernetes.io/service-name=<service-name>

Діапазон sed вище припускає фіксований порядок розділів у виводі describe; порядок розділів може відрізнятися за версією Kubernetes, тож повертайтеся до читання повного опису, коли діапазон не повертає нічого корисного.

Коли сервіс не має ендпоїнтів, а поди в стані Running, порівняйте готовність і мітки перед налагодженням DNS. Розв’язання DNS може бути успішним, навіть коли набір ендпоїнтів порожній. Віртуальний IP сервісу може існувати, але kube-proxy чи dataplane сервісів не має готових бекенд-адрес, куди надсилати трафік.


Частина 5: Тріаж сервісу, мережі та сховища

Розділ «Частина 5: Тріаж сервісу, мережі та сховища»

Усунення несправностей робочого навантаження часто розширюється на сервіс, мережу чи сховище, бо Kubernetes складає багато об’єктів в один шлях застосунку. Деплоймент може бути коректним, тоді як його селектор сервісу неправильний. Под може бути готовим, тоді як мережева політика блокує простір імен, що викликає. Под бази даних може застрягти, бо PVC не може зв’язатися. Метод залишається тим самим: спостерігати, ізолювати, інспектувати, ремонтувати, валідувати.

Налагодження шляху сервісу

Розділ «Налагодження шляху сервісу»

Налагодження сервісу починається з відокремлення розв’язання імені від вибору ендпоїнтів та маршрутизації порту. DNS може розв’язати ім’я сервісу, навіть коли сервіс не має ендпоїнтів. Ендпоїнти можуть існувати, тоді як сервіс націлений на неправильний порт. Застосунок може слухати на одному порту, тоді як targetPort сервісу вказує на інший.

┌──────────────────────────────────────────────────────────────────────────────┐
│ SERVICE REQUEST PATH │
│ │
│ Client Pod │
│ │ │
│ │ 1. DNS lookup: backend.default.svc.cluster.local │
│ ▼ │
│ Service Virtual IP │
│ │ │
│ │ 2. Service selector chooses ready pods through EndpointSlices │
│ ▼ │
│ EndpointSlice addresses │
│ │ │
│ │ 3. targetPort maps service port to container listening port │
│ ▼ │
│ Backend Pod container │
│ │
│ A failure at any step can look like "the service is down." Test each step │
│ separately so you do not repair the wrong object. │
└──────────────────────────────────────────────────────────────────────────────┘

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

Terminal window
kubectl get svc <service-name> -n <namespace> -o yaml
kubectl get pods -n <namespace> --show-labels
kubectl get endpoints <service-name> -n <namespace>
kubectl get endpointslices -n <namespace> -l kubernetes.io/service-name=<service-name> -o wide

Якщо ендпоїнти існують, протестуйте відображення портів. port сервісу — це те, що використовують клієнти. targetPort сервісу — це те, на чому бекенд-поди мають фактично слухати. Іменований targetPort має збігатися з іменованим портом контейнера, що покращує читабельність YAML, але може відмовити, якщо ім’я неправильне.

Terminal window
kubectl get svc <service-name> -n <namespace> -o jsonpath='{.spec.ports[*].port}{" -> "}{.spec.ports[*].targetPort}{"\n"}'
kubectl exec -n <namespace> <client-pod> -- wget -qO- http://<service-name>:<port>/healthz

Проблеми DNS слід тестувати зсередини кластера. Перше питання — чи може под-клієнт розв’язати ім’я. Друге — чи може він з’єднатися з розв’язаним сервісом. Третє — чи здоровий сам CoreDNS, якщо кілька подів і просторів імен мають збої розв’язання.

Terminal window
kubectl exec -n <namespace> <client-pod> -- nslookup kubernetes.default.svc.cluster.local
kubectl exec -n <namespace> <client-pod> -- nslookup <service-name>.<namespace>.svc.cluster.local
kubectl -n kube-system get pods -l k8s-app=kube-dns -o wide
kubectl -n kube-system logs -l k8s-app=kube-dns --tail=100

Не плутайте збій DNS зі збоєм HTTP. nslookup доводить лише розв’язання імені. Якщо DNS успішний, але HTTP відмовляє, переходьте до ендпоїнтів сервісу, цільових портів, готовності, конфігурації слухача застосунку та мережевої політики. Якщо DNS відмовляє для кожного імені сервісу з кількох подів, CoreDNS чи конфігурація DNS кластера стає правдоподібнішою.

Тріаж мережевої політики

Розділ «Тріаж мережевої політики»

Збої мережевої політики — це передусім проблеми політики й міток, і лише потім проблеми пакетів. Політика обирає поди, потім визначає дозволений вхідний (ingress) чи вихідний (egress) трафік. Якщо под обрано обмежувальною політикою, і жодне правило не дозволяє трафік, трафік заборонено, навіть коли сервіси, ендпоїнти та DNS інакше коректні.

Terminal window
kubectl get networkpolicy -n <namespace>
kubectl describe networkpolicy <policy-name> -n <namespace>
kubectl get pods -n <namespace> --show-labels
kubectl exec -n <namespace> <client-pod> -- wget -qO- http://<service-name>:<port>/

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

Збої сховища часто проявляються як поди, застряглі в Pending чи ContainerCreating, але докази в основі можуть жити в PVC, PV, StorageClass чи подах CSI-драйвера. Под не може запуститися, якщо необхідний йому том не може зв’язатися, підключитися чи змонтуватися. Подія пода зазвичай указує на об’єкт сховища, що потребує глибшої інспекції.

Terminal window
kubectl get pvc -n <namespace>
kubectl describe pvc <claim-name> -n <namespace>
kubectl get pv
kubectl get storageclass
kubectl describe pod <pod-name> -n <namespace>
kubectl -n kube-system get pods | grep -i csi

Ключова відмінність — зв’язування проти монтування. PVC, застряглий у Pending, зазвичай означає, що він не може зв’язатися з PV або динамічне забезпечення (provisioning) не вдалося. Под, застряглий з FailedMount, може означати, що PVC зв’язаний, але нода не може підключити чи змонтувати том. Це різні рівні, що потребують різних доказів.

Симптом сховищаІмовірний рівеньДокази для інспекціїПоширений напрямок ремонту
PVC застряг у PendingЗабезпечення чи зв’язуванняkubectl describe pvc та StorageClassВиправте StorageClass, місткість, режим доступу чи провіжнер
Подія пода каже FailedMountМонтування на ноді чи том secret/configkubectl describe pod та події kubeletВиправте посилання на том, права чи вузловий плагін CSI
Подія пода каже тайм-аут підключенняПідключення CSI чи шлях хмарного томуPVC, PV, логи контролера CSIПеревірте справність драйвера та обмеження підключення тому
Под StatefulSet-а чекає на томКонтролер і шаблон PVCСтатус StatefulSet-а та PVCІнспектуйте поподовий claim та поведінку storage class
Том ConfigMap відсутнійПосилання робочого навантаженняПодії пода та список об’єктів простору іменСтворіть правильний ConfigMap у тому самому просторі імен чи виправте ім’я

Частина 6: Екзаменаційні та продакшен-патерни

Розділ «Частина 6: Екзаменаційні та продакшен-патерни»

Патерни та антипатерни

Розділ «Патерни та антипатерни»

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

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

ПатернВикористовуйте, колиЧому масштабуєтьсяАнтипатерн, якого слід уникати
Перший прохід лише для читанняСимптом неясний чи шумнийЗберігає події, попередні логи, історію перезапусків та підказки про розміщення для подальших міркуваньПерезапуск подів до збору доказів
Пошарова ізоляціяТой самий симптом може походити від навантаження, ноди, сервісу, сховища чи площини управлінняЗапобігає налагодженню компонентів, які ще не можуть бути причетнимиНазивати кожен непояснений збій «мережею»
Одне підтверджене виправлення за разУ вас більше одного правдоподібного ремонтуТримає причину й наслідок видимими, що важливо для екзаменів, передавання справ та навчання після інцидентуЛатання образів, проб, селекторів і ресурсів разом
Валідація на основі шляхуБажаний результат — це досяжність, справність викочування чи доступ до залежностіДоводить виправлення з погляду того, хто викликає, а не з погляду статусу одного об’єктаЗупинка, коли под стає Running
┌──────────────────────────────────────────────────────────────────────────────┐
│ THREE-PASS TROUBLESHOOTING STRATEGY │
│ │
│ PASS 1: Fast evidence and obvious fixes, usually one to three minutes │
│ - Wrong namespace, wrong context, typo in image, missing object name │
│ - Selector mismatch, obvious missing ConfigMap or Secret, bad targetPort │
│ │
│ PASS 2: Standard layered debugging, usually four to seven minutes │
│ - Pod lifecycle, rollout status, readiness, endpoints, DNS, simple policy │
│ - Resource requests, taints, affinity, PVC binding, probe failures │
│ │
│ PASS 3: Deeper cluster and node investigation, only when evidence points │
│ - Node NotReady, kubelet or runtime failure, control plane readiness │
│ - CSI, CNI, scheduler, or controller-manager failures │
│ │
│ If the first three minutes produce no narrowing evidence, mark the task and │
│ return after collecting points from faster questions. │
└──────────────────────────────────────────────────────────────────────────────┘

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

6.1 Часово обмежений цикл усунення несправностей на CKA

Розділ «6.1 Часово обмежений цикл усунення несправностей на CKA»

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

Terminal window
kubectl config current-context
kubectl get ns
kubectl get pods -n <namespace> -o wide
kubectl describe pod <pod-name> -n <namespace>
kubectl get deploy,svc,endpoints -n <namespace>

Якщо у формулюванні завдання дано шлях сервісу чи застосунку, валідуйте через цей шлях, а не зупиняйтеся на статусі пода. Якщо завдання каже «зробити вебсервіс досяжним», то важать ендпоїнт сервісу та HTTP-перевірка. Якщо завдання каже «виправити викочування деплойменту», то важить kubectl rollout status.

6.2 Дисципліна реагування на інциденти в продакшені

Розділ «6.2 Дисципліна реагування на інциденти в продакшені»

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

Звичка щодо інцидентуЧому це важливоПриклад Kubernetes
Точно сформулюйте симптомЗапобігає тому, щоб команда розв’язувала різні проблеми«поди checkout готові, сервіс має порожні ендпоїнти»
Зберігайте ключові доказиУникає втрати короткочасних подій та попередніх логівЗбережіть вивід describe та logs --previous, коли корисно
Робіть одне виправлення за разТримає причину й наслідок видимимиВиправте тег образу перед зміною проб чи ресурсів
Валідуйте шлях користувачаЗапобігає хибному відновленнюТестуйте з фронтенд-пода через DNS сервісу
Фіксуйте подальший ризикВідокремлює негайний ремонт від тривкого запобіганняДодайте політику тегів образів чи тест готовності пізніше

Найкращі фахівці з усунення несправностей — це не ті люди, що ніколи не вгадують. Це люди, які роблять здогади явними як гіпотези, а потім дешево їх перевіряють. «Гадаю, це невідповідність селектора, бо сервіс не має ендпоїнтів, тоді як поди готові» — це перевірюване твердження. «Мережа зламана» — надто широко, щоб скеровувати дію.

6.3 Матриця рішень для наступної команди

Розділ «6.3 Матриця рішень для наступної команди»

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

Питання, на яке потрібна відповідьКомандаЯкщо такЯкщо ні
Чи збій ізольований в одному просторі імен?kubectl get pods -A -o wideІнспектуйте навантаження простору іменІнспектуйте ноди чи спільні сервіси
Чи под запланувався?kubectl describe pod <pod> -n <ns>Інспектуйте kubelet, образ, том, стан контейнераІнспектуйте події планувальника та обмеження нод
Чи контейнер запустився й вийшов?kubectl describe pod та kubectl logs --previousІнспектуйте команду застосунку, конфігурацію, проби, ресурсиІнспектуйте образ, монтування та конструювання конфігурації
Чи под готовий до трафіку сервісу?kubectl get pod <pod> -o jsonpath=...Інспектуйте ендпоїнти й порти сервісуІнспектуйте readiness-пробу та слухача застосунку
Чи сервіс обирає готові поди?kubectl get endpointslicesПротестуйте цільовий порт та відповідь застосункуПорівняйте селектор, мітки й готовність
Чи одна нода особлива?kubectl get pods -A -o wideІнспектуйте умови ноди й kubeletІнспектуйте навантаження чи спільний рівень кластера
Чи нещодавні події вказують на причину?kubectl get events --sort-by='.lastTimestamp'Слідуйте за залученим об’єктомВикористайте YAML, логи, метрики чи статус контролера
Чи сам API достатньо здоровий?kubectl get --raw='/readyz?verbose'Продовжуйте налагодження рівня об’єктівІнспектуйте справність компонентів площини управління

Структура прийняття рішень

Розділ «Структура прийняття рішень»

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

Тренування 1: Огляд кластера менш ніж за хвилину

Розділ «Тренування 1: Огляд кластера менш ніж за хвилину»

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

Terminal window
kubectl get nodes -o wide
kubectl get pods -A -o wide
kubectl get events -A --field-selector type=Warning --sort-by='.lastTimestamp' | tail -20

Хороший результат — це не просто «я виконав три команди». Хороший результат — це коротке твердження на кшталт «лише payments має поди, що падають, і обидва падаючі поди на різних нодах, тож далі я інспектуватиму деплоймент і шаблон пода». Це твердження показує, що огляд звузив ваш пошук.

Тренування 2: Тріаж життєвого циклу пода

Розділ «Тренування 2: Тріаж життєвого циклу пода»

Це тренування відповідає на питання, де под застряг у своєму життєвому циклі. Використовуйте його для Pending, ContainerCreating, CrashLoopBackOff, збоїв готовності та несподіваних перезапусків. Послідовність рухається від підсумку до подій Kubernetes і до доказів контейнера.

Terminal window
kubectl get pod <pod-name> -n <namespace> -o wide
kubectl describe pod <pod-name> -n <namespace>
kubectl get pod <pod-name> -n <namespace> -o yaml

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

Тренування 3: Розслідування краху

Розділ «Тренування 3: Розслідування краху»

Це тренування відповідає на питання, чому контейнер перезапустився. Воно поєднує попередні логи зі статусом завершення й уникає поширеної помилки читання лише поточних логів контейнера. Використовуйте його щоразу, коли лічильник перезапусків ненульовий.

Terminal window
kubectl describe pod <pod-name> -n <namespace>
kubectl logs <pod-name> -n <namespace> --previous
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[*].lastState.terminated.exitCode}{"\n"}'
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[*].restartCount}{"\n"}'

Ваш висновок має поєднати докази з причиною. «Под у CrashLoop, бо попередній лог контейнера каже, що він не може прочитати /etc/app/config.yaml, а події пода показують, що том ConfigMap успішно змонтувався, тож я інспектуватиму шлях файлу й аргументи застосунку» — краще за «застосунок упав».

Тренування 4: Перевірка ендпоїнтів сервісу

Розділ «Тренування 4: Перевірка ендпоїнтів сервісу»

Це тренування відповідає на питання, чи маршрутизація сервісу має придатні бекенд-поди. Воно корисне, коли об’єкт сервісу існує, але трафік відмовляє. Порівняйте селектори й мітки, перш ніж припускати, що DNS чи CNI зламані.

Terminal window
kubectl get svc <service-name> -n <namespace> -o yaml
kubectl get endpoints <service-name> -n <namespace>
kubectl get endpointslices -n <namespace> -l kubernetes.io/service-name=<service-name> -o wide
kubectl get pods -n <namespace> --show-labels

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

Тренування 5: DNS та внутрішньокластерне з’єднання

Розділ «Тренування 5: DNS та внутрішньокластерне з’єднання»

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

Terminal window
kubectl exec -n <namespace> <client-pod> -- nslookup <service-name>.<namespace>.svc.cluster.local
kubectl exec -n <namespace> <client-pod> -- wget -qO- http://<service-name>:<port>/healthz
kubectl -n kube-system get pods -l k8s-app=kube-dns -o wide

Інтерпретуйте результат пошарово. Збій DNS указує на CoreDNS, шлях пошуку чи мережу до DNS. Успіх DNS зі збоєм HTTP указує на ендпоїнти сервісу, цільовий порт, мережеву політику чи слухача застосунку. Успіх HTTP з одного пода, але не з іншого, указує на політику, специфічну для джерела, чи відмінності просторів імен.

Тренування 6: Перевірка справності ноди

Розділ «Тренування 6: Перевірка справності ноди»

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

Terminal window
kubectl describe node <node-name>
kubectl get pods -A -o wide --field-selector spec.nodeName=<node-name>
ssh <node-name> "systemctl status kubelet --no-pager"
ssh <node-name> "journalctl -u kubelet --no-pager -n 100"
ssh <node-name> "systemctl status containerd --no-pager"

Шукайте умови тиску, проблеми з heartbeat kubelet, збої середовища виконання, тиск диска та помилки CNI. Якщо лише одне навантаження падає на інакше здоровій ноді, поверніться до доказів навантаження. Якщо багато непов’язаних навантажень падають на одній ноді, нода заслуговує глибшої уваги.

Тренування 7: Зв’язування й монтування сховища

Розділ «Тренування 7: Зв’язування й монтування сховища»

Це тренування відповідає на питання, чи збій сховища відбувається на етапі зв’язування, чи на етапі монтування. Статус PVC і події пода разом кажуть вам, чи планувальник і kubelet чекають на сховище. Ця відмінність важлива, бо зв’язування й монтування залучають різні компоненти.

Terminal window
kubectl get pvc -n <namespace>
kubectl describe pvc <claim-name> -n <namespace>
kubectl describe pod <pod-name> -n <namespace>
kubectl get storageclass

Якщо PVC у Pending, інспектуйте StorageClass, запитаний режим доступу, місткість та провіжнер. Якщо PVC у Bound, але под звітує FailedMount, інспектуйте події монтування на ноді, справність вузлового плагіна CSI та точне посилання на том у поді.

Тренування 8: Тріаж збою викочування

Розділ «Тренування 8: Тріаж збою викочування»

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

Terminal window
kubectl rollout status deployment/<deployment-name> -n <namespace> --timeout=60s
kubectl describe deployment <deployment-name> -n <namespace>
kubectl get rs,pods -n <namespace> -l <selector-key>=<selector-value> -o wide
kubectl describe pod <new-pod-name> -n <namespace>

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


  • Події — це докази з терміном придатності: події Kubernetes призначені для нещодавніх операційних сигналів, а не для довгострокової історії інцидентів, тож продакшен-кластери мають відправляти логи й події до тривких систем спостережуваності.
  • Running — це фаза, а не обіцянка: под може бути в стані Running, тоді як готовність хибна, ендпоїнти порожні або застосунок повертає помилки реальним клієнтам.
  • describe — це багаторівнева команда: один опис пода може показати рішення планувальника, збої kubelet, стан завершення контейнера, посилання на томи, повідомлення проб та нещодавні події.
  • DNS сервісу може бути успішним, тоді як трафік усе одно відмовляє: DNS розв’язує ім’я сервісу у віртуальний IP, але вибір ендпоїнтів, готовність, цільові порти, політика та слухачі застосунку все ще вирішують, чи запити працюють.

ПомилкаЧому вона трапляєтьсяЯк її виправити
Стрибок одразу до логів для кожної проблеми подаЛоги відчуваються знайомими, але вони не існують для незапланованих подів і часто пропускають збої образу, тому та конструювання конфігураціїСпершу виконайте kubectl describe pod, потім використовуйте логи, коли контейнер справді запустився
Перезапуск чи видалення подів до збору доказівПерезапуск виглядає нешкідливим, але може стерти попередні логи, скинути часові підказки й приховати початковий симптомЗафіксуйте статус, події, лічильник перезапусків та попередні логи перед мутацією стану
Сприйняття Running як справногоФаза пода видима й легко викликає довіру, тоді як готовність та публікація ендпоїнтів менш очевидніПеревірте умови готовності, ендпоїнти та реальний шлях запиту
Налагодження DNS перед перевіркою ендпоїнтів сервісуУспішний пошук сервісу звучить як доказ мережі, але DNS може розв’язати сервіс без готових бекендівСпершу інспектуйте селектори, мітки, готовність, ендпоїнти й цільові порти
Кілька спекулятивних виправлень одночасноТиск винагороджує видиму дію, але кілька змін приховують, яке виправлення спрацювало, і можуть створити нові збоїЗмініть одну підтверджену причину, потім валідуйте початковий симптом
Ігнорування простору імен і контекстуКоманди можуть інспектувати справні об’єкти, тоді як зламане навантаження живе деіндеПідтвердьте контекст, простір імен та ім’я об’єкта перед інтерпретацією виводу
Припущення, що доступ до ноди завжди наступний крокНалагодження через SSH відчувається глибшим, але марнує час, коли докази вказують на YAML навантаження чи вибір сервісуПереходьте до перевірок ноди лише після того, як докази пода чи ноди підтримують цей рівень
Зупинка валідації на зеленому статусі подаЗелений под приємний, але шлях навантаження все ще може відмовляти через сервіси, політику, готовність чи залежностіВалідуйте через статус викочування, ендпоїнти та внутрішньокластерний запит, що відповідає початковому збою

Q1: Викочування, що виглядає як крах застосунку

Розділ «Q1: Викочування, що виглядає як крах застосунку»

Ваша команда розгортає нову версію api, і деплоймент зупиняється. Найновіші поди показують CrashLoopBackOff, але колега каже негайно виконати kubectl logs deployment/api -n prod. У вас дві хвилини, щоб почати правильно. Яку команду ви виконаєте першою і яке рішення допоможе ухвалити її вивід?

Відповідь

Почніть із kubectl describe pod <new-api-pod> -n prod, обравши один із нових падаючих подів. Опис каже вам, чи Kubernetes успішно запланував под, завантажив образ, змонтував томи, побудував конфігурацію контейнера, а потім запустив процес, який упав. Якщо події показують збій образу, ConfigMap, Secret, монтування чи проби, логи можуть не бути першим корисним доказом. Якщо контейнер таки запустився й завершився, тоді переходьте до kubectl logs <pod> -n prod --previous, щоб інспектувати останній невдалий екземпляр процесу.

Фронтенд-под може розв’язати checkout.prod.svc.cluster.local, але HTTP-запити до http://checkout:8080/healthz відвалюються за тайм-аутом. kubectl get svc checkout -n prod показує, що сервіс існує. Які докази ви зберете далі та як два різні результати змінять ваш наступний крок?

Відповідь

Перевірте ендпоїнти сервісу через kubectl get endpoints checkout -n prod або kubectl get endpointslices -n prod -l kubernetes.io/service-name=checkout -o wide, потім порівняйте селектор сервісу з мітками подів через kubectl get svc checkout -n prod -o yaml та kubectl get pods -n prod --show-labels. Якщо ендпоїнти порожні, зосередьтеся на невідповідності селектора чи готовності подів, бо DNS уже був успішним. Якщо ендпоїнти існують, зосередьтеся на відображенні порту сервісу на targetPort, мережевій політиці та на тому, чи застосунок справді слухає на цільовому порту.

Q3: Под, що ніколи не мав логів

Розділ «Q3: Под, що ніколи не мав логів»

Под на ім’я report-worker перебуває в Pending кілька хвилин. Молодший інженер каже, що логи застосунку це пояснять, але kubectl logs report-worker -n analytics повертає помилку. Поясніть, чому логи — неправильний перший доказ, та визначте наступну команду.

Відповідь

Логи неправильні, бо под у стані Pending може ще не мати запущеного контейнера. Якщо планувальник не призначив под або kubelet не запустив контейнер, немає процесу застосунку, що виробляв би логи. Виконайте kubectl describe pod report-worker -n analytics і прочитайте розділ Events щодо FailedScheduling, квоти, taint-ів, спорідненості нод, зв’язування PVC чи інших доказів життєвого циклу. Якщо под був запланований, але чекає на налаштування, той самий опис укаже на проблеми з образом чи томом.

Q4: Збій, специфічний для ноди

Розділ «Q4: Збій, специфічний для ноди»

Три непов’язані навантаження падають після потрапляння на worker-2, тоді як ті самі навантаження коректно працюють на інших нодах. Падаючі поди показують ContainerCreating з повторюваними помилками середовища виконання. Як ви ізолюєте, чи це проблема навантаження, чи проблема ноди?

Відповідь

Спершу підтвердьте патерн розміщення через kubectl get pods -A -o wide --field-selector spec.nodeName=worker-2 і порівняйте його зі справними подами на інших нодах. Потім інспектуйте ноду через kubectl describe node worker-2, шукаючи події, пов’язані з готовністю, тиском, середовищем виконання та kubelet. Оскільки непов’язані навантаження падають лише на одній ноді й стан — ContainerCreating, докази рівня ноди виправдані. Якщо у вас є доступ до ноди, перевірте systemctl status kubelet, journalctl -u kubelet та systemctl status containerd на worker-2.

Q5: Успішний DNS-запит, що все одно відмовляє

Розділ «Q5: Успішний DNS-запит, що все одно відмовляє»

Розробник доводить, що DNS працює, виконавши nslookup payments із пода-клієнта. Застосунок усе одно не може з’єднатися з payments:9000. Спроєктуйте наступні дві перевірки та поясніть, що доводить кожна з них.

Відповідь

Спершу перевірте ендпоїнти через kubectl get endpoints payments -n <namespace> або EndpointSlice-и з міткою service-name. Це доводить, чи сервіс має готові адреси бекенд-подів. Другою перевіркою перевірте порт сервісу й targetPort через kubectl get svc payments -n <namespace> -o yaml, потім порівняйте його зі слухаючим портом контейнера чи іменованим портом у специфікації пода. Успіх DNS доводить лише розв’язання імені у віртуальний IP сервісу; ендпоїнти й targetPort доводять, чи трафік має бекенд і чи надсилається він до правильного порту контейнера.

Q6: Обробник даних, убитий OOM

Розділ «Q6: Обробник даних, убитий OOM»

Под обробки даних неодноразово перезапускається після нового релізу. kubectl describe pod показує, що причина останнього стану — OOMKilled і код виходу 137. Колега пропонує негайно подвоїти ліміт пам’яті. Як ви оцінюєте, чи це правильний ремонт?

Відповідь

Спершу підтвердьте докази завершення в kubectl describe pod, потім інспектуйте запити й ліміти контейнера через kubectl get pod <pod> -o yaml та нещодавнє використання, якщо метрики доступні через kubectl top pod <pod> -n <namespace> --containers. Подвоєння ліміту може бути доречним, якщо легітимний попит навантаження зріс і нода має місткість, але воно може приховати витік пам’яті чи погане визначення розміру запиту. Також інспектуйте, чи под має нереалістично низький ліміт, чи численні перезапуски почалися після конкретної версії образу та чи сприяв тиск пам’яті ноди. Ремонт має усувати діагностовану причину, а не просто прибирати видимий ліміт.

Q7: Пастка багатоконтейнерності

Розділ «Q7: Пастка багатоконтейнерності»

Под має контейнер app і sidecar log-agent. Сервіс повертає відповіді 500, але kubectl logs web-abc -n prod показує лише справні повідомлення sidecar. Що ви робите далі та як уникаєте повторної перевірки неправильного контейнера?

Відповідь

Перелічіть імена контейнерів через kubectl get pod web-abc -n prod -o jsonpath='{.spec.containers[*].name}{"\n"}', потім прочитайте логи контейнера застосунку через kubectl logs web-abc -n prod -c app. Якщо контейнер перезапустився, використайте kubectl logs web-abc -n prod -c app --previous. Багатоконтейнерні поди вимагають явного вибору контейнера, бо стандартна поведінка логів може повернути інший контейнер, ніж той, що обслуговує трафік. Тривка звичка — визначати контейнери, перш ніж інтерпретувати логи як доказ для всього пода.

Q8: Виправлення, що не було провалідоване

Розділ «Q8: Виправлення, що не було провалідоване»

Ви виправляєте друкарську помилку в образі деплойменту, і нові поди стають Running. Завдання каже «зробити вебзастосунок досяжним через сервіс web». У вас спокуса рухатися далі. Яку валідацію ви виконаєте, перш ніж вважати завдання завершеним?

Відповідь

Валідуйте запитаний шлях сервісу, а не лише фазу пода. Виконайте kubectl rollout status deployment/<name> -n <namespace>, щоб підтвердити сходження викочування, потім перевірте kubectl get endpointslices -n <namespace> -l kubernetes.io/service-name=web -o wide, щоб підтвердити, що сервіс має готові бекенди. Нарешті, зробіть внутрішньокластерний запит із придатного пода-клієнта, як-от kubectl exec -n <namespace> <client-pod> -- wget -qO- http://web:<port>/healthz. Початкова вимога — досяжність через сервіс, тож самих лише подів у стані Running недостатньо для валідації.


Практична вправа: систематична практика усунення несправностей

Розділ «Практична вправа: систематична практика усунення несправностей»

Ви створите зламані ресурси, діагностуєте їх п’ятикроковим методом, відремонтуєте лише підтверджені причини й валідуєте через шлях навантаження. Вправа навмисно поєднує збої образу, ConfigMap, готовності, селектора сервісу та ресурсів, бо реальні інциденти рідко приходять як окремі акуратні помилки.

Створіть одноразовий простір імен і розгорніть зламане навантаження. Маніфест виконуваний як написано, але містить кілька навмисних помилок, які ви маєте виявити за допомогою доказів, а не візуальним переглядом спершу.

Terminal window
kubectl create ns troubleshoot-lab
cat <<'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: broken-app
namespace: troubleshoot-lab
spec:
replicas: 2
selector:
matchLabels:
app: broken-app
template:
metadata:
labels:
app: broken-app
tier: backend
spec:
containers:
- name: app
image: nginx:latestt
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 3
periodSeconds: 5
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "500m"
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
volumes:
- name: config
configMap:
name: nginx-config
---
apiVersion: v1
kind: Service
metadata:
name: broken-app
namespace: troubleshoot-lab
spec:
selector:
app: broken-api
ports:
- name: http
port: 8080
targetPort: http
EOF

Завдання 1: Спостерігайте поточний стан

Розділ «Завдання 1: Спостерігайте поточний стан»

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

Terminal window
kubectl get deploy,rs,pods,svc,endpoints -n troubleshoot-lab -o wide
kubectl get events -n troubleshoot-lab --sort-by='.lastTimestamp'

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

  • Підтверджено, чи поди були створені деплойментом.
  • Підтверджено, чи поди досягли Running та Ready.
  • Підтверджено, чи сервіс має ендпоїнти.
  • Визначено найновіші попереджувальні події, не змінюючи жодного об’єкта.

Завдання 2: Ізолюйте перший зламаний рівень

Розділ «Завдання 2: Ізолюйте перший зламаний рівень»

Інспектуйте один зламаний под через describe. Не стрибайте до логів, доки не дізнаєтеся, чи запустився контейнер. Використайте розділ Events, щоб вирішити, чи перший зламаний рівень — це планувальник, завантаження образу, монтування тому, процес контейнера, готовність чи вибір сервісу.

Terminal window
POD_NAME="$(kubectl get pods -n troubleshoot-lab -l app=broken-app -o jsonpath='{.items[0].metadata.name}')"
kubectl describe pod "$POD_NAME" -n troubleshoot-lab

Ви маєте виявити принаймні два блокери запуску пода протягом ремонту. Точний порядок залежить від того, що Kubernetes звітує першим, але і друкарська помилка в образі, і відсутній ConfigMap — обидві реальні проблеми. Виправляйте одну підтверджену проблему за раз і повторно спостерігайте після кожного виправлення.

  • Визначено друкарську помилку в образі з подій чи стану контейнера.
  • Визначено відсутній ConfigMap nginx-config із подій після проблеми з образом чи поряд із нею.
  • Уникнуто використання логів до того, як контейнер справді запустився.
  • Записано коротку гіпотезу для кожного блокера перед застосуванням його ремонту.

Завдання 3: Відремонтуйте підтверджені блокери запуску

Розділ «Завдання 3: Відремонтуйте підтверджені блокери запуску»

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

Terminal window
kubectl set image deployment/broken-app -n troubleshoot-lab app=nginx:1.27
kubectl create configmap nginx-config -n troubleshoot-lab --from-literal=default.conf='server { listen 80; location / { return 200 "ok\n"; } location /ready { return 200 "ready\n"; } }'
kubectl rollout status deployment/broken-app -n troubleshoot-lab --timeout=90s
kubectl get pods -n troubleshoot-lab -l app=broken-app

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

  • Виправлено посилання на образ на валідний тег образу nginx.
  • Створено відсутній ConfigMap у тому самому просторі імен, що й под.
  • Повторно виконано describe чи статус викочування після кожного ремонту.
  • Підтверджено, що поди деплойменту в стані Running і готові, перш ніж переходити до валідації сервісу.

Завдання 4: Валідуйте шлях сервісу

Розділ «Завдання 4: Валідуйте шлях сервісу»

Тепер протестуйте вимогу, яка хвилювала б користувача: трафік через сервіс. Об’єкт сервісу існує, але селектор навмисно неправильний. Використайте ендпоїнти й мітки, щоб довести причину, перш ніж її латати.

Terminal window
kubectl get svc broken-app -n troubleshoot-lab -o yaml
kubectl get endpoints broken-app -n troubleshoot-lab
kubectl get endpointslices -n troubleshoot-lab -l kubernetes.io/service-name=broken-app -o wide
kubectl get pods -n troubleshoot-lab --show-labels

Латайте селектор сервісу лише після того, як зможете пояснити невідповідність. Потім створіть тимчасовий под-клієнт і протестуйте сервіс через його кластерне DNS-ім’я та порт.

Terminal window
kubectl patch svc broken-app -n troubleshoot-lab --type='merge' -p '{"spec":{"selector":{"app":"broken-app"}}}'
kubectl get endpoints broken-app -n troubleshoot-lab
kubectl run client -n troubleshoot-lab --image=busybox:1.36 --restart=Never -- sleep 3600
kubectl exec -n troubleshoot-lab client -- wget -qO- http://broken-app:8080/

Валідація має повернути відповідь від nginx через сервіс. Якщо вона відмовляє, інспектуйте ендпоїнти, targetPort, готовність подів та статус тимчасового пода-клієнта, перш ніж змінювати щось інше. Пам’ятайте, що досяжність сервісу — це шлях, а не один об’єкт.

  • Доведено, що початковий селектор сервісу не збігався з мітками бекенд-подів.
  • Пропатчено селектор сервісу на app: broken-app.
  • Підтверджено, що сервіс має ендпоїнти після патча.
  • Протестовано трафік через http://broken-app:8080/ зсередини простору імен.

Завдання 5: Діагностуйте под у CrashLoopBackOff

Розділ «Завдання 5: Діагностуйте под у CrashLoopBackOff»

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

Terminal window
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: crash-pod
namespace: troubleshoot-lab
spec:
containers:
- name: app
image: busybox:1.36
command:
- sh
- -c
- echo "booting"; sleep 2; echo "configured failure"; exit 1
EOF

Використовуйте метод по порядку. Спостерігайте статус, інспектуйте describe, прочитайте попередні логи й підтвердьте код виходу. Потім вирішіть, яка зміна змусила б под припинити падати.

Terminal window
kubectl get pod crash-pod -n troubleshoot-lab
kubectl describe pod crash-pod -n troubleshoot-lab
kubectl logs crash-pod -n troubleshoot-lab --previous
kubectl get pod crash-pod -n troubleshoot-lab -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}{"\n"}'

Вам не потрібно ремонтувати цей окремий под, хіба що ви хочете додаткової практики. Важливий результат — пояснити, чому важить --previous і чому збій є поведінкою процесу застосунку, а не плануванням, завантаженням образу чи налаштуванням тому.

  • Підтверджено, що под досяг CrashLoopBackOff.
  • Використано kubectl logs --previous для інспекції завершеного екземпляра контейнера.
  • Отримано останній код виходу через JSONPath.
  • Пояснено, чому збій усередині процесу контейнера після запуску.

Завдання 6: Діагностуйте под у Pending

Розділ «Завдання 6: Діагностуйте под у Pending»

Створіть под, що запитує нереалістичні ресурси. Він має залишитися в Pending, бо планувальник не може знайти придатну ноду. Ваше завдання — довести, що жодних логів застосунку ще не може існувати і що подія планувальника є релевантним доказом.

Terminal window
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: pending-pod
namespace: troubleshoot-lab
spec:
containers:
- name: app
image: nginx:1.27
resources:
requests:
memory: "100Gi"
cpu: "100"
EOF

Інспектуйте докази планувальника та місткість нод. Не намагайтеся виконати exec чи прочитати логи з пода, який не запустився. Збій — це рішення планування, а не помилка застосунку.

Terminal window
kubectl get pod pending-pod -n troubleshoot-lab
kubectl describe pod pending-pod -n troubleshoot-lab
kubectl get nodes
kubectl describe node "$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')" | sed -n '/Allocatable/,/System Info/p'

Хороша відповідь визначає планувальник як компонент, що відмовляє в розміщенні, бо жодна нода не може задовольнити запит ресурсів. Ремонтом було б зниження запитів до реалістичних значень, додавання придатної місткості чи зміна обмежень планування залежно від реальної вимоги навантаження.

  • Підтверджено, що под залишився в Pending.
  • Знайдено подію FailedScheduling.
  • Пояснено, чому логи некорисні для незапланованого пода.
  • Запропоновано ремонт, що усуває запити чи місткість, а не перезапускає под.

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

Terminal window
kubectl delete ns troubleshoot-lab
kubectl delete ns method-demo --ignore-not-found=true

Рефлексія за вправою

Розділ «Рефлексія за вправою»

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

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

Перевірка засвоєного

Розділ «Перевірка засвоєного»

Цей модуль записує кожен виконуваний приклад повною командою kubectl, тому що скопійовані shell-блоки мають працювати в неінтерактивних терміналах, скриптах та екзаменаційних середовищах без опори на локальні аліаси.

Ви оцінюєте под, убитий OOM, перед підвищенням його ліміту пам’яті. Яка команда показує поконтейнерне використання CPU й пам’яті з API метрик і чому ви маєте виконати її після читання kubectl describe pod, а не до нього?


  • training.linuxfoundation.org: certified kubernetes administrator cka — Сторінка CKA від The Linux Foundation явно вказує Troubleshooting на рівні 30% і зазначає, що екзамен — це 2-годинний тест на основі практичних завдань.
  • Pod Lifecycle — Підкріплює фази подів, стани контейнерів, поведінку перезапусків, семантику CrashLoopBackOff, послідовність init-контейнерів, концепції життєвого циклу, пов’язані з готовністю, та загальну лексику усунення несправностей зі станами подів.
  • Debug Services — Підкріплює перевірки рівня сервісу, як-от верифікація існування сервісу, збіг селектора, заповнення EndpointSlice та класичний потік усунення несправностей «сервіс не має ендпоїнтів».
  • Service — Підкріплює типи й поведінку сервісів: ClusterIP, типовий діапазон NodePort, семантику LoadBalancer, ExternalName, headless-сервіси, селектори, виявлення на основі DNS та зв’язок готовності з ендпоїнтами.
  • kubernetes.io: components — Огляд компонентів Kubernetes напряму визначає обов’язки API-сервера, планувальника та контролер-менеджера.
  • Services, Load Balancing, and Networking — Підкріплює мережеву модель Kubernetes: IP подів, очікування міжподової досяжності, абстракції сервісів, залученість EndpointSlice та високорівневу мережеву архітектуру, що використовується в робочих процесах усунення несправностей.
  • Debug Running Pods — Підкріплює використання describe, logs, events, exec та інспекції YAML для діагностики збоїв запуску, планування та виконання подів.
  • kubectl logs — Підкріплює точну поведінку та прапорці kubectl logs, як-от вибір контейнера, режим follow, мітки часу, tail, since, попередні логи та отримання логів усіх контейнерів.
  • Logging Architecture — Підкріплює очікування щодо логування stdout/stderr, розташування файлів логів на ноді, контекст обробки/ротації логів під керуванням kubelet та патерни логування на основі sidecar для застосунків, що записують у файли.
  • kubeadm Implementation Details — Підкріплює розташування площини управління під керуванням kubeadm, особливо шляхи маніфестів статичних подів під /etc/kubernetes/manifests, типові налаштування host networking та поведінку локального статичного пода etcd.
  • DNS for Services and Pods — Підкріплює поведінку DNS кластера, DNS-записи сервісів і подів, запити з кваліфікацією простору імен, результати DNS для headless-сервісів та роль DNS кластера в усуненні несправностей виявлення сервісів.
  • Network Policies — Підкріплює семантику NetworkPolicy, контролі ingress/egress, адитивну поведінку політик, селектори подів/просторів імен/IPBlock та вимогу мережевого плагіна, що забезпечує дотримання NetworkPolicy.
  • Kubernetes API Health Endpoints — Корисно для настанов модуля з тріажу площини управління, особливо /readyz та докладних перевірок справності.

Перейдіть до Модуля 5.2: Збої застосунків, щоб дізнатися, як глибше усувати несправності подів, деплойментів, проб, помилок конфігурації та збоїв рівня застосунку.