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

Частина 5: Усунення несправностей — підсумковий тест

Lab Progress 0/7 completed

Складність: [СКЛАДНИЙ]

Час на проходження: 75–90 хвилин

Передумови: модулі Частини 5 про методологію усунення несправностей, збої застосунків, збої площини управління, збої робочих вузлів, мережу, сервіси, логування та моніторинг.

Вага на іспиті: усунення несправностей становить 30% покриття домену іспиту CKA.

Цільовий кластер: Kubernetes 1.35+

Примітка щодо команд: цей модуль після перших прикладів команд використовує k як скорочення для kubectl. У командній оболонці на іспиті задайте його через alias k=kubectl.


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

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

Після завершення цього підсумкового модуля з усунення несправностей ви зможете:

  1. Діагностувати робочі навантаження Kubernetes, що збоять, рухаючись від симптомів до доказів, використовуючи Events, поля статусу, логи, стан розгортання та дані про ресурси, а не вгадуючи.
  2. Аналізувати збої площини управління та робочих вузлів, розділяючи доступність API, стан статичних Pod’ів, поведінку kubelet, стан середовища виконання контейнерів, сертифікати та умови тиску на нодах.
  3. Оцінювати інциденти із сервісами та мережею, простежуючи трафік від клієнта до Сервісу, EndpointSlice, готовності Pod’а, порту контейнера, kube-proxy, DNS та поведінки CNI.
  4. Проєктувати обмежений у часі план усунення несправностей для сценаріїв у стилі CKA, який віддає пріоритет оборотним виправленням, зберігає докази та уникає зайвих порушень.
  5. Порівнювати схожі сигнатури збоїв, як-от Pending, ContainerCreating, CrashLoopBackOff, ImagePullBackOff, порожні endpoint’и та NotReady, щоб упевнено обрати наступну команду.

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

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

О 02:13 черговому інженеру надходить виклик, бо запити на оформлення замовлень почали збоїти у двох регіонах. Команда застосунку каже, що їхній Деплоймент “виглядає нормально”, бо бажана кількість реплік усе ще дорівнює шести; платформна команда каже, що кластер “виглядає нормально”, бо більшість нод у стані Ready; а керівник інциденту хоче знати, чи варто відкочуватися, спорожняти ноди, чи відводити трафік від кластера. У цей момент той, хто усуває несправності, але пам’ятає лише команди, стає повільним. Той, хто розуміє шляхи збоїв, здатен перетворити розмиті симптоми на вузьку гіпотезу, яку можна перевірити.

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

Цей підсумковий модуль написано як завершальний (capstone) для Частини 5. Він повторює основні домени усунення несправностей, але робить це, навчаючи того, як ці домени пов’язані між собою. CrashLoopBackOff може бути помилкою застосунку, поганим ConfigMap, OOM-вбивством або пробою, яка надто агресивно вбиває здоровий процес. Збій Сервісу може бути спричинений DNS, мітками, готовністю, портами, kube-proxy, фаєрволом на ноді чи CNI. Збій площини управління може виглядати як “kubectl зламався”, навіть коли справжня причина — друкарська помилка в маніфесті статичного Pod’а або прострочений сертифікат.

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


1. Усунення несправностей керується доказами, а не командами

Розділ «1. Усунення несправностей керується доказами, а не командами»

Інцидент Kubernetes легше діагностувати, коли ви розглядаєте кожну команду як запитання, яке ставите системі. kubectl get pods запитує, чи існує бажане робоче навантаження і який високорівневий стан повідомляє Kubernetes. kubectl describe pod запитує, що площина управління та kubelet нещодавно намагалися зробити. kubectl logs запитує, що сказав процес усередині контейнера до або під час збою. Ці команди перетинаються, але відповідають не на те саме запитання.

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

+----------------------+ +----------------------+ +----------------------+
| 1. Define Symptom | --> | 2. Locate Layer | --> | 3. Collect Evidence |
| Who is affected? | | App, node, network, | | Events, logs, |
| What changed? | | control plane, DNS | | status, metrics |
+----------------------+ +----------------------+ +----------------------+
| |
v v
+----------------------+ +----------------------+ +----------------------+
| 6. Document Result | <-- | 5. Verify Behavior | <-- | 4. Apply Safe Fix |
| What proved fixed? | | User-visible check | | Small, reversible, |
| What evidence stays?| | plus object status | | scoped to cause |
+----------------------+ +----------------------+ +----------------------+

Перше корисне запитання — не “яку команду запустити?”, а “який рівень міг породити цей симптом?”. Користувач, що каже “застосунок не працює”, може мати на увазі, що Pod так і не запустився, що селектор Сервісу неправильний, що DNS не може розв’язати ім’я, що застосунок повертає HTTP 500 або що трафік не може перетнути ноди. Кожен рівень має швидший тест, ніж огляд кожного ресурсу у просторі імен. Ви звужуєте поле, перевіряючи спочатку найцентральніший об’єкт, а потім рухаючись назовні ланцюжком залежностей.

Для інцидентів із робочими навантаженнями починайте з контролера та Pod’а, бо вони пов’язують бажаний стан із фактичним виконанням. Деплоймент може показувати три бажані репліки, але лише Pod’и розкривають, чи збоять планування, завантаження образів, монтування томів, проби або завершення процесів. Для інцидентів із сервісами починайте зі стану Сервісу та endpoint’ів, бо Сервіс без endpoint’ів не може маршрутизувати трафік, хоч би яким здоровим виглядав DNS. Для інцидентів із нодами починайте з умов ноди та kubelet, бо kubelet — це міст між API-сервером і локальним виконанням контейнерів.

Завдання для активного навчання: передбачте, перш ніж оглядати

