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

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

Lab Progress 0/5 completed

Складність: огляд спостережуваності рівня CKAD — від середнього до просунутого.

Орієнтовний час: 70–90 хвилин на вивчення, практику, тест та прибирання.

Передумови: завершені модулі Частини 3 про проби, логи, діагностику, моніторинг ресурсів та версії API.

Припущення щодо кластера: Kubernetes 1.35 або новіша версія, зі встановленим Metrics Server для kubectl top.

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

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

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

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

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

Ви зможете оцінити докази спостережуваності з kubectl describe, k logs, k top та команд виявлення API, щоб обрати наступну найціннішу дію з діагностики під екзаменаційним тиском CKAD.

Ви зможете порівняти поширені режими відмов, такі як CrashLoopBackOff, Поди у стані NotReady, порожні ендпоінти (Endpoints), відсутні метрики та маніфести зі застарілим API, а потім обґрунтувати послідовність команд, яка підтверджує або відкидає кожну гіпотезу.

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

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

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

Команда розгортає платіжний API за кілька хвилин до початку гарячого розпродажу, і викочування виглядає зеленим, тому що Деплоймент повідомляє про бажану кількість реплік. За кілька хвилин запити клієнтів починають завершуватися за таймаутом, у Сервісу менше ендпоінтів, ніж очікувалося, а один контейнер перезапускається настільки швидко, що його поточні логи показують лише найновіший банер завантаження. Завчена напам’ять команда не допоможе нікому, якщо оператор не може вирішити, що робити далі: describe, logs --previous, top, перевірку ендпоінтів чи зміну проби.

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

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

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

1. Спостережуваність починається з меж, а не з команд

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

Перша помилка в діагностиці Kubernetes — трактувати кожен симптом як проблему Пода. Збій, помітний користувачеві, перетинає кілька меж: запит клієнта, Сервіс, ендпоінти (Endpoints) або EndpointSlices, готовність Пода, процес контейнера, файлову систему, тиск на ресурси, а іноді й версію API, що використовувалася для створення об’єкта. Найшвидший діагностичний шлях — це не найдовший список команд; це найкоротший шлях, який визначає, яка саме межа зламана.

Використовуйте цю ментальну модель, перш ніж торкатися YAML. Якщо Сервіс не має ендпоінтів, негайне питання — не чи правильно встановлено nginx. Негайне питання — чи селектор Сервісу збігається з готовими (Ready) Подами, бо тільки готові Поди, що збігаються, мають отримувати трафік. Якщо Под у стані Running, але не Ready, негайне питання — чи readiness зазнає невдачі через те, що застосунок не приймає трафік, чи через те, що проба націлена не туди. Якщо Под перезапускається, поточні логи можуть вводити в оману, бо вони показують новий екземпляр контейнера, тоді як --previous показує той, що впав.

+-------------------+ +-------------------+ +-------------------+
| External symptom | ---> | Kubernetes route | ---> | Container reality |
| timeout or 503 | | Service endpoints | | process and logs |
+-------------------+ +-------------------+ +-------------------+
| | |
v v v
+-------------------+ +-------------------+ +-------------------+
| Check Service | | Check readiness | | Check previous |
| selector and port | | probe and Events | | logs and restarts |
+-------------------+ +-------------------+ +-------------------+

Діаграма навмисно проста, бо перший прохід через інцидент має бути простим. Ви намагаєтеся знайти зламану межу, перш ніж заглиблюватися в деталі. Коли межа — між Сервісом і Подом, перевіряйте селектори та ендпоінти. Коли межа — між kubelet і контейнером, перевіряйте проби, лічильники перезапусків, події та логи. Коли межа — між планувальником і ресурсами вузла, перевіряйте запити (requests), обмеження (limits), тиск на вузол та метрики.

Корисна звичка для CKAD — запитати: «Що мало б бути правдою, щоб з’явився цей симптом?» Сервіс без ендпоінтів вимагає або відсутності Подів, що збігаються, або наявності таких Подів, що не є Ready, або селектора, який вказує на хибні мітки. CrashLoopBackOff вимагає контейнера, який завершується, який убиває проба, або який не може успішно стартувати. Відсутній результат kubectl top вимагає або відсутнього Metrics Server, або затримки збору, або об’єкта, який наразі не видає метрик. Кожен симптом має невелику множину ймовірних причин, і ця множина визначає наступну команду.

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

2. Стратегія проб: startup, liveness та readiness виконують різні завдання

Розділ «2. Стратегія проб: startup, liveness та readiness виконують різні завдання»

