Модуль 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-блоки мають працювати в неінтерактивних терміналах, скриптах та екзаменаційних середовищах без опори на локальні аліаси.
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 чи будь-якої команди, що змінює стан, бо такі команди можуть приховати початковий збій.
kubectl get nodes -o widekubectl get pods -A -o widekubectl get events -A --sort-by='.lastTimestamp' | tail -30kubectl -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 чи Secret | kubectl 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, навмисно змініть один бік; не пересоздавайте простір імен. Малі ремонти зменшують ризик, спрощують валідацію та зберігають ланцюг міркувань для перегляду.
kubectl set image deployment/web -n prod app=nginx:1.27kubectl 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.
kubectl rollout status deployment/backend -n prod --timeout=90skubectl get pods -n prod -l app=backend -o widekubectl get endpointslices -n prod -l kubernetes.io/service-name=backendkubectl 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-apiserver | API 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 так само, як у подіях пода.
kubectl describe deployment <name> -n <namespace>kubectl rollout status deployment/<name> -n <namespace> --timeout=90skubectl get rs -n <namespace> -l app=<label> -o widekubectl 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 та цілеспрямоване виправлення. Перевірки ноди та площини управління важливі, але вони мають слідувати за доказами, а не заміняти базову інспекцію робочого навантаження.
3.1 Команди огляду
Розділ «3.1 Команди огляду»Команди огляду відповідають на «що зламано?» та «наскільки воно широке?». Вони мають бути достатньо швидкими, щоб ви могли виконати їх, не втрачаючи темпу. Використовуйте простори імен і мітки, коли ви їх знаєте, але починайте ширше, коли симптом неясний.
kubectl get pods -A -o widekubectl get nodes -o widekubectl 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 щодо нещодавніх збоїв. Він показує події, обрану ноду, томи, стан контейнера, стан останнього завершення, готовність, лічильник перезапусків та повідомлення проб. Логи можуть пояснити запущений процес, але вони не можуть пояснити, чому процес так і не запустився.
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 каже, що контейнер завершився.
kubectl logs <pod-name> -n <namespace>kubectl logs <pod-name> -n <namespace> --previouskubectl logs <pod-name> -n <namespace> -c <container-name>kubectl logs deployment/<deployment-name> -n <namespace> --tail=100Багатоконтейнерні поди вимагають явного вибору контейнера. Sidecar може виглядати справним, тоді як контейнер застосунку падає, тож завжди визначайте імена контейнерів, перш ніж дійти висновку, що логи чисті. Специфікація пода та JSONPath можуть швидко перелічити контейнери.
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 корисний, коли вам потрібне одне точне поле під час екзамену або коли ви хочете уникнути візуального перегляду великого об’єкта.
kubectl get pod <pod-name> -n <namespace> -o yamlkubectl get svc <service-name> -n <namespace> -o yamlkubectl 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 — це короткочасні сигнали, що їх видають контролери та агенти нод. Вони не є повноцінною системою логування, але вони часто є найкращим безпосереднім доказом для збоїв планування, завантаження образу, монтування та проб. Сортуйте їх за міткою часу, коли простір імен має багато об’єктів.
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-ім’я, порт і протокол, які використовує застосунок.
kubectl run netcheck -n <namespace> --image=busybox:1.36 --restart=Never -- sleep 3600kubectl exec -n <namespace> netcheck -- nslookup kubernetes.default.svc.cluster.localkubectl exec -n <namespace> netcheck -- wget -qO- http://<service-name>:<port>/healthzkubectl delete pod netcheck -n <namespace>Якщо образ вашого кластера не містить wget чи nslookup, оберіть налагоджувальний образ, доступний у середовищі. У обмеженому середовищі мінімального налагоджувального образу часто достатньо для DNS та простих HTTP-перевірок. Важлива звичка — узгоджувати джерело й шлях призначення, а не тестувати з місця, яке обходить збій.
3.7 Перевірки ноди та площини управління
Розділ «3.7 Перевірки ноди та площини управління»Перевірки ноди стають доречними, коли докази вказують нижче специфікації пода. Под, застряглий у ContainerCreating з повторюваними помилками середовища виконання, багато подів, що падають на одній ноді, чи нода, позначена NotReady, — усе це виправдовує перехід до доказів рівня ноди. На екзаменаційних кластерах у стилі kubeadm компоненти площини управління часто працюють як статичні поди в kube-system, тоді як kubelet працює як системний сервіс на ноді.
kubectl describe node <node-name>kubectl -n kube-system get pods -o widekubectl -n kube-system logs <control-plane-pod-name> --tail=100ssh <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-проби, неправильний порт, залежність чи повільний старт |
Evicted | Kubelet видалив под через тиск на ноді чи політику | kubectl describe pod та kubectl describe node | Тиск пам’яті, диска, PID, пріоритет чи запити ресурсів |
Unknown | Площина управління не може отримати поточний статус з ноди | kubectl describe node | Kubelet, мережа ноди, середовище виконання чи доступність ноди |
4.2 Розбір прикладу CrashLoopBackOff
Розділ «4.2 Розбір прикладу CrashLoopBackOff»Цей розібраний приклад демонструє повний цикл, перш ніж ви розв’язуватимете схожі збої у вправі. Сценарій простий: под запускається, негайно виходить, і Kubernetes перезапускає його з експоненційним відкатом. Мета — не просто виправити под, а попрактикувати порядок доказів.
Створіть простір імен і навмисно падаючий под. Цей под використовує BusyBox і виходить зі статусом 1, тож збій детермінований і безпечний для відтворення в практичному кластері.
kubectl create ns method-democat <<'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: crash-demo namespace: method-demospec: containers: - name: app image: busybox:1.36 command: - sh - -c - echo "starting demo"; sleep 2; echo "failing now"; exit 1EOFСпостерігайте, не змінюючи под. Перша команда каже вам видимий статус і лічильник перезапусків. Вона ще не доводить, чому контейнер падає.
kubectl get pod crash-demo -n method-demoТепер інспектуйте докази Kubernetes. Розділ Events покаже запуск контейнера та поведінку відкату, а стан контейнера покаже деталі завершення. Це пояснює, що Kubernetes може запустити контейнер, тож збій настає після початку процесу.
kubectl describe pod crash-demo -n method-demoПерейдіть до попередніх логів, бо поточний контейнер міг уже перезапуститися. Прапорець --previous запитує логи останнього завершеного екземпляра, а саме там і живе повідомлення про крах. На швидких кластерах зачекайте кілька секунд після першого перезапуску, перш ніж запускати --previous; kubelet міг ще не скинути буфер логів попереднього екземпляра.
kubectl logs crash-demo -n method-demo --previousВикористайте JSONPath, щоб підтвердити код виходу. Це не завжди потрібно, але корисно, коли треба вибрати між виходом застосунку, завершенням за сигналом та поведінкою OOM. Код виходу 1 тут підтверджує звичайний збій рівня застосунку, а не збій планувальника, образу чи тому.
kubectl get pod crash-demo -n method-demo -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}{"\n"}'Відремонтуйте под, замінивши падаючу команду на довготривалу. У звичайній продакшен-роботі ви редагували б версійовані маніфести чи оновлювали шаблон деплойменту, але окремий практичний под можна замінити напряму.
kubectl delete pod crash-demo -n method-democat <<'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: crash-demo namespace: method-demospec: containers: - name: app image: busybox:1.36 command: - sh - -c - echo "starting demo"; sleep 3600EOFВалідуйте початковий симптом. Под має припинити перезапуски, а логи мають показати старт без повідомлення про збій. Ви валідуєте не теоретичне виправлення; ви перевіряєте, що спостережений стан збою змінився.
kubectl get pod crash-demo -n method-demokubectl logs crash-demo -n method-demoУрок з цього прикладу — у послідовності. describe довів, що контейнер запустився й перезапустився. logs --previous розкрив, що записав завершений процес. JSONPath підтвердив код виходу. Ремонт змінив лише підтверджену падаючу команду. Валідація перевірила той самий об’єкт і симптом, які були зламані спочатку.
4.3 Коди виходу та причини завершення
Розділ «4.3 Коди виходу та причини завершення»Коди виходу компактні, але їх легко переоцінити. Kubernetes записує причину завершення, код виходу, сигнал, а іноді й повідомлення. Ви маєте поєднати код виходу з подіями пода, лімітами ресурсів та логами застосунку, перш ніж вирішувати причину.
| Вихід або причина | Імовірне значення | Підтвердьте через | Типовий напрямок ремонту |
|---|---|---|---|
Код виходу 1 | Застосунок повернув загальну помилку | kubectl logs --previous | Виправте команду, конфігурацію, залежність чи баг застосунку |
Код виходу 126 | Команда знайдена, але не виконувана | Образ контейнера та поле команди | Виправте права файлу чи шлях команди |
Код виходу 127 | Команда не знайдена | Команда в специфікації пода та вміст образу | Використайте правильний бінарник чи образ |
Код виходу 137 | SIGKILL, часто OOMKilled | Last State, ліміти пода, тиск ноди | Скоригуйте пам’ять, виправте витік, налаштуйте запити й ліміти |
Код виходу 143 | SIGTERM, часто плавна зупинка | Події, викочування, виселення, час завершення | Перевірте дію контролера чи поведінку завершення |
Причина OOMKilled | Контейнер перевищив ліміт пам’яті або тиск ноди вбив його | kubectl describe pod та метрики | Збільшуйте ліміт лише після розуміння використання |
Причина Error | Процес вийшов із ненульовим кодом | Логи та конфігурація застосунку | Виправте причину рівня застосунку |
Причина Completed у довготривалому поді | Процес несподівано вийшов із нулем для цього типу навантаження | Команда, аргументи, тип контролера | Використайте правильний контролер чи довготривалу команду |
Поширена помилка — сприймати OOMKilled просто як «збільшити пам’ять». Іноді це правильно, але не завжди. Якщо застосунок раптом використовує вдесятеро більше пам’яті після релізу, підвищення лімітів може приховати регресію. Якщо под не має запиту пам’яті й потрапляє на перевантажену ноду, встановлення відповідних запитів може бути так само важливим, як і зміна ліміту.
4.4 Running не означає Ready
Розділ «4.4 Running не означає Ready»Готовність — це міст між запущеним процесом і трафіком сервісу. Kubernetes може виконувати процес контейнера, виключаючи його з ендпоїнтів сервісу, бо readiness-проба не проходить. Це здорова поведінка: вона запобігає тому, щоб трафік досягав пода, який не готовий обслуговувати.
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. │└──────────────────────────────────────────────────────────────────────────────┘Сервіс без ендпоїнтів зазвичай не є мережевою проблемою. Зазвичай це проблема міток чи готовності. Порівняйте селектор сервісу з мітками подів точно, зокрема імена ключів, значення та простір імен.
kubectl get svc <service-name> -n <namespace> -o yamlkubectl get pods -n <namespace> --show-labelskubectl get endpoints <service-name> -n <namespace>kubectl get endpointslices -n <namespace> -l kubernetes.io/service-name=<service-name> -o wideЯкщо ендпоїнти існують, протестуйте відображення портів. port сервісу — це те, що використовують клієнти. targetPort сервісу — це те, на чому бекенд-поди мають фактично слухати. Іменований targetPort має збігатися з іменованим портом контейнера, що покращує читабельність YAML, але може відмовити, якщо ім’я неправильне.
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
Розділ «Тріаж DNS»Проблеми DNS слід тестувати зсередини кластера. Перше питання — чи може под-клієнт розв’язати ім’я. Друге — чи може він з’єднатися з розв’язаним сервісом. Третє — чи здоровий сам CoreDNS, якщо кілька подів і просторів імен мають збої розв’язання.
kubectl exec -n <namespace> <client-pod> -- nslookup kubernetes.default.svc.cluster.localkubectl exec -n <namespace> <client-pod> -- nslookup <service-name>.<namespace>.svc.cluster.localkubectl -n kube-system get pods -l k8s-app=kube-dns -o widekubectl -n kube-system logs -l k8s-app=kube-dns --tail=100Не плутайте збій DNS зі збоєм HTTP. nslookup доводить лише розв’язання імені. Якщо DNS успішний, але HTTP відмовляє, переходьте до ендпоїнтів сервісу, цільових портів, готовності, конфігурації слухача застосунку та мережевої політики. Якщо DNS відмовляє для кожного імені сервісу з кількох подів, CoreDNS чи конфігурація DNS кластера стає правдоподібнішою.
Тріаж мережевої політики
Розділ «Тріаж мережевої політики»Збої мережевої політики — це передусім проблеми політики й міток, і лише потім проблеми пакетів. Політика обирає поди, потім визначає дозволений вхідний (ingress) чи вихідний (egress) трафік. Якщо под обрано обмежувальною політикою, і жодне правило не дозволяє трафік, трафік заборонено, навіть коли сервіси, ендпоїнти та DNS інакше коректні.
kubectl get networkpolicy -n <namespace>kubectl describe networkpolicy <policy-name> -n <namespace>kubectl get pods -n <namespace> --show-labelskubectl exec -n <namespace> <client-pod> -- wget -qO- http://<service-name>:<port>/Налагоджуючи політику, порівняйте чотири набори міток: селектор подів політики, мітки вихідного пода, мітки вихідного простору імен та мітки пода призначення. Багато збоїв походять від політики, що обирає більше подів, ніж задумано, або від селектора простору імен, який більше не збігається після зміни міток простору імен.
Тріаж сховища
Розділ «Тріаж сховища»Збої сховища часто проявляються як поди, застряглі в Pending чи ContainerCreating, але докази в основі можуть жити в PVC, PV, StorageClass чи подах CSI-драйвера. Под не може запуститися, якщо необхідний йому том не може зв’язатися, підключитися чи змонтуватися. Подія пода зазвичай указує на об’єкт сховища, що потребує глибшої інспекції.
kubectl get pvc -n <namespace>kubectl describe pvc <claim-name> -n <namespace>kubectl get pvkubectl get storageclasskubectl 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/config | kubectl 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, тоді як зламане навантаження живе деінде. Потім виконайте сфокусований огляд, інспектуйте найрелевантніший об’єкт, застосуйте найменше виправлення та валідуйте точно запитаний результат.
kubectl config current-contextkubectl get nskubectl get pods -n <namespace> -o widekubectl 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, де простір імен неочевидний. Шукайте незапущені поди, патерни розміщення на нодах та нещодавні попередження.
kubectl get nodes -o widekubectl get pods -A -o widekubectl get events -A --field-selector type=Warning --sort-by='.lastTimestamp' | tail -20Хороший результат — це не просто «я виконав три команди». Хороший результат — це коротке твердження на кшталт «лише payments має поди, що падають, і обидва падаючі поди на різних нодах, тож далі я інспектуватиму деплоймент і шаблон пода». Це твердження показує, що огляд звузив ваш пошук.
Тренування 2: Тріаж життєвого циклу пода
Розділ «Тренування 2: Тріаж життєвого циклу пода»Це тренування відповідає на питання, де под застряг у своєму життєвому циклі. Використовуйте його для Pending, ContainerCreating, CrashLoopBackOff, збоїв готовності та несподіваних перезапусків. Послідовність рухається від підсумку до подій Kubernetes і до доказів контейнера.
kubectl get pod <pod-name> -n <namespace> -o widekubectl describe pod <pod-name> -n <namespace>kubectl get pod <pod-name> -n <namespace> -o yamlПісля виконання тренування класифікуйте перший етап збою. Якщо под так і не запланувався, не інспектуйте логи. Якщо образ так і не завантажився, ще не налагоджуйте конфігурацію застосунку. Якщо процес запустився й вийшов, тоді логи та коди виходу стають доречними.
Тренування 3: Розслідування краху
Розділ «Тренування 3: Розслідування краху»Це тренування відповідає на питання, чому контейнер перезапустився. Воно поєднує попередні логи зі статусом завершення й уникає поширеної помилки читання лише поточних логів контейнера. Використовуйте його щоразу, коли лічильник перезапусків ненульовий.
kubectl describe pod <pod-name> -n <namespace>kubectl logs <pod-name> -n <namespace> --previouskubectl 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 зламані.
kubectl get svc <service-name> -n <namespace> -o yamlkubectl get endpoints <service-name> -n <namespace>kubectl get endpointslices -n <namespace> -l kubernetes.io/service-name=<service-name> -o widekubectl get pods -n <namespace> --show-labelsЯкщо ендпоїнти порожні, поясніть, чи селектор неправильний, чи поди не готові. Якщо ендпоїнти існують, поясніть, чи порт сервісу відображається на слухача застосунку. Ця відмінність запобігає широким «мережевим» виправленням, які не торкаються справжньої причини.
Тренування 5: DNS та внутрішньокластерне з’єднання
Розділ «Тренування 5: DNS та внутрішньокластерне з’єднання»Це тренування відповідає на питання, чи може клієнт розв’язати й досягти призначення зсередини кластера. Використовуйте вихідний под у тому самому просторі імен і контексті політик, коли можливо. Уникайте тестування лише з ноутбука, бо це обходить внутрішньокластерну маршрутизацію та політику.
kubectl exec -n <namespace> <client-pod> -- nslookup <service-name>.<namespace>.svc.cluster.localkubectl exec -n <namespace> <client-pod> -- wget -qO- http://<service-name>:<port>/healthzkubectl -n kube-system get pods -l k8s-app=kube-dns -o wideІнтерпретуйте результат пошарово. Збій DNS указує на CoreDNS, шлях пошуку чи мережу до DNS. Успіх DNS зі збоєм HTTP указує на ендпоїнти сервісу, цільовий порт, мережеву політику чи слухача застосунку. Успіх HTTP з одного пода, але не з іншого, указує на політику, специфічну для джерела, чи відмінності просторів імен.
Тренування 6: Перевірка справності ноди
Розділ «Тренування 6: Перевірка справності ноди»Це тренування відповідає на питання, чи конкретна нода є першим зламаним рівнем. Використовуйте його, коли багато збоїв скупчуються на одній ноді або коли нода в стані NotReady. Спершу йдуть докази Kubernetes, потім докази сервісів ноди, якщо у вас є доступ до ноди.
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 чекають на сховище. Ця відмінність важлива, бо зв’язування й монтування залучають різні компоненти.
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-и показують, яка ревізія володіє якими подами, а інспекція пода пояснює фактичний збій. Це один із найпоширеніших екзаменаційних та продакшен-патернів.
kubectl rollout status deployment/<deployment-name> -n <namespace> --timeout=60skubectl describe deployment <deployment-name> -n <namespace>kubectl get rs,pods -n <namespace> -l <selector-key>=<selector-value> -o widekubectl 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, щоб інспектувати останній невдалий екземпляр процесу.
Q2: Порожній сервіс
Розділ «Q2: Порожній сервіс»Фронтенд-под може розв’язати 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, готовності, селектора сервісу та ресурсів, бо реальні інциденти рідко приходять як окремі акуратні помилки.
Підготовка
Розділ «Підготовка»Створіть одноразовий простір імен і розгорніть зламане навантаження. Маніфест виконуваний як написано, але містить кілька навмисних помилок, які ви маєте виявити за допомогою доказів, а не візуальним переглядом спершу.
kubectl create ns troubleshoot-labcat <<'EOF' | kubectl apply -f -apiVersion: apps/v1kind: Deploymentmetadata: name: broken-app namespace: troubleshoot-labspec: 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: v1kind: Servicemetadata: name: broken-app namespace: troubleshoot-labspec: selector: app: broken-api ports: - name: http port: 8080 targetPort: httpEOFЗавдання 1: Спостерігайте поточний стан
Розділ «Завдання 1: Спостерігайте поточний стан»Почніть широко й поки що нічого не виправляйте. Зафіксуйте, які об’єкти існують, які поди падають і які події найновіші. Запишіть одне речення, що описує перший видимий симптом, перш ніж заглиблюватися.
kubectl get deploy,rs,pods,svc,endpoints -n troubleshoot-lab -o widekubectl get events -n troubleshoot-lab --sort-by='.lastTimestamp'Критерії успіху для цього завдання базуються на доказах. Ви маєте змогти сказати, чи деплоймент створив поди, чи поди досягли Running і чи сервіс має ендпоїнти. Якщо ви не можете сформулювати ці три речі, ви спостерігали недостатньо.
- Підтверджено, чи поди були створені деплойментом.
- Підтверджено, чи поди досягли
RunningтаReady. - Підтверджено, чи сервіс має ендпоїнти.
- Визначено найновіші попереджувальні події, не змінюючи жодного об’єкта.
Завдання 2: Ізолюйте перший зламаний рівень
Розділ «Завдання 2: Ізолюйте перший зламаний рівень»Інспектуйте один зламаний под через describe. Не стрибайте до логів, доки не дізнаєтеся, чи запустився контейнер. Використайте розділ Events, щоб вирішити, чи перший зламаний рівень — це планувальник, завантаження образу, монтування тому, процес контейнера, готовність чи вибір сервісу.
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. Використовуйте команди, що прямо усувають підтверджені причини. Потім стежте за викочуванням достатньо довго, щоб побачити наступний рівень збою, бо виправлення блокерів запуску може розкрити проблеми готовності чи сервісу.
kubectl set image deployment/broken-app -n troubleshoot-lab app=nginx:1.27kubectl 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=90skubectl get pods -n troubleshoot-lab -l app=broken-appЯкщо викочування все ще не завершується, інспектуйте найновіший под знову. Не припускайте, що перший ремонт виправив усе. Усунення несправностей у Kubernetes часто розкриває один блокер за раз, бо пізніші етапи життєвого циклу не можуть відмовити, доки не вдадуться раніші етапи.
- Виправлено посилання на образ на валідний тег образу nginx.
- Створено відсутній ConfigMap у тому самому просторі імен, що й под.
- Повторно виконано
describeчи статус викочування після кожного ремонту. - Підтверджено, що поди деплойменту в стані
Runningі готові, перш ніж переходити до валідації сервісу.
Завдання 4: Валідуйте шлях сервісу
Розділ «Завдання 4: Валідуйте шлях сервісу»Тепер протестуйте вимогу, яка хвилювала б користувача: трафік через сервіс. Об’єкт сервісу існує, але селектор навмисно неправильний. Використайте ендпоїнти й мітки, щоб довести причину, перш ніж її латати.
kubectl get svc broken-app -n troubleshoot-lab -o yamlkubectl get endpoints broken-app -n troubleshoot-labkubectl get endpointslices -n troubleshoot-lab -l kubernetes.io/service-name=broken-app -o widekubectl get pods -n troubleshoot-lab --show-labelsЛатайте селектор сервісу лише після того, як зможете пояснити невідповідність. Потім створіть тимчасовий под-клієнт і протестуйте сервіс через його кластерне DNS-ім’я та порт.
kubectl patch svc broken-app -n troubleshoot-lab --type='merge' -p '{"spec":{"selector":{"app":"broken-app"}}}'kubectl get endpoints broken-app -n troubleshoot-labkubectl run client -n troubleshoot-lab --image=busybox:1.36 --restart=Never -- sleep 3600kubectl exec -n troubleshoot-lab client -- wget -qO- http://broken-app:8080/Валідація має повернути відповідь від nginx через сервіс. Якщо вона відмовляє, інспектуйте ендпоїнти, targetPort, готовність подів та статус тимчасового пода-клієнта, перш ніж змінювати щось інше. Пам’ятайте, що досяжність сервісу — це шлях, а не один об’єкт.
- Доведено, що початковий селектор сервісу не збігався з мітками бекенд-подів.
- Пропатчено селектор сервісу на
app: broken-app. - Підтверджено, що сервіс має ендпоїнти після патча.
- Протестовано трафік через
http://broken-app:8080/зсередини простору імен.
Завдання 5: Діагностуйте под у CrashLoopBackOff
Розділ «Завдання 5: Діагностуйте под у CrashLoopBackOff»Створіть окремий падаючий под і застосуйте послідовність розібраного прикладу, не озираючись на розв’язок. Цей под запускається, виводить дані й виходить із ненульовим кодом. Ваша мета — зафіксувати попередні логи й деталі завершення перед ремонтом.
cat <<'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: crash-pod namespace: troubleshoot-labspec: containers: - name: app image: busybox:1.36 command: - sh - -c - echo "booting"; sleep 2; echo "configured failure"; exit 1EOFВикористовуйте метод по порядку. Спостерігайте статус, інспектуйте describe, прочитайте попередні логи й підтвердьте код виходу. Потім вирішіть, яка зміна змусила б под припинити падати.
kubectl get pod crash-pod -n troubleshoot-labkubectl describe pod crash-pod -n troubleshoot-labkubectl logs crash-pod -n troubleshoot-lab --previouskubectl 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, бо планувальник не може знайти придатну ноду. Ваше завдання — довести, що жодних логів застосунку ще не може існувати і що подія планувальника є релевантним доказом.
cat <<'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: pending-pod namespace: troubleshoot-labspec: containers: - name: app image: nginx:1.27 resources: requests: memory: "100Gi" cpu: "100"EOFІнспектуйте докази планувальника та місткість нод. Не намагайтеся виконати exec чи прочитати логи з пода, який не запустився. Збій — це рішення планування, а не помилка застосунку.
kubectl get pod pending-pod -n troubleshoot-labkubectl describe pod pending-pod -n troubleshoot-labkubectl get nodeskubectl describe node "$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')" | sed -n '/Allocatable/,/System Info/p'Хороша відповідь визначає планувальник як компонент, що відмовляє в розміщенні, бо жодна нода не може задовольнити запит ресурсів. Ремонтом було б зниження запитів до реалістичних значень, додавання придатної місткості чи зміна обмежень планування залежно від реальної вимоги навантаження.
- Підтверджено, що под залишився в
Pending. - Знайдено подію
FailedScheduling. - Пояснено, чому логи некорисні для незапланованого пода.
- Запропоновано ремонт, що усуває запити чи місткість, а не перезапускає под.
Прибирання
Розділ «Прибирання»Видаліть практичний простір імен після завершення вправи. Це видаляє всі зламані ресурси й тимчасові поди, створені під час лабораторної роботи.
kubectl delete ns troubleshoot-labkubectl 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: Збої застосунків, щоб дізнатися, як глибше усувати несправності подів, деплойментів, проб, помилок конфігурації та збоїв рівня застосунку.