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

Модуль 3.1: Проби застосунку

Hands-On Lab Available
K8s Cluster intermediate 30 min
Launch Lab ↗

Opens in Killercoda in a new tab

Складність: [СЕРЕДНЯ] — критична екзаменаційна тема з виробничими наслідками та кількома компромісами щодо налаштувань.

Час на проходження: 50–60 хвилин.

Передумови: Модуль 1.1 (Поди), базова маршрутизація Сервісів та впевнене читання подій Пода через kubectl describe.


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

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

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

  • Спроєктувати конфігурації liveness-, readiness- та startup-проб, які відповідають поведінці застосунку під час запуску, його моделі залежностей і режимам відмов.
  • Порівняти механізми проб HTTP, TCP, exec та gRPC, а потім обрати найменш ризиковану перевірку для конкретного робочого навантаження.
  • Діагностувати цикли перезапусків, відсутні ендпоінти Сервісу та повільні розгортання, читаючи події проб, статус Пода і членство в ендпоінтах.
  • Оцінити параметри таймінгу проб так, щоб відновлення було швидким, але не спричиняло хибних спрацювань під час звичайного запуску, навантаження чи пауз на збирання сміття.
  • Реалізувати придатні до запуску маніфести Kubernetes, які поєднують startup-, liveness- та readiness-проби для сценаріїв екзаменаційного й виробничого штибу.

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

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

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

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

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

Аналогія з лікарняним моніторингом

Liveness-проба — це наче запитання: «Чи потребує цей пацієнт екстреного втручання, бо життєво важливий процес зупинився?» Readiness-проба — наче запитання: «Чи може цей пацієнт безпечно приймати відвідувачів просто зараз?» Startup-проба — наче вказівка системі моніторингу: «Не застосовуй звичайні правила тривог, поки пацієнт ще прокидається після операції». Кожне запитання має інший наслідок, і використання одного запитання для будь-якої ситуації спричиняє галасливі тривоги або пропущені відмови.


Ментальна модель: три запитання, три дії

Розділ «Ментальна модель: три запитання, три дії»

Проба — це не просто ендпоінт перевірки справності. Це ендпоінт перевірки справності плюс дія Kubernetes. Найшвидший спосіб уникнути помилок із пробами — запитати, що Kubernetes зробить після відмови, бо та сама URL-адреса /healthz може бути безпечною в одній пробі та руйнівною в іншій.

┌──────────────────────────────────────────────────────────────────────────────┐
│ Kubernetes Probe Decision Map │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ startupProbe │
│ Question: Has the application completed its startup sequence? │
│ Failure: Keep waiting until failureThreshold is exceeded. │
│ Success: Enable livenessProbe and readinessProbe evaluation. │
│ │
│ livenessProbe │
│ Question: Is the application alive enough that continuing is useful? │
│ Failure: Kill the container and let the restart policy recreate it. │
│ Success: Leave the running container alone. │
│ │
│ readinessProbe │
│ Question: Should this Pod receive Service traffic right now? │
│ Failure: Remove the Pod IP from matching Service endpoints. │
│ Success: Add or keep the Pod IP in matching Service endpoints. │
│ │
└──────────────────────────────────────────────────────────────────────────────┘

Найважливіша операційна відмінність полягає в тому, що liveness змінює час життя контейнера, тоді як readiness змінює маршрутизацію трафіку. Liveness-проба, що відмовляє, збільшує лічильник перезапусків і може спричинити поведінку CrashLoopBackOff, якщо застосунок ніколи не задовольняє перевірку. Readiness-проба, що відмовляє, не перезапускає контейнер; вона змінює те, чи надсилають Сервіси трафік до цього Пода. Startup-проби стримують дві інші, щоб повільні застосунки не каралися ще до того, як отримали справедливий шанс ініціалізуватися.

Підказка для активного навчання: передбачте дію

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

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


Типи проб у контексті

Розділ «Типи проб у контексті»

Liveness-проба: відновлюйтеся, коли продовжувати гірше, ніж перезапуститися

Розділ «Liveness-проба: відновлюйтеся, коли продовжувати гірше, ніж перезапуститися»

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

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

apiVersion: v1
kind: Pod
metadata:
name: liveness-web
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3

Цей Под використовує просту HTTP liveness-пробу, бо nginx може швидко відповісти на / після запуску. Kubelet чекає десять секунд перед першою перевіркою, опитує кожні десять секунд і перезапускає контейнер після трьох послідовних відмов. Для реального застосунку шлях міг би бути /healthz, але діє той самий принцип: ендпоінт має означати «перезапусти мене, якщо це й далі відмовляє».

Readiness-проба: керуйте трафіком, не вбиваючи контейнер

Розділ «Readiness-проба: керуйте трафіком, не вбиваючи контейнер»

Readiness-проба відповідає на інше запитання: чи може цей Под безпечно отримувати запити просто зараз? Вона може відмовляти під час запуску, прогріву кешу, періодів перевантаження, вікон обслуговування або тимчасової втрати потрібної залежності. Коли readiness відмовляє, Под залишається живим, але Сервіси припиняють маршрутизувати до нього трафік, доки проба знову не пройде.

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