Проби часто подають як три схожі YAML-блоки, але їхні значення достатньо різні, щоб їх плутання спричиняло збої. Проба startup захищає повільну ініціалізацію, відкладаючи перевірки liveness та readiness, доки застосунок не матиме достатньо часу на завантаження. Проба liveness відповідає на питання: «Чи має kubelet перезапустити цей контейнер, бо він зламаний?» Проба readiness відповідає на питання: «Чи має цей Под отримувати трафік прямо зараз?» Ці питання вказують на різні ризики, тож конфігурація проб має відображати різну поведінку при відмові.

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

Проби startup особливо важливі для застосунків, які виконують міграції, прогрівають кеш, завантажують моделі або ініціалізують великі графи залежностей. Без проби startup liveness починається після initialDelaySeconds, і затримка, що працює на ноутбуці розробника, може зазнати невдачі на навантаженому вузлі. Проба startup дає застосунку довше вікно завантаження, водночас і далі дозволяючи liveness захищати його після успішного запуску. Це не просто зручність; це змінює семантику відмови з «перезапуск під час повільного завантаження» на «перезапуск після того, як запуск зазнав невдачі понад прийнятний поріг».

apiVersion: apps/v1
kind: Deployment
metadata:
name: observed-api
spec:
replicas: 2
selector:
matchLabels:
app: observed-api
template:
metadata:
labels:
app: observed-api
spec:
containers:
- name: api
image: nginx:1.27
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /
port: 80
failureThreshold: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: 80
periodSeconds: 10
timeoutSeconds: 2
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
timeoutSeconds: 2

Цей Деплоймент навмисно скромний, бо структура важливіша за образ. Проба startup дозволяє до п’яти хвилин спроб запуску, перш ніж kubelet вважатиме запуск невдалим. Після успішного запуску liveness перевіряє кожні десять секунд і може перезапустити контейнер, якщо HTTP-ендпоінт перестане відповідати. Readiness перевіряє частіше, бо маршрутизація Сервісу виграє від швидшого вилучення та відновлення трафіку.

Проба, яку ви обираєте, має відповідати тій відмові, яку ви хочете доручити Kubernetes. HTTP-проби природні, коли застосунок виставляє ендпоінт справності. TCP-проби корисні, коли відкритий сокет є добрим сигналом готовності, хоча вони не можуть перевірити коректність на рівні застосунку. Exec-проби корисні, коли справність залежить від локальних файлів або команд усередині контейнера, але вони можуть бути дорогими та крихкими, якщо виконують складну shell-логіку. Проба — це частина вашого контракту площини управління з kubelet, тож тримайте її вузькою, швидкою та змістовною.

Тип пробиГоловне питанняТипова дія при відмовіПоширений ризик на CKAD
startupProbeЧи застосунок уже завершив ініціалізацію?Відкладає інші проби, потім перезапускає, якщо запуск так і не вдавсяЇї відсутність для повільних застосунків спричиняє перезапуски liveness під час завантаження
livenessProbeЧи контейнер достатньо зламаний, щоб перезапуститися?Перезапускає контейнер після досягнення порога відмовПеревірка зовнішніх залежностей може спричинити шторм перезапусків
readinessProbeЧи має цей Под отримувати трафік Сервісу?Вилучає або додає ендпоінти Пода без перезапускуХибний шлях або порт робить здорові Поди недосяжними
exec-пробаЧи команда всередині контейнера завершується успішно?Залежить від поля проби, що її використовуєПрипущення про shell зазнають невдачі в мінімальних образах
httpGet-пробаЧи HTTP-ендпоінт повертає успіх?Залежить від поля проби, що її використовуєНевідповідність шляху, іменованого порту або схеми спричиняє хибну відмову

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

Підказка для активного навчання: припустимо, API не може обслуговувати запити, поки його база даних недоступна, але автоматично під’єднується знову, коли база повертається. Куди ви помістили б перевірку бази даних: у liveness, readiness, в обидві чи в жодну? Обґрунтуйте операційні наслідки свого вибору, перш ніж порівнювати його зі сценаріями тесту далі.

3. Розбір прикладу: діагностика Пода, що працює, але ніколи не отримує трафіку

Розділ «3. Розбір прикладу: діагностика Пода, що працює, але ніколи не отримує трафіку»

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