Ваш колега каже, що Деплоймент має READY 0/3, а k get pods показує, що всі три Pod’и у стані Pending. Перш ніж запускати ще одну команду, передбачте, яке джерело доказів найімовірніше пояснить причину: логи контейнера, Events Pod’а, endpoint’и Сервісу чи логи CoreDNS. Потім поясніть, чому інші три — слабші перші перевірки для Pod’а у стані Pending.

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

Terminal window
kubectl get pods -o wide

Після цього використовуйте псевдонім:

Terminal window
alias k=kubectl
k describe pod <pod-name>

-o wide дає вам розміщення на ноді, IP-адреси Pod’ів і готовність одним поглядом. describe дає Events, які часто є найшвидшим шляхом до причин на кшталт невдалого планування, помилок завантаження образів, відсутніх ConfigMap, відсутніх Secret’ів, збоїв монтування томів, невдалих проб і тиску на ноді. Логи потужні, але це докази рівня застосунку; Events — це докази оркестрації Kubernetes. Pod, який ніколи не запускався, зазвичай не матиме корисних логів застосунку.

Практичний цикл усунення несправностей CKA виглядає так:

Terminal window
k get deploy,rs,pods -o wide
k describe pod <pod-name>
k logs <pod-name> --previous
k get events --sort-by=.lastTimestamp
k get pod <pod-name> -o yaml

Не запускайте все це щоразу. Використовуйте їх як послідовність лише тоді, коли попередня команда не відповідає на запитання. Якщо Events кажуть FailedScheduling, бо Pod запитує більше CPU, ніж може надати будь-яка нода, логи не допоможуть. Якщо Events показують, що контейнер запускається, а потім завершується, кращим джерелом стають логи. Якщо логи показують, що застосунок не може прочитати файл, змонтований із ConfigMap, релевантними стають специфікація Pod’а та конфігурація змонтованого тому.

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


2. Збої робочих навантажень: від стану Pod’а до кореневої причини

Розділ «2. Збої робочих навантажень: від стану Pod’а до кореневої причини»

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

+----------------+ +-------------------+ +----------------------+ +------------------+
| Pod Accepted | --> | Scheduled To Node | --> | Image And Volumes | --> | Container Runs |
| API object | | scheduler | | kubelet + runtime | | process + probes |
+----------------+ +-------------------+ +----------------------+ +------------------+
| | | |
v v v v
YAML invalid? Pending forever? ContainerCreating? CrashLoopBackOff?
admission denied? taints/resources? ConfigMap/Secret/CNI? logs/probes/OOM?

Pending зазвичай означає, що планування не завершилося. Найшвидші докази — розділ Events у k describe pod. Поширені причини: недостатньо CPU чи пам’яті, неприпустимі taint’и, селектори нод, що не відповідають жодній ноді, надто строга обов’язкова спорідненість до нод (node affinity), PVC, що не можуть зв’язатися, або недоступний планувальник. Логи не корисні, бо контейнер ще не запускався.

ContainerCreating означає, що Pod заплановано, але kubelet не завершив локальне налаштування. Це часто вказує на підготовку образу, монтування томів, відсутні ConfigMap чи Secret’и, налаштування CNI або проблеми середовища виконання контейнерів. І знову Events зазвичай перемагають логи. Якщо Events кажуть MountVolume.SetUp failed через відсутній Secret, виправлення — не перезапуск Деплойменту. Виправлення — створити чи виправити Secret, на який є посилання, або оновити шаблон Pod’а, щоб використовувати правильне ім’я.

ImagePullBackOff означає, що kubelet не може отримати образ, а backoff — це лише уповільнення Kubernetes повторних спроб. Причиною може бути неправильний репозиторій, неправильний тег, відсутні облікові дані реєстру, неавторизований доступ до приватного реєстру, збій DNS до реєстру, обмеження частоти реєстром або блокування мережевого вихідного трафіку. Ключові докази — рядок образу та повідомлення Events, а не логи застосунку.

CrashLoopBackOff означає, що процес контейнера запускається, завершується та перезапускається згідно з політикою перезапуску Pod’а. Застосунок таки запустився, тож k logs --previous часто є найкориснішою командою. Причини: некоректні аргументи команди, відсутня конфігурація середовища виконання, збої залежностей на рівні застосунку, невдалі startup-проби, невдалі liveness-проби, помилки прав доступу та ліміти пам’яті, що спричиняють OOMKilled.

Приклад з розбором: діагностування CrashLoopBackOff без вгадування

Розділ «Приклад з розбором: діагностування CrashLoopBackOff без вгадування»

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

Terminal window
k get deploy,pods -l app=orders-api

Приклад виводу:

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/orders-api 0/3 3 0 6m
NAME READY STATUS RESTARTS AGE
pod/orders-api-6b6f8f7b8d-2bq9m 0/1 CrashLoopBackOff 5 6m
pod/orders-api-6b6f8f7b8d-hw6kn 0/1 CrashLoopBackOff 5 6m
pod/orders-api-6b6f8f7b8d-tm8xs 0/1 CrashLoopBackOff 5 6m

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

Terminal window
k describe pod orders-api-6b6f8f7b8d-2bq9m

Приклад доказів:

Last State: Terminated
Reason: OOMKilled
Exit Code: 137
Restart Count: 5

Код виходу 137 зазвичай асоціюється з SIGKILL, а повідомлення Kubernetes OOMKilled підтверджує тиск на пам’ять на рівні ліміту контейнера. Наступне запитання: чи не є налаштований ліміт нереалістично низьким для цього застосунку. Ви оглядаєте шаблон Pod’а через Деплоймент, бо редагування окремого Pod’а було б тимчасовим, і контролер відтворив би його.

Terminal window
k get deployment orders-api -o jsonpath='{.spec.template.spec.containers[0].resources}{"\n"}'

Приклад виводу:

{"limits":{"memory":"64Mi"},"requests":{"cpu":"100m","memory":"64Mi"}}

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

Terminal window
k set resources deployment/orders-api \
--containers=orders-api \
--requests=cpu=100m,memory=128Mi \
--limits=memory=256Mi