apiVersion: v1
kind: Pod
metadata:
name: readiness-web
labels:
app: readiness-web
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 2

Якщо ця readiness-проба відмовляє, k get pod може й далі показувати Под як Running, але колонка READY не показуватиме контейнер як готовий. Якщо Сервіс обирає Под, членство в ендпоінтах змінюється разом зі зміною readiness. Саме тому readiness-проби центральні для розгортань без простою: Kubernetes може дочекатися, поки нові Поди стануть готовими, перш ніж надсилати їм трафік.

Startup-проба: захистіть повільне завантаження, не послаблюючи liveness назавжди

Розділ «Startup-проба: захистіть повільне завантаження, не послаблюючи liveness назавжди»

Startup-проба призначена для застосунків, час запуску яких тривалий, мінливий або складно передбачуваний. Доки startup-проб не існувало, команди часто використовували дуже великі значення initialDelaySeconds на liveness-пробах. Цей обхідний шлях запобігав раннім перезапускам, але також відкладав виявлення реальних відмов після запуску. Startup-проби розв’язують це, надаючи застосунку окремий бюджет на запуск, а потім передаючи керування звичайним liveness- і readiness-перевіркам, щойно запуск успішно завершується.

Ключова поведінка — стримування. Коли налаштовано startup-пробу, liveness- та readiness-проби не виконуються, доки startup-проба не пройде. Якщо startup-проба ніколи не проходить і перевищено її поріг відмов, Kubernetes перезапускає контейнер. Після того як запуск успішно завершився один раз, startup-проба для цього екземпляра контейнера завершена, і починається звичайна поведінка проб.

apiVersion: v1
kind: Pod
metadata:
name: startup-web
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
failureThreshold: 24
livenessProbe:
httpGet:
path: /
port: 80
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
failureThreshold: 2

Ця startup-проба дає контейнеру близько двох хвилин на проходження першої перевірки справності. Щойно вона проходить, liveness-проба може лишатися доволі агресивною, що означає швидке виявлення відмов після запуску. Це зазвичай краще, ніж встановлювати initialDelaySeconds: 120 на liveness-пробі, бо шлях запуску та шлях відновлення в усталеному стані розділені.

Підказка для активного навчання: оберіть наслідок

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

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


Механізми проб: як Kubernetes перевіряє справність

Розділ «Механізми проб: як Kubernetes перевіряє справність»

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

МеханізмНайкраще пасуєУмова успіхуПоширений ризик
HTTP GETВебсервіси та API з ендпоінтами справностіHTTP-код статусу від 200 до 399Ендпоінт виконує надто багато роботи або перенаправляє на загальну сторінку входу
TCP-сокетПротоколи, де відкриття порту доводить базову доступністьМожна встановити TCP-з’єднанняПорт відкритий, хоча протокол застосунку нездоровий
ExecКонтейнери з локальною командою справності або файловим сигналомКоманда завершується зі статусом 0Команда повільна, відсутня або споживає забагато ресурсів
gRPCgRPC-сервіси, що реалізують стандартний протокол перевірки справностіgRPC-відповідь про справність — servingСервіс не реалізує очікуваний сервіс справності

HTTP-проби поширені, бо більшість вебзастосунків можуть надавати дешеві ендпоінти справності. Kubernetes трактує коди статусу від 200 до 399 як успіх. Будь-який інший код статусу, таймаут, проблема з DNS або відмова з’єднання зараховується як невдала проба. Заголовки можна постачати, коли ендпоінт вимагає певного хоста або спеціального маркера, але перевірки справності не мають вимагати автентифікації користувача.

livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Probe
value: kubelet
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 2

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

TCP-сокет-проба лише перевіряє, чи здатен kubelet відкрити TCP-з’єднання до порту контейнера. Це корисно для сервісів, які не спілкуються через HTTP, як-от Redis, MySQL або власні бінарні протоколи. Це також слабше за перевірку рівня застосунку, бо процес може приймати TCP-з’єднання, водночас відмовляючи на кожній реальній команді після з’єднання.

livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 2

Використовуйте TCP-проби, коли прийняття з’єднання — найкращий дешевий доступний сигнал. Наприклад, екзаменаційне запитання може просити liveness-перевірку Redis, і TCP-пробу на порту 6379 швидко написати та зазвичай прийнятно. У виробничому розгортанні Redis ви могли б віддати перевагу exec-пробі, що запускає redis-cli ping, якщо образ містить цей інструмент і команда надійна.

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

livenessProbe:
exec:
command:
- sh
- -c
- test -f /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2

Потужність exec-проб супроводжується накладними витратами та прив’язкою до образу. Команда має існувати в образі контейнера, виконуватися швидко та поводитися узгоджено під навантаженням. Якщо мінімальний образ не містить sh, cat, curl чи клієнта бази даних, проба відмовлятиме, навіть якщо застосунок справний. Цей режим відмови поширений у практиці до екзамену, бо учні копіюють exec-команду в образ, який не містить потрібного бінарного файлу.

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

livenessProbe:
grpc:
port: 50051
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 2

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


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

Розділ «Параметри таймінгу: швидке відновлення без хибних спрацювань»

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