Спершу створіть невелике зламане навантаження з невідповідністю між мітками шаблону Пода та селектором Сервісу. Це можна запускати в практичному просторі імен, і воно використовує лише стандартні ресурси Kubernetes. Деплоймент створює Поди з міткою app: checkout-api, тоді як Сервіс обирає app: checkout, тож Сервіс не має жодних ендпоінтів, що збігаються, навіть попри наявність Подів.

Terminal window
k create namespace observability-lab
k -n observability-lab create deployment checkout-api --image=nginx:1.27 --replicas=2
k -n observability-lab label deployment checkout-api tier=frontend
k -n observability-lab expose deployment checkout-api --name=checkout-svc --port=80 --target-port=80
k -n observability-lab patch svc checkout-svc -p '{"spec":{"selector":{"app":"checkout"}}}'

Тепер перевіримо симптом з межі Сервісу. Перша команда підтверджує селектор Сервісу, а друга перевіряє, чи знайшов Kubernetes хоч якісь готові Поди, що йому відповідають. Залежно від версії вашого кластера та налаштувань відображення, k get endpoints може показувати <none> для Сервісу, тоді як EndpointSlices надають новіше подання тих самих даних маршрутизації.

Terminal window
k -n observability-lab describe svc checkout-svc
k -n observability-lab get endpoints checkout-svc
k -n observability-lab get endpointslice -l kubernetes.io/service-name=checkout-svc

Очікувані докази вказують геть від логів контейнера. Контейнери, ймовірно, у порядку, бо Сервіс навіть не може їх обрати. Наступна команда порівнює мітки Подів із селектором Сервісу. Це цінніший крок, ніж запуск k logs, бо межа відмови вже пролягає між Сервісом і вибором Пода.

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

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

Terminal window
k -n observability-lab patch svc checkout-svc -p '{"spec":{"selector":{"app":"checkout-api"}}}'
k -n observability-lab get endpoints checkout-svc
k -n observability-lab get endpointslice -l kubernetes.io/service-name=checkout-svc

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

Схожий патерн з’являється з пробами readiness. Якщо мітки збігаються, але Поди не Ready, у Сервісу все одно може не бути придатних ендпоінтів. У цьому разі наступні докази — це k describe pod, особливо секція проби readiness та події ближче до низу. Правильним виправленням може бути зміна шляху проби, виставлення правильного порту контейнера або лагодження ендпоінта справності застосунку. Метод «спочатку межа» все одно діє: доведіть, що саме відповідальне — маршрутизація, readiness чи справність процесу, перш ніж редагувати YAML.

Terminal window
k -n observability-lab get pods
k -n observability-lab describe pod -l app=checkout-api
k -n observability-lab logs -l app=checkout-api --tail=40

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

4. CrashLoopBackOff: збережіть докази, поки вони не зникли

Розділ «4. CrashLoopBackOff: збережіть докази, поки вони не зникли»

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

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

Terminal window
k get pod crashing-pod
k describe pod crashing-pod
k logs crashing-pod --previous --tail=80
k logs crashing-pod --tail=80

Використовуйте describe, щоб пов’язати логи з деталями життєвого циклу. Секція Last State може показувати коди виходу, причини та позначки часу. Події можуть показувати невдачі проб, проблеми завантаження образу, OOM-убивства, невдалі монтування та проблеми планування. Якщо події згадують невдачі проби liveness перед перезапусками, застосунок може не завершуватися сам по собі; kubelet може вбивати його, бо налаштована перевірка справності зазнає невдачі.

Terminal window
k describe pod crashing-pod | sed -n '/Containers:/,/Conditions:/p'
k describe pod crashing-pod | sed -n '/Events:/,$p'

Коли Под має більш ніж один контейнер, завжди вказуйте ім’я контейнера. Sidecar- та init-контейнери дають різні докази, і k logs pod-name може обрати усталений варіант, що не є контейнером, який падає. У контексті CKAD це часте джерело витраченого часу, бо команда завершується успішно, відповідаючи на хибне питання.

Terminal window
k get pod multi-app -o jsonpath='{.spec.containers[*].name}{"\n"}'
k logs multi-app -c backend --previous --tail=60
k logs multi-app -c frontend --tail=60

Тиск на ресурси додає ще один шар. Якщо контейнер було OOMKilled, логи можуть бути неповними, бо ядро завершило процес. kubectl top допомагає визначити поточне використання CPU та пам’яті, але не замінює стан життєвого циклу, бо top показує живі метрики, а не точну причину попереднього завершення. Використовуйте обидва сигнали разом: життєвий цикл каже, що сталося, а метрики кажуть, чи умова досі присутня.