Тепер перевірте, що Kubernetes створює нові Pod’и і що вони залишаються запущеними.

Terminal window
k rollout status deployment/orders-api
k get pods -l app=orders-api

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

Завдання для активного навчання: оберіть наступну команду

Ви бачите CrashLoopBackOff, але k describe pod показує Last State: Terminated, Reason: Error, Exit Code: 1, а не OOMKilled. Яку команду слід запустити наступною і який вид доказів змусив би вас змінити Деплоймент проти того, щоб відкотити образ?

Інший CrashLoopBackOff може вказувати на конфігурацію застосунку. Наступною командою були б попередні логи:

Terminal window
k logs <pod-name> --previous

Якщо лог каже missing environment variable DATABASE_URL, огляньте середовище Деплойменту та ConfigMap чи Secret’и, на які є посилання:

Terminal window
k get deployment <deployment-name> -o yaml
k get configmap
k get secret

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

Матриця рішень для поширених станів робочих навантажень

Розділ «Матриця рішень для поширених станів робочих навантажень»
СимптомНайкорисніші перші доказиІмовірний рівеньДоброю наступною дією є
Pod у стані PendingEvents у k describe podПланувальник, зв’язування PVC, taint’и, ресурсиВиправити requests, toleration’и, селектори, спорідненість або зв’язування сховища
Pod у стані ContainerCreatingEvents у k describe podНалаштування kubelet, монтування тому, CNI, середовище виконанняВиправити відсутній ConfigMap чи Secret, том, CNI або проблему середовища виконання
Pod у стані ImagePullBackOffEvents у k describe pod та поле образуРеєстр, ім’я образу, облікові дані, мережаВиправити образ, тег, imagePullSecrets або доступ до реєстру
Pod у стані CrashLoopBackOffk logs --previous та стан останнього завершенняПроцес, конфігурація, проби, пам’ятьВиправити конфігурацію, команду, ресурси, проби або відкотити поганий образ
Деплоймент застряг на розгортанніk rollout status та Pod’и нового ReplicaSetРевізія нового шаблонуВиправити причину нового Pod’а або k rollout undo, коли відкат найбезпечніший
Сервіс не має endpoint’івk get endpointslice та готовність Pod’аМітки або готовністьВиправити селектор, мітки, readiness-пробу або справність контейнера

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

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

Використовуйте цю послідовність відкату, коли доступність важливіша за збереження нової ревізії:

Terminal window
k rollout history deployment/<deployment-name>
k rollout undo deployment/<deployment-name>
k rollout status deployment/<deployment-name>

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

Terminal window
k edit deployment/<deployment-name>
k rollout status deployment/<deployment-name>
k get pods -l app=<label-value>

У сценаріях CKA віддавайте перевагу прямим, вузьким змінам, які можна перевірити. Якщо Pod посилається на configmap app-config, а Events кажуть, що цей ConfigMap відсутній, створення цього ConfigMap або виправлення посилання — це вузьке виправлення. Відтворення Деплойменту з нуля — широке, ризиковане та зазвичай зайве.


3. Збої площини управління та нод: розділяйте API, kubelet, середовище виконання та хост

Розділ «3. Збої площини управління та нод: розділяйте API, kubelet, середовище виконання та хост»

Усунення несправностей кластера ускладнюється, коли сам kubectl стає ненадійним. Якщо API-сервер недоступний, звичайні команди Kubernetes не можуть сказати вам, чи відповідальні API-сервер, etcd, сертифікати, мережа чи kubelet. У цей момент ви переходите від API Kubernetes до хоста та середовища виконання контейнерів на ноді площини управління.

У кластерах у стилі kubeadm ключові компоненти площини управління зазвичай працюють як статичні Pod’и. Маніфести статичних Pod’ів лежать на диску, і kubelet спостерігає за цими файлами. Коли маніфест змінюється, kubelet відтворює відповідний статичний Pod. Це означає, що поганий прапорець, неправильний шлях до сертифіката, некоректне поле YAML або переміщений маніфест можуть зламати компонент площини управління, навіть коли решта ноди справна.