ПараметрЗначенняУсталеноПрактична порада
initialDelaySecondsЗатримка перед першою пробою після запуску контейнера0Корисно без startup-проб, але уникайте використання як довгострокового обхідного шляху для запуску
periodSecondsЧас між спробами проби10Коротші періоди швидше виявляють відмови, але збільшують навантаження від проб
timeoutSecondsЧас, відведений на одну спробу проби1Збільшуйте, коли ендпоінт справності валідний, але передбачувано повільніший за одну секунду
successThresholdПослідовні успіхи, потрібні після відмови1Для readiness значення понад одиницю можуть запобігти швидкому миготінню ендпоінтів
failureThresholdПослідовні відмови, потрібні перед дією3Вищі значення зменшують хибні спрацювання, але відкладають перезапуск чи прибирання ендпоінта

Приблизний час дії при відмові дорівнює initialDelaySeconds + (failureThreshold * periodSeconds), без урахування деталей таймауту та відхилень у плануванні. Наприклад, liveness-проба з initialDelaySeconds: 10, periodSeconds: 10 та failureThreshold: 3 зазвичай перезапустить контейнер приблизно за сорок секунд, якщо кожна проба відмовляє. Це досить довго, щоб не вбити під час короткої заминки, але досить коротко, щоб відновитися після реального застряглого процесу.

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

┌──────────────────────────────────────────────────────────────────────────────┐
│ Probe Timing Timeline │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ container starts │
│ │ │
│ ├── initialDelaySeconds │
│ │ │
│ ├── probe attempt 1 fails │
│ │ wait periodSeconds │
│ ├── probe attempt 2 fails │
│ │ wait periodSeconds │
│ ├── probe attempt 3 fails │
│ │ │
│ └── failureThreshold reached, so Kubernetes performs probe action │
│ │
│ For liveness: restart container. For readiness: remove endpoint. │
│ For startup: restart container because startup never completed. │
│ │
└──────────────────────────────────────────────────────────────────────────────┘

Розбір прикладу: розберіть арифметику, перш ніж редагувати YAML

Java API стартує за тридцять п’ять секунд на прогрітій ноді й до дев’яноста секунд на холодній ноді. Команда налаштувала liveness-пробу без startup-проби, з initialDelaySeconds: 15, periodSeconds: 10 та failureThreshold: 3. Вікно першої відмови закінчується приблизно на сорок п’ятій секунді, що означає, що холодні старти можуть бути вбиті до завершення. Кращий дизайн — startup-проба з periodSeconds: 5 та failureThreshold: 24, що дає приблизно дві хвилини на запуск, а потім liveness-проба зі звичайним таймінгом усталеного стану.

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


Проєктування ендпоінтів проб

Розділ «Проєктування ендпоінтів проб»

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

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

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

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

┌──────────────────────────────────────────────────────────────────────────────┐
│ Endpoint Design Boundary │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ /livez │
│ - checks local process progress │
│ - avoids broad downstream dependency checks │
│ - failure means restart could help │
│ │
│ /readyz │
│ - checks whether requests can be served now │
│ - may include critical dependencies with strict timeouts │
│ - failure means remove from Service traffic │
│ │
│ /startupz │
│ - checks whether boot has completed enough for normal probes │
│ - protects slow initialization without weakening steady-state liveness │
│ - failure means keep waiting until startup budget is exhausted │
│ │
└──────────────────────────────────────────────────────────────────────────────┘

Поширений вибір дизайну рівня senior — розділити /livez та /readyz, навіть коли вони спочатку повертають той самий результат. Розділення дає застосунку простір для розвитку без зміни семантики Kubernetes згодом. Якщо команда пізніше додасть readiness-перевірку бази даних, вона може оновити /readyz, не спричиняючи випадково перезапусків через liveness під час інциденту з базою даних.


Розбір прикладу: виправлення циклу перезапусків, спричиненого liveness

Розділ «Розбір прикладу: виправлення циклу перезапусків, спричиненого liveness»

У цьому сценарії учень успадковує Под, який постійно перезапускається. Образ контейнера справний, але liveness-проба вказує на відсутній шлях. Под досягає Running, kubelet перевіряє /not-here, отримує невдалий HTTP-статус і перезапускає контейнер після досягнення порогу.

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

Terminal window
kubectl apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: broken-liveness
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /not-here
port: 80
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 2
EOF

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

Terminal window
sleep 20
k get pod broken-liveness
k describe pod broken-liveness

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

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

Terminal window
k delete pod broken-liveness --ignore-not-found=true
k apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: broken-liveness
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
EOF

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

Terminal window
k wait --for=condition=Ready pod/broken-liveness --timeout=60s
sleep 25
k get pod broken-liveness
k describe pod broken-liveness | grep -A 12 Events

Цей розбір прикладу демонструє повний цикл: спостерігайте симптом, пов’яжіть поведінку перезапуску з liveness, прочитайте події kubelet, виправте шлях проби та перевірте з часом. Той самий цикл застосовний до хибних портів, відсутніх exec-команд і таймаутів проб.


Діагностика readiness та ендпоінтів Сервісу

Розділ «Діагностика readiness та ендпоінтів Сервісу»