Terminal window
k top pod crashing-pod
k top pod crashing-pod --containers
k describe pod crashing-pod | grep -A8 "Last State"

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

+----------------------+
| Pod is CrashLooping |
+----------+-----------+
|
v
+----------------------+
| Read previous logs |
| k logs --previous |
+----------+-----------+
|
v
+----------------------+
| Describe lifecycle |
| exit code + Events |
+----------+-----------+
|
v
+----------------------+ +----------------------+
| Probe failure shown? | -----> | Inspect probe path, |
+----------+-----------+ yes | port, delay, timing |
| no +----------------------+
v
+----------------------+ +----------------------+
| OOMKilled or limits? | -----> | Compare top metrics |
+----------+-----------+ yes | with requests/limits|
| no +----------------------+
v
+----------------------+
| Inspect command, env,|
| mounts, image, args |
+----------------------+

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

5. Логи, метрики та виявлення API під екзаменаційним тиском

Розділ «5. Логи, метрики та виявлення API під екзаменаційним тиском»

Завдання CKAD часто винагороджують швидкість, але швидкість має походити з відпрацьованого добору команд, а не з вгадування. Логи відповідають на питання «що видав процес?» Метрики відповідають на питання «які ресурси об’єкти споживають зараз?» Виявлення API відповідає на питання «яку схему приймає цей кластер?» Ці інструменти доповнюють одне одного, і їхнє плутання веде до поверхневої діагностики.

Логи найсильніші для поведінки застосунку та виводу контейнера. Використовуйте --tail, щоб тримати вивід сфокусованим, -f, щоб стежити за активними логами, --previous для перезапущених контейнерів та -c для конкретного контейнера. Використовуйте селектори міток, коли питання стосується всіх реплік Деплойменту, але пам’ятайте, що поєднані логи з кількох Подів можуть перемішувати рядки й приховувати послідовність. Для точної діагностики звужуйте докази за потреби.

Terminal window
k logs deploy/checkout-api --tail=100
k logs deploy/checkout-api --all-containers --tail=100
k logs pod/checkout-api-abc123 -c api --previous --tail=80
k logs -l app=checkout-api --since=10m --tail=200

Метрики найсильніші для поточного використання ресурсів та відносного порівняння. Вони залежать від Metrics Server, тож помилка від k top може бути проблемою системи спостережуваності, а не проблемою застосунку. Сортування допомагає під екзаменаційним тиском, коли вам потрібен найбільший споживач CPU або пам’яті. Використовуйте --containers, коли багатоконтейнерний Под приховує, який контейнер відповідальний.

Terminal window
k top pods -A --sort-by=memory
k top pods -n observability-lab --sort-by=cpu
k top pod checkout-api-abc123 --containers
k top nodes

Виявлення API запобігає помилкам зі застарілими маніфестами. Kubernetes 1.35 приймає поточні стабільні API для поширених ресурсів CKAD, таких як Ingress networking.k8s.io/v1, CronJob batch/v1 та NetworkPolicy networking.k8s.io/v1. Замість того щоб покладатися на пам’ять під час екзамену, використовуйте k explain або k api-resources, щоб підтвердити групу та версію, які обслуговує кластер.

Terminal window
k explain ingress | grep VERSION
k explain cronjob | grep VERSION
k explain networkpolicy | grep VERSION
k api-resources | grep -E 'ingresses|cronjobs|networkpolicies'

Тонкий нюанс у тому, що команди виявлення показують вам, що знає API-сервер, а не чи коректний семантично саме ваш маніфест. CronJob може використовувати batch/v1 і все одно зазнати невдачі, бо імена полів хибні. Ingress може використовувати правильну версію API і все одно маршрутизувати неправильно, бо pathType або імена бекенд-сервісів хибні. Виявлення — це перший шлюз, а не повна історія валідації.

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

+----------+ +-------+ +----------+ +------+ +-------------+
| Symptom | --> | Scope | --> | Evidence | --> | Fix | --> | Verification|
+----------+ +-------+ +----------+ +------+ +-------------+
| 503 | | svc | | endpoints| | label| | endpoints |
| restart | | pod | | previous | | probe| | restarts |
| high mem | | node | | top | | limit| | top + state |
| bad YAML | | api | | explain | | field| | apply dryrun|
+----------+ +-------+ +----------+ +------+ +-------------+

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

6. Від огляду тесту до операційної практики