+--------------------------- Control Plane Node ---------------------------+
| |
| +-------------------+ watches +-----------------------+ |
| | kubelet | ---------------------> | /etc/kubernetes/ | |
| | systemd service | | manifests/*.yaml | |
| +-------------------+ +-----------------------+ |
| | | |
| | creates static Pods | |
| v v |
| +-------------------+ +-------------------+ +-------------------+ |
| | kube-apiserver | | scheduler | | controller-manager | |
| | listens on 6443 | | assigns Pods | | reconciles objects | |
| +-------------------+ +-------------------+ +-------------------+ |
| | |
| v |
| +-------------------+ |
| | etcd | |
| | cluster state | |
| +-------------------+ |
+-------------------------------------------------------------------------+

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

Корисна послідовність на рівні хоста:

Terminal window
sudo systemctl status kubelet
sudo journalctl -u kubelet -n 80 --no-pager
sudo crictl ps -a | grep kube-apiserver
sudo crictl logs <api-server-container-id>
sudo ls -l /etc/kubernetes/manifests/

Ці команди не взаємозамінні з kubectl. crictl спілкується із середовищем виконання контейнерів через Container Runtime Interface, тож залишається корисним, коли API-сервер не працює. journalctl читає логи systemd, тож може показувати помилки kubelet ще до того, як з’являться статичні Pod’и. Каталог маніфестів показує бажані визначення статичних Pod’ів, які kubelet намагається запустити.

Для перевірки справності etcd у кластері kubeadm використовуйте etcdctl із правильними сертифікатами. Точні імена файлів сертифікатів можуть відрізнятися залежно від налаштування, але кластери kubeadm зазвичай використовують каталог PKI для etcd, показаний нижче.

Terminal window
sudo ETCDCTL_API=3 etcdctl endpoint health \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key

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

Збої сертифікатів часто виглядають як помилки автентифікації чи з’єднання, а не як очевидні повідомлення про закінчення терміну дії. kubeadm certs check-expiration — це швидка перевірка в кластерах, керованих kubeadm:

Terminal window
sudo kubeadm certs check-expiration

Якщо сертифікати прострочені у тренувальному кластері, команда оновлення:

Terminal window
sudo kubeadm certs renew all
sudo systemctl restart kubelet

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

Збої робочих вузлів мають схожу багаторівневу модель. Нода стає NotReady, коли площина управління перестає отримувати справний статус kubelet. Причиною може бути зупинений kubelet, зупинене середовище виконання контейнерів, поламаний мережевий шлях до API-сервера, тиск на диск, тиск на пам’ять, тиск на PID, проблеми із сертифікатами або проблеми CNI. NotReady каже вам, що площина управління бачить проблему ноди; вона не каже, який компонент хоста збоїв.

+------------------------------- Worker Node ------------------------------+
| |
| +-------------------+ CRI calls +------------------------+ |
| | kubelet | --------------------> | containerd or runtime | |
| | reports Node | | starts containers | |
| +-------------------+ +------------------------+ |
| | |
| | CNI calls |
| v |
| +-------------------+ traffic +------------------------+ |
| | CNI plugin | --------------------> | Pod network namespace | |
| | routes Pods | | app container ports | |
| +-------------------+ +------------------------+ |
| | |
| v |
| +-------------------+ |
| | host resources | disk, memory, PIDs, kernel, certificates |
| +-------------------+ |
+--------------------------------------------------------------------------+

Починайте з огляду через API, якщо API доступний:

Terminal window
k get nodes -o wide
k describe node <node-name>

Потім переходьте до ноди, коли потрібні докази, локальні для ноди:

Terminal window
ssh <node-name>
sudo systemctl status kubelet
sudo journalctl -u kubelet -n 80 --no-pager
sudo systemctl status containerd
sudo crictl ps
df -h
free -m

Умови тиску на ноді впливають на планування та витіснення. MemoryPressure=True може блокувати планування нових Pod’ів на ноду та спричиняти витіснення Pod’ів нижчого класу якості обслуговування. DiskPressure=True може заважати kubelet створювати більше контейнерів чи писати логи. Нода може бути досяжною і все одно непридатною для нових робочих навантажень, бо тиск на ресурси робить її небезпечною.

Безпечна реакція на обслуговування — застосувати cordon перед drain, коли потрібно зупинити надходження нових робочих навантажень і навмисно витіснити наявні:

Terminal window
k cordon <node-name>
k drain <node-name> --ignore-daemonsets --delete-emptydir-data

Після обслуговування поверніть ноду до планування:

Terminal window
k uncordon <node-name>

Не спорожняйте ноду як першу реакцію на кожен стан NotReady. Спорожнення вимагає, щоб працювали API-сервер і шлях витіснення, і воно може порушити роботу навантажень зі строгими PodDisruptionBudget. Спершу визначте, чи можна відновити ноду, перезапустивши kubelet або containerd, звільнивши диск, виправивши мережевий доступ чи виправивши сертифікати. Спорожнення — це дія з обслуговування, а не діагностичний скорочений шлях.

Завдання для активного навчання: діагностуйте рівень

Нода у стані NotReady, і нові Pod’и не можуть на ній плануватися. ssh працює, containerd активний, але journalctl -u kubelet неодноразово показує збої з’єднання з https://control-plane:6443. Вирішіть, що ви оглянете наступним: CNI-Pod’и, логи контейнера, досяжність API-сервера чи селектори Сервісу. Поясніть свій вибір у термінах шляху залежностей.


4. Усунення несправностей Сервісів, DNS та мережі: простежте за пакетом

Розділ «4. Усунення несправностей Сервісів, DNS та мережі: простежте за пакетом»

Інциденти із Сервісами заплутані, бо Kubernetes ховає кілька рухомих частин за одним стабільним іменем. Клієнт може звертатися до http://checkout.default.svc.cluster.local, але шлях запиту включає розв’язання DNS, обробку віртуального IP Сервісу, правила kube-proxy чи еквівалентну поведінку площини даних, членство в EndpointSlice, готовність Pod’а, порти контейнера та мережеву політику. Збій на будь-якому рівні може виглядати як “Сервіс не працює”.

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

+-------------+ DNS +-------------+ VIP +----------------+
| client Pod | ---------------> | CoreDNS | ---------------> | Service |
| curl name | | kube-dns | | ClusterIP:port |
+-------------+ +-------------+ +----------------+
| |
| connection after name resolves |
v v
+-------------+ dataplane +----------------+ ready Pods +-------------+
| node rules | -----------------> | EndpointSlice | ---------------> | Pod IP |
| kube-proxy | | addresses | | targetPort |
+-------------+ +----------------+ +-------------+

Компактна послідовність для діагностики Сервісу:

Terminal window
k get svc <service-name> -o wide
k get endpointslice -l kubernetes.io/service-name=<service-name>
k get pods --show-labels
k describe svc <service-name>

Якщо EndpointSlice не має адрес, перевірте селектор і мітки Pod’а. Селектор Сервісу має точно відповідати міткам Pod’а. Часто буває, що Деплоймент використовує app: checkout-api, тоді як Сервіс вибирає app: checkout. Kubernetes охоче створить Сервіс, але Сервіс не матиме endpoint’ів, бо жоден готовий Pod не відповідає.

Terminal window
k get svc checkout -o jsonpath='{.spec.selector}{"\n"}'
k get pods -l app=checkout --show-labels
k get pods -l app=checkout-api --show-labels

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

Terminal window
k get pods -l app=checkout -o wide
k describe pod <pod-name>
k logs <pod-name>

Невідповідність портів — ще один поширений збій Сервісу. У Сервісі port — це порт, який клієнти використовують на Сервісі, тоді як targetPort — це порт на Pod’і. Якщо Сервіс має port: 80 і targetPort: 8080, але контейнер слухає на 80, трафік буде переспрямовано на порт, де ніщо не слухає. Об’єкт Сервісу може виглядати нормально, endpoint’и можуть існувати, а DNS може розв’язувати, проте застосунок залишається недосяжним.

apiVersion: v1
kind: Service
metadata:
name: checkout
spec:
selector:
app: checkout
ports:
- port: 80
targetPort: 8080

Виправлення — узгодити targetPort Сервісу з фактичним портом прослуховування контейнера або змінити контейнер, щоб він слухав на очікуваному цільовому порту. У сценаріях іспиту огляньте специфікацію Pod’а та документацію застосунку в запитанні. Не припускайте, що port і targetPort мають завжди збігатися; вони можуть навмисно відрізнятися, коли Сервіс розкриває звичний порт, а застосунок слухає деінде.

Усунення несправностей DNS починається всередині Pod’а, бо поведінка DNS кластера залежить від конфігурації розв’язувача імен (resolver) Pod’а та мережевого шляху до CoreDNS. Використовуйте тимчасовий Pod або наявний Pod застосунку, коли це дозволено:

Terminal window
k run dns-test --image=busybox:1.36 --restart=Never -- sleep 3600
k exec dns-test -- nslookup kubernetes.default.svc.cluster.local
k exec dns-test -- cat /etc/resolv.conf

Якщо кожне ім’я Сервісу збоїть, огляньте CoreDNS і Сервіс kube-dns:

Terminal window
k -n kube-system get pods -l k8s-app=kube-dns -o wide
k -n kube-system logs -l k8s-app=kube-dns
k -n kube-system get svc kube-dns
k -n kube-system get endpointslice -l kubernetes.io/service-name=kube-dns

Якщо збоїть лише одне ім’я Сервісу, DNS навряд чи є кореневою причиною. Сервіс може не існувати, простір імен може бути неправильним, або клієнт може використовувати неправильне коротке ім’я. Pod у просторі імен frontend, що розв’язує checkout, шукатиме checkout.frontend.svc.cluster.local перед іншими іменами. Якщо Сервіс розташований у просторі імен payments, клієнт має використовувати checkout.payments або повністю кваліфіковане ім’я.

Збої NetworkPolicy вимагають іншої звички: перевірте, чи політика вибирає уражені Pod’и та чи дозволяє вона напрямок, який ви тестуєте. Політика, яка вибирає Pod’и та має ingress-правила, робить вхідний трафік обмеженим для цих Pod’ів. Вихідний трафік залишається необмеженим, доки ізоляцію egress не створено типом політики та правилами. Якщо обмежено і вхідний, і вихідний трафік, ви маєте дозволити DNS, а також трафік застосунку, коли Pod’и потребують розв’язання імен.

Terminal window
k get networkpolicy
k describe networkpolicy <policy-name>
k get pod <pod-name> --show-labels

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

Terminal window
k -n kube-system get pods -o wide
k -n kube-system logs <cni-pod-name>

Ключове — простежити за пакетом, а не випадково ганятися за компонентами. Якщо ім’я не розв’язується, працюйте над DNS. Якщо ім’я розв’язується, а Сервіс не має endpoint’ів, працюйте над мітками та готовністю. Якщо endpoint’и існують, але з’єднання збоять, працюйте над портами, NetworkPolicy, площиною даних і CNI. Кожен крок виключає кілька можливих причин.


5. Логування, Events, метрики та час: використовуйте правильний сигнал для часового вікна

Розділ «5. Логування, Events, метрики та час: використовуйте правильний сигнал для часового вікна»

Kubernetes дає вам кілька сигналів спостережуваності, але кожен сигнал має інший часовий горизонт і рівень збою. Events чудові для нещодавніх рішень оркестрації. Логи контейнера чудові для збоїв на рівні процесу. Попередні логи незамінні для перезапущених контейнерів. Метрики корисні для трендів ресурсів, але kubectl top залежить від Metrics Server і не замінює статус та Events під час першої реакції.

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

Terminal window
k get events --sort-by=.lastTimestamp
k describe pod <pod-name>

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

Terminal window
k logs <pod-name> --previous

Для багатоконтейнерних Pod’ів завжди вказуйте контейнер, коли потрібно:

Terminal window
k logs <pod-name> -c <container-name> --previous

Metrics Server живить kubectl top, але відсутність метрик не означає автоматично, що навантаження справні чи несправні. Вона означає, що конвеєр метрик недоступний для цієї команди. Перевірте, чи Metrics Server існує і чи готовий він, перш ніж припускати, що огляд ресурсів є осмисленим:

Terminal window
k top pods
k -n kube-system get pods | grep metrics-server

Коли Metrics Server недоступний у кластері, де вам дозволено його встановлювати, часто використовують стандартний маніфест. У заблокованому екзаменаційному чи продакшен-середовищі не встановлюйте компоненти, якщо задача явно цього не дозволяє. Спершу перевірте очікувану політику кластера.

Terminal window
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

Локальні для ноди логи мають значення, коли докази з API Kubernetes неповні. Логи контейнерів зазвичай доступні через шляхи в /var/log/containers/, тоді як логи kubelet доступні через systemd на багатьох нодах Linux. Використовуйте їх, коли kubectl logs недостатньо або коли API-сервер недоступний.

Terminal window
sudo journalctl -u kubelet -n 100 --no-pager
sudo ls -l /var/log/containers/

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

Це мислення в термінах часової шкали перетворює сирі команди на аналіз. Якщо DNS збоїть для кожного Pod’а в кожному просторі імен, не починайте з редагування Деплойменту одного застосунку. Якщо лише один Сервіс має порожні endpoint’и, не перезапускайте CoreDNS. Якщо лише нові Pod’и застрягли у Pending, але наявні Pod’и продовжують працювати, зосередьтеся на плануванні, квоті, ресурсах ноди, taint’ах чи зв’язуванні PVC, а не на логах застосунку.


6. Екзаменаційна стратегія: швидко, безпечно та з можливістю перевірки

Розділ «6. Екзаменаційна стратегія: швидко, безпечно та з можливістю перевірки»

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

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

Для виправлень робочих навантажень редагуйте контролер, а не Pod, коли Pod належить контролеру. Для виправлень сервісів редагуйте Сервіс чи мітки відповідно до доказів, а потім перевірте endpoint’и та трафік. Для виправлень нод перевірте kubelet, середовище виконання, диск, пам’ять і досяжність API перед спорожненням. Для виправлень площини управління використовуйте інструменти на рівні хоста, бо API може бути недоступним.

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

Добра фінальна перевірка простежує шлях залежностей у зворотному напрямку. Якщо ви виправили Деплоймент, перевірте стан розгортання та Pod’и. Якщо ви виправили селектор Сервісу, перевірте EndpointSlice та запустіть запит із Pod’а-клієнта. Якщо ви перезапустили kubelet, перевірте готовність ноди та те, що Pod’и можна планувати. Якщо ви оновили сертифікати, перевірте справність API та стан компонентів через підтримувані команди.

Terminal window
k rollout status deployment/<deployment-name>
k get pods -o wide
k get endpointslice -l kubernetes.io/service-name=<service-name>
k run curl-test --image=curlimages/curl:8.11.1 --restart=Never --rm -it -- \
curl -sS http://<service-name>.<namespace>.svc.cluster.local

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


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

  2. CrashLoopBackOff називає поведінку перезапуску, а не кореневу причину. Фактична причина зазвичай з’являється у попередніх логах, стані завершення, Events проб, посиланнях на конфігурацію чи доказах ліміту ресурсів.

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

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


ПомилкаЧому це шкодитьКраща практика
Перевірка логів застосунку перед Events для Pod’а у стані PendingPod у стані Pending не запускався, тож логи зазвичай не можуть пояснити збій плануванняВикористовуйте k describe pod і читайте Events, перш ніж переходити до логів
Видалення Pod’ів, що належать поламаному шаблону ДеплойментуReplicaSet відтворює Pod’и з тією самою поганою конфігурацієюВиправте шаблон Деплойменту, потім перевірте розгортання
Розгляд CrashLoopBackOff як одного конкретного збоюЗбої можуть походити від помилок застосунку, відсутньої конфігурації, проб, прав доступу чи лімітів пам’ятіОгляньте попередні логи та стан останнього завершення перед патчем
Перезапуск CoreDNS через один Сервіс із порожніми endpoint’амиDNS може бути справним, тоді як селектор Сервісу чи готовність Pod’а неправильніСпершу перевірте селектор Сервісу, EndpointSlice, мітки та готовність
Спорожнення ноди у стані NotReady перед перевіркою kubelet і середовища виконанняСпорожнення може порушити роботу навантажень і може збоїти, якщо шляхи ноди чи API несправніСпершу огляньте kubelet, containerd, диск, пам’ять і досяжність API
Редагування маніфесту статичного Pod’а без перевірки синтаксису та шляхівДрукарська помилка може тримати компонент площини управління вимкненим, бо kubelet постійно повторює спроби з поганим маніфестомУважно перевіряйте логи kubelet і вміст маніфесту до та після змін
Встановлення Metrics Server щоразу, коли k top збоїтьЗбій команди може відображати відсутні метрики, права доступу чи політику кластера, а не збій навантаженняПеревірте, чи Metrics Server очікуваний і дозволений, перш ніж встановлювати компоненти

Q1: Pod’и у стані Pending після Деплойменту

Розділ «Q1: Pod’и у стані Pending після Деплойменту»

Ваша команда розгортає reports-api з трьома репліками. Деплоймент існує, але кожен Pod у стані Pending, і команда застосунку просить у вас логи контейнера. Вам потрібно обрати найшвидшу корисну першу перевірку та пояснити, що ви зробите з результатом.

Відповідь

Починайте з k describe pod <pod-name> і читайте розділ Events, бо Pending означає, що Pod не було заплановано або він не може завершити передумови, пов’язані з плануванням. Логи контейнера навряд чи існують, бо контейнер не запускався.

Якщо Events показують недостатньо CPU чи пам’яті, зменшіть request, якщо це доречно, або додайте ресурси в реальному кластері. Якщо Events показують неприпустимий taint, додайте правильний toleration, лише якщо навантаження має там працювати. Якщо Events показують невідповідність селектора нод чи спорідненості, виправте шаблон Деплойменту. Якщо Events показують проблеми зв’язування PVC, огляньте PVC і StorageClass. Перевірка — k get pods -o wide, що показує призначені ноди, а потім прогрес готовності.

Q2: CrashLoopBackOff після нового образу

Розділ «Q2: CrashLoopBackOff після нового образу»

Деплоймент було оновлено десять хвилин тому, а нові Pod’и — у стані CrashLoopBackOff. k describe pod показує Last State: Terminated, Reason: Error, Exit Code: 1, але без OOMKilled. Попередня ревізія працювала. Вам потрібно вирішити, чи відкочуватися негайно, чи патчити конфігурацію.

Відповідь

Спершу запустіть k logs <pod-name> --previous, бо контейнер запустився та завершився. Якщо попередні логи показують помилку застосунку, спричинену новим образом, як-от невдала міграція чи відсутній бінарний файл, а негайна мета — доступність, k rollout undo deployment/<name> — найшвидше безпечне відновлення. Перевірте через k rollout status deployment/<name> і k get pods.

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

Q3: Ім’я Сервісу розв’язується, але запити збоять

Розділ «Q3: Ім’я Сервісу розв’язується, але запити збоять»

Pod-клієнт може розв’язати checkout.default.svc.cluster.local, але HTTP-запити завершуються за тайм-аутом. Сервіс існує, а Pod’и CoreDNS справні. Вам потрібно простежити наступні рівні без випадкового перезапуску компонентів.

Відповідь

Оскільки розв’язання DNS працює, переходьте до доказів маршрутизації Сервісу. Перевірте Сервіс і EndpointSlice:

Terminal window
k get svc checkout -o wide
k get endpointslice -l kubernetes.io/service-name=checkout
k describe svc checkout

Якщо EndpointSlice порожні, порівняйте селектор Сервісу з мітками та готовністю Pod’а. Якщо endpoint’и існують, порівняйте targetPort Сервісу з фактичним портом прослуховування контейнера, потім розгляньте NetworkPolicy, поведінку kube-proxy чи площини даних і CNI. Перезапуск CoreDNS не виправданий, бо розв’язання імен уже працює.

Q4: Тайм-аут API-сервера в кластері kubeadm

Розділ «Q4: Тайм-аут API-сервера в кластері kubeadm»

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

Відповідь

Використовуйте перевірки на рівні хоста, бо API недоступний. Починайте з доказів kubelet і статичних Pod’ів:

Terminal window
sudo systemctl status kubelet
sudo journalctl -u kubelet -n 80 --no-pager
sudo crictl ps -a | grep kube-apiserver
sudo ls -l /etc/kubernetes/manifests/

Якщо контейнер API-сервера перезапускається, огляньте його логи контейнера через crictl logs <container-id> і перевірте маніфест на нещодавнє редагування. Неправильний прапорець, поганий шлях до сертифіката чи помилка YAML можуть завадити запуску статичного Pod’а. Після виправлення маніфесту kubelet має відтворити статичний Pod. Перевірте через crictl ps, а потім kubectl get nodes, щойно доступ до API повернеться.

Q5: Нода у стані NotReady, але навантаження ще існують деінде

Розділ «Q5: Нода у стані NotReady, але навантаження ще існують деінде»

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

Відповідь

Зосередьтеся на досяжності API-сервера з ноди та автентифікації чи мережевому шляху kubelet, а не на логах застосунку чи селекторах Сервісу. Kubelet має спілкуватися з API-сервером, щоб повідомляти статус ноди. Перевірте мережеву зв’язність до endpoint’а API, DNS чи розв’язання імені хоста, якщо використовується ім’я, правила фаєрвола та помилки, пов’язані із сертифікатами kubelet, у журналі.

Корисні перевірки включають:

Terminal window
curl -k https://<api-server-address>:6443/healthz
sudo journalctl -u kubelet -n 120 --no-pager

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

Q6: Порожні endpoint’и після зміни мітки

Розділ «Q6: Порожні endpoint’и після зміни мітки»

Розробник змінив мітки Pod’а під час прибирання. Деплоймент має справні Pod’и, але трафік через Сервіс збоїть, а k get endpointslice -l kubernetes.io/service-name=web не показує готових адрес. Вам потрібно відновити трафік без відтворення застосунку.

Відповідь

Порівняйте селектор Сервісу з фактичними мітками Pod’а:

Terminal window
k get svc web -o jsonpath='{.spec.selector}{"\n"}'
k get pods --show-labels

Якщо Сервіс вибирає app=web, але Pod’и тепер мають app=frontend, або відновіть очікувану мітку Pod’а через шаблон Деплойменту, або оновіть селектор Сервісу до правильної стабільної мітки. Оберіть варіант, що відповідає передбачуваній угоді про іменування у сценарії. Перевірте через EndpointSlice, що показують адреси, та запит із Pod’а-клієнта. Відтворення Pod’ів зайве, якщо тільки ви не змінили шаблон Деплойменту і вам не потрібно, щоб контролер розгорнув нові мітки.

Q7: Метрики відсутні під час розслідування OOM

Розділ «Q7: Метрики відсутні під час розслідування OOM»

Pod неодноразово перезапускається, а власник застосунку просить вивід kubectl top pod. Команда повертає metrics not available. Вам усе ще потрібно визначити, чи задіяні ліміти пам’яті, і вирішити наступну дію.

Відповідь

Не зупиняйтеся через метрики, якщо доступні докази статусу. Огляньте стан завершення Pod’а та Events:

Terminal window
k describe pod <pod-name>
k get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}{"\n"}'

Якщо причина — OOMKilled, огляньте ліміти ресурсів контейнера в шаблоні контролера та скоригуйте їх, якщо сценарій підтримує таке виправлення. Відсутність Metrics Server означає лише те, що kubectl top не може надати поточні метрики; вона не стирає доказів завершення. Ви можете окремо перевірити, чи встановлено Metrics Server, але негайний шлях до кореневої причини використовує статус Pod’а та Events.

Q8: Міжнодовий трафік збоїть, але трафік у межах однієї ноди працює

Розділ «Q8: Міжнодовий трафік збоїть, але трафік у межах однієї ноди працює»

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

Відповідь

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

Перевірте CNI-Pod’и та логи на нодах:

Terminal window
k -n kube-system get pods -o wide
k -n kube-system logs <cni-pod-name>

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


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

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

Крок 1: Встановіть простір імен і базовий стан

Розділ «Крок 1: Встановіть простір імен і базовий стан»

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

Terminal window
k get all -n trouble-lab -o wide
k get events -n trouble-lab --sort-by=.lastTimestamp

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

Крок 2: Огляньте Pod’и за станом життєвого циклу

Розділ «Крок 2: Огляньте Pod’и за станом життєвого циклу»

Якщо будь-який Pod у стані Pending, ContainerCreating, ImagePullBackOff чи CrashLoopBackOff, огляньте один репрезентативний Pod.

Terminal window
k describe pod -n trouble-lab <pod-name>

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

Terminal window
k logs -n trouble-lab <pod-name> --previous

Вирішіть, чи належить виправлення шаблону Деплойменту, ConfigMap чи Secret’у, на який є посилання, request чи ліміту ресурсів, посиланню на образ чи пробі. Застосуйте лише ту зміну, що підтверджена доказами.

Крок 3: Перевірте джерело істини контролера

Розділ «Крок 3: Перевірте джерело істини контролера»

Якщо ви змінюєте конфігурацію навантаження, змінюйте контролер-власник, а не окремий Pod.

Terminal window
k get deploy -n trouble-lab
k edit deployment -n trouble-lab <deployment-name>
k rollout status deployment -n trouble-lab <deployment-name>

Після розгортання підтвердьте, що нові Pod’и справні.

Terminal window
k get pods -n trouble-lab -o wide

Крок 4: Простежте маршрутизацію Сервісу

Розділ «Крок 4: Простежте маршрутизацію Сервісу»

Щойно Pod’и стануть справними або поки інший колега виправляє навантаження, огляньте шлях Сервісу.

Terminal window
k get svc -n trouble-lab web -o wide
k describe svc -n trouble-lab web
k get endpointslice -n trouble-lab -l kubernetes.io/service-name=web
k get pods -n trouble-lab --show-labels

Якщо endpoint’и порожні, порівняйте селектори та мітки, потім виправте селектор Сервісу чи мітки шаблону Деплойменту відповідно до передбачуваного іменування. Якщо endpoint’и існують, порівняйте targetPort Сервісу з портом контейнера та прослуховувачем застосунку.

Крок 5: Тестуйте з Pod’а-клієнта

Розділ «Крок 5: Тестуйте з Pod’а-клієнта»

Використовуйте тимчасовий Pod-клієнт, щоб протестувати той самий шлях, який використовував би реальний клієнт усередині кластера.

Terminal window
k run curl-test -n trouble-lab \
--image=curlimages/curl:8.11.1 \
--restart=Never \
--rm -it -- \
curl -sS http://web.trouble-lab.svc.cluster.local

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

Крок 6: Зафіксуйте свої міркування

Розділ «Крок 6: Зафіксуйте свої міркування»

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

Критерії успіху:

  • Ви ідентифікували перший рівень, що збоїть, перед внесенням змін.
  • Ви використали Events із k describe pod для доказів планування, образу, монтування, проби чи життєвого циклу.
  • Ви використали k logs --previous лише тоді, коли контейнер дійсно запускався та перезапускався.
  • Ви змінили контролер-власник чи об’єкт, на який є посилання, а не патчили ефемерний Pod.
  • Ви перевірили відновлення Деплойменту через k rollout status, коли було задіяно розгортання.
  • Ви перевірили маршрутизацію Сервісу через EndpointSlice чи endpoint’и перед тестуванням HTTP.
  • Ви протестували фінальний шлях користувача з Pod’а-клієнта всередині кластера.
  • Ви можете пояснити, чому ваше виправлення було вужчим за видалення та відтворення застосунку.

Питання для роздумів:

  1. Яка команда дала вам перші вирішальні докази і чому вона була кращою за команду, яку ви ледь не запустили?
  2. Що сталося б, якби ви видалили Pod’и, що збоять, не виправивши об’єкт-джерело?
  3. Яка команда перевірки довела, що видимий користувачем шлях виправлено, а не просто довела, що Kubernetes прийняв ваше редагування?
  4. Якби цей інцидент стався на продакшені, які докази ви хотіли б зберегти після того, як Events Kubernetes закінчаться?

Переходьте до Частини 6: Пробні іспити для практики під час на умовах іспиту.

  • cncf.io: cka — CNCF публікує поточні ваги доменів CKA та зазначає Troubleshooting на рівні 30%.
  • kubernetes.io: pods — документація Kubernetes Pods зазначає, що одне з основних застосувань статичних Pod’ів — запуск самостійно розміщеної площини управління.
  • kubernetes.io: static pod — задача про статичні Pod’и документує, що kubelet періодично сканує налаштований каталог маніфестів і додає чи видаляє Pod’и, коли файли з’являються чи зникають.
  • kubernetes.io: pod lifecycle — документація життєвого циклу Pod’а визначає CrashLoopBackOff як стан backoff для контейнера, що неодноразово збоїть.
  • kubernetes.io: crictl — задача про crictl явно описує crictl як CLI для CRI-сумісних середовищ виконання, що використовується для огляду та діагностики на рівні ноди.
  • kubernetes.io: node status — довідник стану ноди визначає семантику Ready та пояснює, що пропущені серцебиття призводять до станів готовності Unknown чи False.
  • kubernetes.io: endpoint slices — готовність EndpointSlice задокументована як відображення готовності Pod’а для вибору трафіку Сервісу.
  • kubernetes.io: index.html — документація Сервісу явно описує зіставлення port Сервісу з targetPort бекенду на Pod’ах.
  • kubernetes.io: dns pod service — документація DNS для Сервісів і Pod’ів пояснює пошук коротких імен у межах простору імен та потребу вказувати простір імен для розв’язання між просторами імен.
  • kubernetes.io: network policies — документація NetworkPolicy охоплює незалежну ізоляцію ingress та egress і явно зазначає, що навантаження, які потребують розв’язання DNS, вимагають окремої egress-політики.
  • kubernetes.io: event v1 — довідник API Event каже, що Events мають обмежений час зберігання та є інформативними, найкращими за можливістю додатковими даними.
  • kubernetes.io: kubectl logs — довідник kubectl logs документує --previous як друк логів попереднього екземпляра контейнера, коли вони доступні.
  • kubernetes.io: kubectl top — довідник kubectl top зазначає, що він отримує дані з Metrics Server і вимагає, щоб цей компонент було встановлено та запущено.
  • Troubleshooting Applications — охоплює практичні шляхи діагностики для Pod’ів, Сервісів, StatefulSet’ів і поширених режимів збоїв контейнерів.