Проблеми з readiness часто виглядають як мережеві проблеми, бо процес застосунку живий, але Сервіс не має придатних ендпоінтів. Користувачі повідомляють про відмови з’єднання, тоді як k get pods показує Running. Ця невідповідність — сильний сигнал перевірити readiness, мітки та ендпоінти разом.

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

apiVersion: apps/v1
kind: Deployment
metadata:
name: ready-demo
spec:
replicas: 2
selector:
matchLabels:
app: ready-demo
template:
metadata:
labels:
app: ready-demo
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 2
periodSeconds: 5
failureThreshold: 2
---
apiVersion: v1
kind: Service
metadata:
name: ready-demo
spec:
selector:
app: ready-demo
ports:
- port: 80
targetPort: 80

Застосуйте це й перевірте всі рівні. Розгортання Деплойменту повідомляє, чи бачить Kubernetes бажані репліки як доступні. Список Подів повідомляє про readiness на рівні Пода. Список ендпоінтів повідомляє, чи має Сервіс маршрутизовані бекенд-IP.

Terminal window
k apply -f ready-demo.yaml
k rollout status deployment/ready-demo --timeout=90s
k get pods -l app=ready-demo
k get endpoints ready-demo

Коли readiness зламана, використовуйте той самий трирівневий підхід. Якщо Поди в стані Running, але не Ready, інспектуйте k describe pod. Якщо Поди в стані Ready, але ендпоінти відсутні, інспектуйте селектори Сервісу та мітки Пода. Якщо ендпоінти існують, але трафік усе одно відмовляє, переходьте до портів Сервісу, NetworkPolicy, поведінки застосунку чи мережі на рівні ноди.

Terminal window
k describe pod -l app=ready-demo
k get svc ready-demo -o yaml
k get pods -l app=ready-demo --show-labels

Ця відмінність важлива під тиском екзамену, бо не кожна проблема «Сервіс не має ендпоінтів» є проблемою проби. Погана readiness-проба прибирає ендпоінти. Поганий селектор також прибирає ендпоінти. Добрий діагност перевіряє обидва, перш ніж змінювати маніфести.


Вибір правильного механізму проби

Розділ «Вибір правильного механізму проби»

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

Для вебзастосунку HTTP-проби зазвичай дають найчіткіший сигнал. Використовуйте /livez для справності локального процесу та /readyz для готовності до трафіку. Для Redis або іншого TCP-сервісу TCP-проба може бути прийнятною для liveness, але exec-проба з командою протоколу може бути сильнішою, якщо образ містить цей інструмент. Для gRPC-сервісів віддавайте перевагу gRPC-пробам, коли застосунок реалізує протокол справності. Для мінімальних образів уникайте exec-проб, що припускають наявність утиліт оболонки.

СценарійРекомендована пробаЧому цей вибір пасуєНа що зважати
HTTP API з виділеними маршрутами справностіHTTP liveness та readinessЧіткий сигнал рівня застосунку з низькими накладними витратамиНе робіть liveness залежною від кожного сервісу нижчого рівня
Контейнер Redis в екзаменаційному завданніTCP liveness на порту 6379Швидко написати та підтверджує доступність слухачаУспіх TCP не доводить, що команди Redis працюють
Образ PostgreSQL із доступним pg_isreadyExec readiness або liveness залежно від метиПеревірка з усвідомленням протоколу зсередини контейнераВідсутній бінарний файл або повільна команда спричиняють хибні відмови
gRPC-сервіс із реалізованим протоколом справностіgRPC-пробаУникає зайвих бінарних файлів і перевіряє нативний статус справностіЗастосунок має надавати стандартний сервіс справності
Повільний застарілий Java-сервісStartup плюс HTTP liveness та readinessВідділяє бюджет завантаження від відновлення в усталеному станіНе замінюйте startup-пробу величезною затримкою liveness

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


Патерн 1: вебзастосунок з окремими ендпоінтами життєвого циклу

Розділ «Патерн 1: вебзастосунок з окремими ендпоінтами життєвого циклу»

Цей патерн — найбезпечніший усталений варіант для виробничих вебзастосунків. Startup-проба захищає ініціалізацію, liveness-проба перевіряє базову справність процесу, а readiness-проба вирішує, чи має текти трафік. Ендпоінти окремі, бо їхні значення окремі.

apiVersion: v1
kind: Pod
metadata:
name: webapp-probes
labels:
app: webapp-probes
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /
port: 80
failureThreshold: 24
periodSeconds: 5
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /
port: 80
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 2

У реальному застосунку / зазвичай став би /startupz, /livez та /readyz. Образ nginx використано тут, бо він дає вам придатний до запуску маніфест у будь-якому стандартному практичному кластері Kubernetes. Урок — це структура життєвого циклу, а не те, що кожен виробничий сервіс має використовувати /.

Патерн 2: гейт readiness для трафіку під час прогріву

Розділ «Патерн 2: гейт readiness для трафіку під час прогріву»

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

readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
successThreshold: 2
failureThreshold: 2

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

Патерн 3: exec-проба для локального файлу справності

Розділ «Патерн 3: exec-проба для локального файлу справності»

Перевірка локального файлу корисна для навчання exec-проб, бо її легко спостерігати та ламати. Застосунок створює /tmp/healthy під час запуску, а liveness-проба перезапускає контейнер, якщо цей файл зникає. Це не універсальний виробничий патерн, але він чітко демонструє правило успіху exec.