Розділ «6. Від огляду тесту до операційної практики»

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

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

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

  1. Невдачі readiness не перезапускають контейнер; вони вилучають Под з ендпоінтів Сервісу, доки умова готовності знову не стане істинною.

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

  3. EndpointSlices — це масштабований наступник старішого об’єкта Endpoints, але k get endpoints залишається корисним для швидких перевірок у стилі CKAD на невеликих Сервісах.

  4. kubectl top повідомляє метрики, зібрані через конвеєр метрик ресурсів, тож це живе подання використання, а не історичний реєстратор інцидентів.

ПомилкаЧому це шкодитьКраща практика
Перевірка логів застосунку до перевірки того, чи має Сервіс ендпоінтиКонтейнер може бути здоровим, тоді як маршрутизація зламана, тож логи марнують час і відвертають увагу від доказів селектора чи readinessПочинайте з межі, яку передбачає симптом, і рухайтеся всередину лише тоді, коли стан маршрутизації правдоподібний
Використання того самого ендпоінта, навантаженого залежностями, для liveness і readinessТимчасовий збій залежності може спричинити перезапуски, замість того щоб лише вилучити трафік з ПодаТримайте liveness сфокусованою на справності процесу, а readiness використовуйте для здатності обслуговувати трафік
Забування --previous під час CrashLoopBackOffПоточні логи можуть показати лише найновіший перезапуск і пропустити екземпляр контейнера, що впавЗахоплюйте попередні логи рано, потім пов’язуйте їх із кодами виходу та подіями
Пропуск -c у багатоконтейнерних ПодахKubernetes може показати логи не того контейнера або попросити обрати контейнер під час браку часуПерелічіть імена контейнерів і перевірте той, що відповідає симптому
Трактування kubectl top як інструмента визначення першопричиниМетрики показують поточне використання, а не повну історію чи причину завершенняПоєднуйте метрики з describe, подіями, лічильниками перезапусків та причинами завершення
Патчинг селектора Сервісу без перевірки ендпоінтівAPI може прийняти патч, який усе одно не обирає жодного готового ПодаПеревіряйте через Endpoints або EndpointSlices після кожної зміни маршрутизації
Копіювання старих маніфестів без виявлення APIЗастарілі або вилучені версії API зазнають невдачі ще до того, як можна перевірити поведінку навантаженняПідтверджуйте поточні версії через k explain або k api-resources у цільовому кластері
Збільшення затримок проб без розуміння відмовиЗміни таймінгу можуть приховати помилку застосунку або подовжити збійСпершу читайте події та логи, потім свідомо коригуйте тип проби, шлях, порт, поріг або затримку

Питання 1: Сервіс маршрутизує до жодного Пода

Розділ «Питання 1: Сервіс маршрутизує до жодного Пода»

Ваша команда виставляє Деплоймент на ім’я orders-api через Сервіс на ім’я orders-svc. Деплоймент має два Поди у стані Running, але запити через Сервіс зазнають невдачі з помилками з’єднання. k get endpoints orders-svc не показує жодних адрес. Що слід перевірити першим і яким є прицільне виправлення, якщо селектор Сервісу не збігається з мітками Подів?

Відповідь

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

Terminal window
k describe svc orders-svc
k get pods --show-labels
k get svc orders-svc -o jsonpath='{.spec.selector}{"\n"}'
# Приклад прицільного виправлення, коли Поди мають мітку app=orders-api:
k patch svc orders-svc -p '{"spec":{"selector":{"app":"orders-api"}}}'
# Перевірте стан, який має змінитися:
k get endpoints orders-svc
k get endpointslice -l kubernetes.io/service-name=orders-svc

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

Питання 2: Под у стані Running не стає Ready

Розділ «Питання 2: Под у стані Running не стає Ready»

Под на ім’я catalog-0 у стані Running, але ніколи не стає Ready. Проба readiness налаштована як HTTP GET на /ready порт 8080, але застосунок слухає порт 8000. Які команди ви використали б, щоб підтвердити невдачу проби, і як ви виправили б конфігурацію?

Відповідь

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

Terminal window
k describe pod catalog-0 | sed -n '/Readiness:/,/Environment:/p'
k describe pod catalog-0 | sed -n '/Events:/,$p'
k get pod catalog-0 -o jsonpath='{.spec.containers[*].ports}{"\n"}'
# Якщо цей Под належить Деплойменту на ім'я catalog:
k patch deployment catalog --type='json' \
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/httpGet/port","value":8000}]'
k rollout status deployment catalog
k get pods -l app=catalog
k get endpoints catalog

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

Питання 3: Повільний запуск спричиняє цикл перезапусків

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

Java-застосунок ініціалізується три хвилини на навантаженому вузлі. Деплоймент має пробу liveness з initialDelaySeconds: 20, periodSeconds: 10 та failureThreshold: 3. Поди потрапляють у CrashLoopBackOff, хоча застосунок працює локально. Як би ви переробили проби, щоб Kubernetes не вбивав застосунок під час нормального запуску?

Відповідь

Додайте пробу startup, що дає достатньо часу на ініціалізацію, потім збережіть liveness для справності процесу після запуску, а readiness — для обслуговування трафіку. Проба startup вимикає liveness і readiness, доки запуск не вдасться, що запобігає перетворенню нормального повільного завантаження на цикл перезапусків.

Terminal window
k patch deployment java-api --type='json' -p='[
{
"op": "add",
"path": "/spec/template/spec/containers/0/startupProbe",
"value": {
"httpGet": {
"path": "/healthz",
"port": 8080
},
"periodSeconds": 10,
"failureThreshold": 30
}
},
{
"op": "replace",
"path": "/spec/template/spec/containers/0/livenessProbe/httpGet/path",
"value": "/healthz"
},
{
"op": "replace",
"path": "/spec/template/spec/containers/0/readinessProbe/httpGet/path",
"value": "/ready"
}
]'
k rollout status deployment java-api
k describe pod -l app=java-api | sed -n '/Startup:/,/Environment:/p'

Важливий проєктний вибір — не просто збільшення затримки liveness. Проба startup моделює окрему фазу запуску, тоді як readiness усе одно може тримати Под поза трафіком, доки він справді не зможе обслуговувати.

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

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

Под на ім’я billing-worker у стані CrashLoopBackOff. Запуск k logs billing-worker показує лише найновіше повідомлення про запуск, а корисний виняток не видно. Які докази вам слід зібрати далі і як ви вирішуєте, чи процес завершився сам, чи його вбив kubelet?

Відповідь

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

Terminal window
k logs billing-worker --previous --tail=100
k describe pod billing-worker | sed -n '/Last State:/,/Ready:/p'
k describe pod billing-worker | sed -n '/Events:/,$p'

Якщо попередні логи показують виняток застосунку, а Last State показує ненульовий код виходу, процес, імовірно, завершився сам. Якщо події показують повторні невдачі проби liveness, після яких ідуть перезапуски, kubelet, імовірно, убив контейнер, бо проба зазнала невдачі. Якщо причина — OOMKilled, тиск на ресурси є центральним, а поточні логи можуть бути неповними.

Питання 5: Багатоконтейнерний Под приховує контейнер, що падає

Розділ «Питання 5: Багатоконтейнерний Под приховує контейнер, що падає»

Под на ім’я web-stack має контейнери з іменами frontend, backend та log-agent. Под раз за разом перезапускається, але логи frontend виглядають нормально. Як ви визначаєте, який контейнер падає, і отримуєте відповідні логи?

Відповідь

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

Terminal window
k get pod web-stack -o jsonpath='{.spec.containers[*].name}{"\n"}'
k describe pod web-stack | sed -n '/Containers:/,/Conditions:/p'
k logs web-stack -c backend --previous --tail=100
k logs web-stack -c backend --tail=100

Якщо backend показує перезапуски, а попередні логи містять виняток, це і є докази для виправлення. Логи frontend можуть бути коректними і все одно не стосуватися справи, бо симптом на рівні Пода може спричинити будь-який контейнер у Поді.

Питання 6: Високе споживання пам’яті під час інциденту

Розділ «Питання 6: Високе споживання пам’яті під час інциденту»

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

Відповідь

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

Terminal window
k top pods -n production --sort-by=memory
k top pod suspicious-pod -n production --containers
k describe pod suspicious-pod -n production | sed -n '/Limits:/,/Requests:/p'

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

Питання 7: Маніфест використовує застарілий API

Розділ «Питання 7: Маніфест використовує застарілий API»

Колега дає вам маніфест Ingress, що починається з apiVersion: extensions/v1beta1, і k apply зазнає невдачі на кластері Kubernetes 1.35. Як ви підтверджуєте підтримувану версію API і уникаєте вгадування форми заміни?

Відповідь

Використайте виявлення API проти цільового кластера, потім перевірте схему ресурсу. Для Ingress у сучасному Kubernetes стабільний API — це networking.k8s.io/v1, і маніфест має використовувати поточну структуру полів.

Terminal window
k explain ingress | grep VERSION
k explain ingress.spec
k api-resources | grep ingress