apiVersion: v1
kind: Pod
metadata:
name: exec-health-file
spec:
containers:
- name: app
image: busybox:1.36
command:
- sh
- -c
- touch /tmp/healthy && sleep 3600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 2

Якщо ви видалите файл командою k exec exec-health-file -- rm /tmp/healthy, наступна послідовність невдалих проб перезапустить контейнер. Після перезапуску команда запуску повторно створює файл, тож Под знову стає справним. Це компактний спосіб побачити зв’язок між відмовою проби, перезапуском контейнера та ініціалізацією застосунку.

Патерн 4: TCP-проба для не-HTTP-слухача

Розділ «Патерн 4: TCP-проба для не-HTTP-слухача»

TCP-проба працює, коли корисний сигнал справності сервісу — це «чи приймає порт з’єднання?». Це поширено в екзаменаційних завданнях для Redis або простих TCP-демонів. Вона менш виразна за специфічну для протоколу команду, але це валідна конфігурація Kubernetes і часто очікувана відповідь.

apiVersion: v1
kind: Pod
metadata:
name: redis-tcp-probe
spec:
containers:
- name: redis
image: redis:7
ports:
- containerPort: 6379
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3

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


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

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

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

Почніть із генерації маніфесту, коли це можливо. Імперативні команди не розкривають кожну опцію проби чисто, тож використовуйте вивід dry-run як відправну точку та редагуйте YAML.

Terminal window
k run webapp --image=nginx:1.27 --port=80 --dry-run=client -o yaml > pod.yaml

Відкрийте pod.yaml, додайте блок проби під контейнером і застосуйте його. Будьте уважні з відступами: проби — це поля контейнера, а не поля специфікації Пода і не поля під ports.

Terminal window
k apply -f pod.yaml
k describe pod webapp | grep -E "Liveness|Readiness|Startup"
k get pod webapp

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

Terminal window
k get endpoints
k get endpoints webapp
k describe pod webapp | grep -A 20 Events

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

Terminal window
sleep 35
k get pod webapp
k describe pod webapp | grep -A 20 Events

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

  • Відмови readiness не перезапускають контейнери: вони змінюють членство в ендпоінтах Сервісу, тому Под може мати нуль перезапусків, водночас не отримуючи жодного трафіку.

  • Exec-проби виконуються всередині образу контейнера: якщо образ не містить команди, яку ви налаштували, проба відмовляє, навіть коли процес застосунку справний.

  • Перенаправлення HTTP-проби можуть зараховуватися як успіх: Kubernetes трактує HTTP-коди статусу від 200 до 399 як успішні, тож ендпоінт справності, що перенаправляє, може приховати погано спроєктовану перевірку.


ПомилкаЧому це шкодитьКраща практика
Використання тієї самої глибокої перевірки залежності для liveness і readinessВідмова бази даних або стороннього сервісу може спричинити перезапуски, які не виправляють залежність і можуть погіршити відновленняТримайте liveness зосередженою на справності локального процесу та кладіть критичні для трафіку залежності в readiness зі щільними таймаутами
Надто агресивна liveness під час запускуПовільні, але справні контейнери вбиваються до завершення завантаження, створюючи цикли перезапусківВикористовуйте startup-пробу для повільного запуску, потім тримайте liveness налаштованою на відновлення в усталеному стані
Забування, що readiness керує ендпоінтами СервісуДіагностика зосереджується на лічильнику перезапусків, тоді як трафік відмовляє, бо Под не вважається готовимПеревіряйте READY, події Пода, селектори Сервісу та k get endpoints разом
Припущення, що успіх TCP означає успіх застосункуПорт може приймати з’єднання, тоді як обробник протоколу чи бізнес-логіка зламаніВикористовуйте HTTP-, exec- чи gRPC-проби, коли вам потрібен сигнал рівня застосунку
Налаштування exec-проби з відсутніми інструментамиМінімальним образам часто бракує sh, cat, curl, клієнтів бази даних чи власних бінарних файлівПереконайтеся, що команда існує в образі, або оберіть мережеву пробу, що відповідає застосунку
Залишення timeoutSeconds на одній секунді для повільних перевірокЛегітимні перевірки справності відмовляють під навантаженням, спричиняючи миготіння ендпоінтів або перезапускиЗробіть перевірки справності дешевими, потім встановіть значення таймауту на основі спостереженої поведінки відповіді
Розміщення полів проби на хибному рівні YAMLМаніфест може бути відхилений, або проба може не приєднатися до потрібного контейнераРозміщуйте startupProbe, livenessProbe та readinessProbe під конкретним записом контейнера
Сприйняття startup-проб як постійних перевірок справностіКоманди неправильно розуміють, чому liveness і readiness не виконуються під час запуску, а потім пропускають поведінку після запускуПам’ятайте, що startup стримує звичайні проби лише доти, доки не пройде для цього екземпляра контейнера

  1. Ваша команда розгортає Java API, який стартує приблизно за двадцять секунд на прогрітих нодах, але інколи займає дві хвилини після завантаження образу ноди. Поточна liveness-проба стартує через тридцять секунд і вбиває контейнер після трьох невдалих перевірок. Під час розгортання нові Поди постійно перезапускаються, перш ніж стати готовими. Який дизайн проб ви б застосували і як обґрунтували б його?

    Відповідь

    Додайте startup-пробу, що дає застосунку достатньо часу для випадку повільного запуску, потім тримайте liveness налаштованою на відмови в усталеному стані. Наприклад, startup-проба з periodSeconds: 5 та failureThreshold: 30 дає близько двох з половиною хвилин на запуск, перш ніж Kubernetes перезапустить контейнер. Liveness і readiness мають починатися лише після успішного завершення запуску. Це краще, ніж збільшувати initialDelaySeconds liveness до дуже великого значення, бо відділяє толерантність до часу завантаження від звичайного виявлення відмов після того, як застосунок працює.

  2. Сервіс періодично не має ендпоінтів, але всі обрані Поди показують Running, а лічильники перезапусків лишаються на нулі. Користувачі бачать відмови з’єднання під час цих вікон. Які об’єкти Kubernetes і поведінку проб слід дослідити першими, і яку відмову ви б очікували знайти?

    Відповідь

    Дослідіть статус readiness Подів, події Подів, селектори Сервісу, мітки Подів і k get endpoints <service-name>. Нуль перезапусків робить відмову liveness менш імовірною, тоді як зникнення ендпоінтів вказує на відмову readiness або невідповідність селектора. Якщо мітки та селектор збігаються, очікуйте відмов readiness-проби в k describe pod, можливо, спричинених ненадійним readiness-ендпоінтом, перевіркою зовнішньої залежності або порогами, надто агресивними за звичайного навантаження.

  3. Команда використовує /healthz і для liveness, і для readiness. Ендпоінт перевіряє базу даних, чергу повідомлень і сторонній API виставлення рахунків. Коли API виставлення рахунків сповільнюється, Kubernetes перезапускає кожен Под застосунку. Як би ви переспроєктували проби, щоб зменшити радіус ураження?

    Відповідь

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

  4. Вас просять додати liveness-пробу до Пода Redis під час екзамену. Вимога каже, що проба має перевіряти, що порт 6379 приймає з’єднання, і HTTP-ендпоінта не існує. Який механізм проби слід використати і яке обмеження слід тримати на думці?

    Відповідь

    Використайте TCP-сокет liveness-пробу на порту 6379. Вона відповідає заявленій вимозі та валідна для не-HTTP-сервісу. Обмеження в тому, що успіх TCP лише доводить, що порт приймає з’єднання; він не доводить, що Redis може успішно обробляти команди. У виробничих умовах exec-проба з використанням клієнта Redis могла б дати сильніший сигнал, якщо образ містить цей інструмент і команда надійна.

  5. Под використовує exec liveness-пробу з command: ["cat", "/tmp/healthy"]. Вона працює добре в тестовому образі busybox, але відмовляє одразу після того, як команда переходить на distroless-образ застосунку. Логи застосунку не показують помилок запуску. Як би ви діагностували та виправили проблему?

    Відповідь

    Команда проби, найімовірніше, відмовляє, бо distroless-образ не містить cat чи очікуваних утиліт оболонки. Перевірте події Пода через k describe pod, щоб підтвердити відмови exec-проби, і за потреби інспектуйте дизайн образу. Виправте пробу, використавши команду, яка справді існує в образі, додавши невеликий спеціально створений бінарний файл справності або перейшовши на HTTP- чи gRPC-пробу, що надається застосунком. Не припускайте, що інструменти з навчального образу існують у мінімальному виробничому образі.

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

    Відповідь

    Спершу зробіть readiness-перевірку дешевшою, якщо це можливо, бо ендпоінти справності мають бути швидкими та передбачуваними. Потім оцініть timeoutSeconds, failureThreshold, periodSeconds і, можливо, successThreshold для readiness, щоб членство в ендпоінтах не миготіло через одну повільну відповідь. Збільшення реплік може тимчасово приховати симптоми, але не виправляє сигнал readiness. Правильне виправлення — узгодити таймінг readiness із реалістичною поведінкою ендпоінтів, тримаючи перевірку достатньо вузькою, щоб уникнути зайвого навантаження.

  7. Ви успадковуєте маніфест Пода, де livenessProbe має відступ під spec поруч із containers, а не під записом контейнера. Под не застосовується з помилкою, пов’язаною зі схемою. Як би ви виправили маніфест і чому вкладеність важлива операційно?

    Відповідь

    Перемістіть livenessProbe під конкретний запис контейнера, на тому самому рівні відступу, що й поля на кшталт image, ports та readinessProbe. Проби — це конфігурація рівня контейнера, бо кожен контейнер у Поді може мати різну поведінку справності, порти, команди та потреби життєвого циклу. Вкладеність важлива, бо Kubernetes має точно знати, який контейнер kubelet має пробувати та перезапускати, коли liveness відмовляє.


Завдання: налаштувати, перевірити, зламати та полагодити проби для вебзастосунку, щоб ви могли пов’язати поля маніфесту з поведінкою kubelet.

Мета: до кінця цієї вправи ви маєте вміти довести, що startup стримує звичайні проби, liveness перезапускає зламаний контейнер, а readiness керує членством в ендпоінтах Сервісу.