Коректне виправлення змінює більше, ніж рядок версії, якщо старий маніфест використовував застарілі поля. Наприклад, pathType є обов’язковим у шляхах сучасного Ingress, а посилання на бекенд-сервіс використовують поточну структуру service.name та service.port.

Питання 8: Виправлення проби без перевірки

Розділ «Питання 8: Виправлення проби без перевірки»

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

Відповідь

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

Terminal window
k rollout status deployment checkout-api
k get pods -l app=checkout-api
k describe pod -l app=checkout-api | sed -n '/Readiness:/,/Environment:/p'
k describe pod -l app=checkout-api | sed -n '/Events:/,$p'
k get endpoints checkout-svc

Інцидент виправлено лише тоді, коли нові Поди стають Ready, а Сервіс має очікувані ендпоінти. Якщо readiness усе ще зазнає невдачі, зміна шляху не усунула справжню межу або залишається інша проблема.

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

Налаштування вправи

Розділ «Налаштування вправи»

Створіть простір імен і розгорніть невеликий застосунок із двома навмисними проблемами. Селектор Сервісу не збігатиметься з мітками Подів, а проба readiness вказуватиме на хибний порт. Ці дві відмови дозволяють відпрацювати розділення маршрутизації Сервісу та готовності Пода.

Terminal window
k create namespace part3-observability
Terminal window
cat << 'EOF' | k apply -n part3-observability -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: inventory-api
spec:
replicas: 2
selector:
matchLabels:
app: inventory-api
template:
metadata:
labels:
app: inventory-api
tier: backend
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 8080
periodSeconds: 5
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /
port: 80
periodSeconds: 10
timeoutSeconds: 2
EOF
Terminal window
cat << 'EOF' | k apply -n part3-observability -f -
apiVersion: v1
kind: Service
metadata:
name: inventory-svc
spec:
selector:
app: inventory
ports:
- port: 80
targetPort: 80
EOF

Крок 1: Спостерігайте межу маршрутизації

Розділ «Крок 1: Спостерігайте межу маршрутизації»

Почніть із Сервісу, бо симптом, помітний користувачеві, полягає в тому, що трафік через Сервіс не працює. Перевірте селектор Сервісу, мітки Подів, ендпоінти (Endpoints) та EndpointSlices. Не змінюйте нічого, доки не зможете пояснити, чи має Сервіс Поди, що збігаються.

Terminal window
k -n part3-observability describe svc inventory-svc
k -n part3-observability get pods --show-labels
k -n part3-observability get endpoints inventory-svc
k -n part3-observability get endpointslice -l kubernetes.io/service-name=inventory-svc

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

Крок 2: Виправте селектор Сервісу та перевірте новий симптом

Розділ «Крок 2: Виправте селектор Сервісу та перевірте новий симптом»

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

Terminal window
k -n part3-observability patch svc inventory-svc -p '{"spec":{"selector":{"app":"inventory-api"}}}'
k -n part3-observability get endpoints inventory-svc
k -n part3-observability get pods

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

Крок 3: Перевірте докази readiness

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

Тепер перевірте один із Подів і прочитайте секцію проби readiness та події. Проба readiness вказує на порт 8080, але nginx слухає порт 80 у цьому маніфесті. Це саме та помилка, що залишає контейнери працювати, тримаючи їх поза трафіком Сервісу.

Terminal window
POD_NAME="$(k -n part3-observability get pod -l app=inventory-api -o jsonpath='{.items[0].metadata.name}')"
k -n part3-observability describe pod "$POD_NAME" | sed -n '/Readiness:/,/Environment:/p'
k -n part3-observability describe pod "$POD_NAME" | sed -n '/Events:/,$p'

Очікувана логіка: readiness — це шлюз трафіку, тож хибний порт readiness пояснює, чому Поди не стають Ready. Liveness використовує порт 80, тож контейнери можуть уникати перезапусків, усе одно не проходячи readiness. Ця відмінність — навчальний момент: liveness і readiness не мають однакового операційного значення.

Крок 4: Виправте пробу readiness у шаблоні Деплойменту

Розділ «Крок 4: Виправте пробу readiness у шаблоні Деплойменту»

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

Terminal window
k -n part3-observability patch deployment inventory-api --type='json' \
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/httpGet/port","value":80}]'
k -n part3-observability rollout status deployment inventory-api
k -n part3-observability get pods -l app=inventory-api
k -n part3-observability get endpoints inventory-svc

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