Крок 1: створіть Под зі startup-, liveness- та readiness-пробами

Розділ «Крок 1: створіть Под зі startup-, liveness- та readiness-пробами»

Застосуйте придатний до запуску маніфест Пода, що використовує nginx та HTTP-проби. Шляхи використовують /, бо цей образ обслуговує цей шлях усталено, що дозволяє зосередитися на поведінці проб Kubernetes, а не на коді застосунку.

Terminal window
k apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: probe-demo
labels:
app: probe-demo
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /
port: 80
failureThreshold: 12
periodSeconds: 5
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /
port: 80
periodSeconds: 10
failureThreshold: 3
timeoutSeconds: 2
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
failureThreshold: 2
timeoutSeconds: 2
EOF

Крок 2: перевірте Под і конфігурацію проб

Розділ «Крок 2: перевірте Под і конфігурацію проб»

Використайте wait, get та describe, щоб перевірити і високорівневий статус, і фактичні поля проб, приєднані до контейнера.

Terminal window
k wait --for=condition=Ready pod/probe-demo --timeout=90s
k get pod probe-demo
k describe pod probe-demo | grep -E "Startup|Liveness|Readiness"

Критерії успіху: k wait --for=condition=Ready pod/probe-demo --timeout=90s має успішно виконатися, k get pod probe-demo має показувати Под запущеним і готовим, а k describe pod probe-demo має підтвердити конфігурацію startup-, liveness- та readiness-проб на контейнері app.

  • k wait повідомляє, що pod/probe-demo досяг умови Ready в межах таймауту.
  • k get pod probe-demo показує Под у статусі Running з готовим контейнером.
  • k describe pod probe-demo показує конфігурацію startup-, liveness- та readiness-проб для контейнера app.

Крок 3: відкрийте Под і підтвердьте, що readiness керує ендпоінтами

Розділ «Крок 3: відкрийте Под і підтвердьте, що readiness керує ендпоінтами»

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

Terminal window
k expose pod probe-demo --port=80 --target-port=80
k get svc probe-demo
k get endpoints probe-demo

Критерії успіху: після створення Сервісу підтвердьте, що для probe-demo з’являється принаймні один ендпоінт, і поясніть, як зміна readiness може прибрати цей ендпоінт, не спричиняючи перезапуску.

  • k get svc probe-demo показує Сервіс з іменем probe-demo.
  • k get endpoints probe-demo показує принаймні одну адресу та порт ендпоінта для Пода.
  • Ви можете пояснити, чому readiness-проба, що відмовляє, прибрала б цей ендпоінт, не збільшуючи лічильник перезапусків.

Крок 4: зламайте сигнал liveness-проби та спостерігайте поведінку перезапуску

Розділ «Крок 4: зламайте сигнал liveness-проби та спостерігайте поведінку перезапуску»

Видаліть усталений файл індексу nginx, щоб шлях / більше не повертав ту саму успішну відповідь. Потім зачекайте достатньо довго, щоб liveness-проба відмовила згідно з налаштованим періодом і порогом.

Terminal window
k exec probe-demo -- rm /usr/share/nginx/html/index.html
sleep 40
k get pod probe-demo
k describe pod probe-demo | grep -A 20 Events

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

  • Потік подій Пода показує повідомлення про невдалу liveness-пробу або перезапуск контейнера, пов’язаний із відмовою проби.
  • k get pod probe-demo показує, що лічильник перезапусків змінився після відмов liveness.
  • Ви можете пояснити, чому Kubernetes перезапустив контейнер, а не просто прибрав Под з ендпоінтів Сервісу.

Крок 5: полагодьте сигнал застосунку та перевірте стабільність

Розділ «Крок 5: полагодьте сигнал застосунку та перевірте стабільність»

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

Terminal window
k wait --for=condition=Ready pod/probe-demo --timeout=90s
sleep 15
k get pod probe-demo
k get endpoints probe-demo

Критерії успіху: після того як перезапуск завершиться, Под має повернутися до Ready, а ендпоінти мають з’явитися знову, причому лічильники перезапусків відповідатимуть спостереженому шляху відновлення.

  • Под повертається до Ready після перезапуску.
  • Ендпоінт Сервісу існує знову після успіху readiness.
  • Лічильник перезапусків лишається стабільним протягом фінального вікна спостереження.

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

Terminal window
k delete svc probe-demo --ignore-not-found=true
k delete pod probe-demo --ignore-not-found=true

Критерії успіху: видаліть Сервіс і Под та переконайтеся, що простір імен чистий для наступної тренувальної вправи, водночас підтвердивши, що не було видалено непов’язаних ресурсів.

  • k get pod probe-demo більше не повертає практичний Под.
  • k get svc probe-demo більше не повертає практичний Сервіс.
  • Жодних непов’язаних ресурсів не було видалено під час прибирання.

Тренувальні вправи

Розділ «Тренувальні вправи»

Вправа 1: HTTP liveness-проба

Розділ «Вправа 1: HTTP liveness-проба»

Створіть Под з іменем drill-http-live, що запускає nginx:1.27 з HTTP liveness-пробою на / на порту 80. Проба має чекати п’ять секунд перед першою перевіркою та виконуватися кожні десять секунд.

Розв'язок
Terminal window
k apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: drill-http-live
spec:
containers:
- name: nginx
image: nginx:1.27
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
EOF
k describe pod drill-http-live | grep Liveness
k delete pod drill-http-live --ignore-not-found=true

Вправа 2: exec liveness-проба

Розділ «Вправа 2: exec liveness-проба»

Створіть Под з іменем drill-exec-live, що використовує busybox:1.36. Контейнер має створити /tmp/healthy, а потім спати. Налаштуйте exec liveness-пробу, що перевіряє цей файл.

Розв'язок
Terminal window
k apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: drill-exec-live
spec:
containers:
- name: app
image: busybox:1.36
command:
- sh
- -c
- touch /tmp/healthy && sleep 3600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
EOF
k describe pod drill-exec-live | grep Liveness
k delete pod drill-exec-live --ignore-not-found=true

Вправа 3: TCP liveness-проба

Розділ «Вправа 3: TCP liveness-проба»

Створіть Под з іменем drill-tcp-live, що запускає redis:7 з TCP liveness-пробою на порту 6379. Проба має чекати десять секунд перед першою перевіркою та виконуватися кожні п’ять секунд.

Розв'язок
Terminal window
k apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: drill-tcp-live
spec:
containers:
- name: redis
image: redis:7
ports:
- containerPort: 6379
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 10
periodSeconds: 5
EOF
k describe pod drill-tcp-live | grep Liveness
k delete pod drill-tcp-live --ignore-not-found=true

Вправа 4: readiness-проба з перевіркою Сервісу

Розділ «Вправа 4: readiness-проба з перевіркою Сервісу»

Створіть Деплоймент з іменем drill-ready з двома репліками nginx:1.27 та HTTP readiness-пробою на /. Відкрийте його через Сервіс і переконайтеся, що обидві репліки з’являються як ендпоінти.

Розв'язок
Terminal window
k apply -f - << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: drill-ready
spec:
replicas: 2
selector:
matchLabels:
app: drill-ready
template:
metadata:
labels:
app: drill-ready
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 2
periodSeconds: 3
EOF
k expose deployment drill-ready --port=80 --target-port=80
k rollout status deployment/drill-ready --timeout=90s
k get endpoints drill-ready
k delete service drill-ready --ignore-not-found=true
k delete deployment drill-ready --ignore-not-found=true

Вправа 5: startup-проба для повільної ініціалізації

Розділ «Вправа 5: startup-проба для повільної ініціалізації»

Створіть Под з іменем drill-startup, що спить двадцять секунд перед запуском nginx. Налаштуйте startup-пробу, що дає достатньо часу для відкладеного запуску, потім додайте liveness- та readiness-проби для усталеного стану.

Розв'язок
Terminal window
k apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: drill-startup
spec:
containers:
- name: app
image: nginx:1.27
command:
- sh
- -c
- sleep 20 && nginx -g 'daemon off;'
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
failureThreshold: 8
livenessProbe:
httpGet:
path: /
port: 80
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
failureThreshold: 2
EOF
k wait --for=condition=Ready pod/drill-startup --timeout=90s
k describe pod drill-startup | grep -E "Startup|Liveness|Readiness"
k delete pod drill-startup --ignore-not-found=true

Вправа 6: діагностика зламаного шляху проби

Розділ «Вправа 6: діагностика зламаного шляху проби»

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

Розв'язок
Terminal window
k apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: drill-broken-path
spec:
containers:
- name: app
image: nginx:1.27
livenessProbe:
httpGet:
path: /missing
port: 80
initialDelaySeconds: 5
periodSeconds: 3
failureThreshold: 2
EOF
sleep 20
k get pod drill-broken-path
k describe pod drill-broken-path | grep -A 20 Events
k delete pod drill-broken-path --ignore-not-found=true
k apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: drill-broken-path
spec:
containers:
- name: app
image: nginx:1.27
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
EOF
k wait --for=condition=Ready pod/drill-broken-path --timeout=60s
k get pod drill-broken-path
k delete pod drill-broken-path --ignore-not-found=true

Вправа 7: відрізнення проблем селектора від проблем readiness

Розділ «Вправа 7: відрізнення проблем селектора від проблем readiness»

Створіть Деплоймент з валідною readiness-пробою, потім створіть Сервіс із хибним селектором. Використайте ендпоінти та мітки, щоб довести, що проблема не в пробі.

Розв'язок
Terminal window
k apply -f - << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: drill-selector
spec:
replicas: 1
selector:
matchLabels:
app: drill-selector
template:
metadata:
labels:
app: drill-selector
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: drill-selector
spec:
selector:
app: wrong-label
ports:
- port: 80
targetPort: 80
EOF
k rollout status deployment/drill-selector --timeout=90s
k get pods -l app=drill-selector --show-labels
k get endpoints drill-selector
k get service drill-selector -o yaml
k delete service drill-selector --ignore-not-found=true
k delete deployment drill-selector --ignore-not-found=true

Контрольний список огляду рівня senior

Розділ «Контрольний список огляду рівня senior»

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

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

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


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