Крок 5: Додайте тренування зі збору доказів CrashLoopBackOff

Розділ «Крок 5: Додайте тренування зі збору доказів CrashLoopBackOff»

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

Terminal window
cat << 'EOF' | k apply -n part3-observability -f -
apiVersion: v1
kind: Pod
metadata:
name: failing-worker
spec:
restartPolicy: Always
containers:
- name: worker
image: busybox:1.36
command:
- sh
- -c
- echo "starting worker"; echo "fatal: missing required queue name"; exit 2
EOF

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

Terminal window
k -n part3-observability get pod failing-worker
k -n part3-observability logs failing-worker --previous --tail=20
k -n part3-observability describe pod failing-worker | sed -n '/Last State:/,/Ready:/p'
k -n part3-observability describe pod failing-worker | sed -n '/Events:/,$p'

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

Крок 6: Перевірте метрики та виявлення API

Розділ «Крок 6: Перевірте метрики та виявлення API»

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

Terminal window
k top pods -n part3-observability --sort-by=memory
k top pod -n part3-observability --containers
k explain ingress | grep VERSION
k explain cronjob | grep VERSION
k explain networkpolicy | grep VERSION

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

  • Ви можете пояснити, чому початковий Сервіс не мав ендпоінтів, перш ніж перевіряти логи застосунку.
  • Ви запатчили селектор Сервісу та перевірили стан ендпоінтів після патча.
  • Ви визначили невідповідність порту проби readiness із виводу describe та подій.
  • Ви запатчили шаблон Деплойменту, а не трактували керований Под як довговічне джерело істини.
  • Ви перевірили, що Поди стали Ready і що Сервіс отримав ендпоінти після виправлення readiness.
  • Ви захопили попередні логи з навмисно несправного Пода та пов’язали їх із кодом виходу.
  • Ви належно використали kubectl top або розпізнали, що Metrics Server недоступний.
  • Ви підтвердили принаймні одну поточну версію API за допомогою k explain або k api-resources.
  • Ви можете описати різницю між виправленням маршрутизації, виправленням readiness та виправленням процесу, що падає.

Видаліть практичний простір імен після завершення вправи. Видалення простору імен прибирає Деплоймент, Сервіс, Поди та навмисно несправний worker, створений цією лабораторною роботою.

Terminal window
k delete namespace part3-observability

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

  • training.linuxfoundation.org: certified kubernetes application developer ckad — Офіційна сторінка CKAD називає Kubernetes v1.35 і перелічує ці компетенції зі спостережуваності та обслуговування.
  • kubernetes.io: kubectl top — Довідник kubectl прямо вказує, що Metrics Server має бути встановлений і запущений, щоб kubectl top працював.
  • kubernetes.io: glossary — Стаття глосарія Kubernetes про Event явно описує обмежене утримання та найкращі-зусилля, допоміжну семантику.
  • kubernetes.io: liveness readiness startup probes — Документація про проби вказує, що невдала readiness не перезапускає контейнер і встановлює умову готовності Пода у false.
  • kubernetes.io: endpoint slices — Документація про EndpointSlice пояснює, що Сервіси із селекторами відстежують Поди, що збігаються, і що готовність ендпоінта відповідає готовності Пода.
  • kubernetes.io: pod lifecycle — Документація про життєвий цикл Пода визначає CrashLoopBackOff як стан затримки для контейнера, який раз за разом падає та перезапускається.
  • kubernetes.io: kubectl logs — Довідник kubectl logs явно визначає --previous як друк логів попереднього екземпляра контейнера, якщо він існує.
  • v1-35.docs.kubernetes.io: v1.35 — Довідник API Kubernetes v1.35 перелічує ці ресурси під відповідними обслуговуваними парами група/версія API.
  • v1-35.docs.kubernetes.io: deprecation guide — Посібник з виведення з обігу v1.35 документує вилучення старих API Ingress та обов’язкові зміни форми полів для networking.k8s.io/v1.
  • kubernetes.io: pod condition — Документація про умови Пода вказує, що Поди, які не є Ready, вилучаються з ендпоінтів Сервісу, а документація про проби визначає поведінку при невдачі readiness.
  • kubernetes.io: index.html — Документація про Сервіс прямо підтримує первинність EndpointSlice та обмеження застарілих Endpoints; настанова про швидку перевірку є практичною порадою, а не точним твердженням документації.
  • Debug Services — Вона проходить через діагностику селектора, порту та EndpointSlice у тому самому стилі «спочатку межа», якого навчає цей модуль.