Що таке readiness probe
На відміну від Liveness Probe, Readiness Probe НІКОЛИ не вбиває і не перезапускає контейнер:
🟢 Junior Level
30-секундна відповідь
Readiness Probe (Проба готовності) — це діагностичний механізм Kubernetes, за допомогою якого агент kubelet безперервно перевіряє, чи готовий застосунок усередині пода приймати та обробляти вхідний мережевий трафік від користувачів.
На відміну від Liveness Probe, Readiness Probe НІКОЛИ не вбиває і не перезапускає контейнер:
- Якщо проба готовності провалилася, Kubernetes виконує лише одну дію: тимчасово виключає IP-адресу цього пода з балансування сервісу (
Endpoints/EndpointSlice). - Користувацький трафік припиняє надходити на проблемний под і перенаправляється на сусідні здорові репліки.
- Щойно застосунок прогріється або звільнить внутрішні черги, проба знову стане успішною, і Kubernetes автоматично поверне под назад у балансування.
Наочна аналогія з життя
Readiness Probe — це табличка «ПЕРЕРВА 10 ХВИЛИН» на касі супермаркету:
- Касир живий, здоровий і не звільнений (контейнер не перезапускається).
- Але просто зараз касир змінює касову стрічку або перераховує готівку (прогрів кешу, підключення до БД).
- Черга покупців спрямовується до сусідніх працюючих кас (трафік іде на інші поди).
- Щойно касир готовий, табличка прибирається, і каса знову приймає покупців.
Базовий маніфест для Spring Boot 3
apiVersion: v1
kind: Pod
metadata:
name: order-service
spec:
containers:
- name: order-app
image: order-service:1.0
readinessProbe:
httpGet:
path: /actuator/health/readiness # Ендпоінт готовності Spring Boot Actuator
port: 8080
initialDelaySeconds: 15 # Пауза перед першою перевіркою
periodSeconds: 5 # Перевіряти кожні 5 секунд
failureThreshold: 2 # Виключити з трафіку після 2 невдач поспіль
successThreshold: 1 # Повернути в трафік після 1 першого успіху
У виводі kubectl get pods статус готовності видно у стовпчику READY:
1/1 Running— под готовий і приймає трафік.0/1 Running— процес запущений, але трафік на нього НЕ йде (провал readiness probe).
🟡 Middle Level
Роль Readiness Probe у Rolling Update (Zero Downtime)
Без налаштування Readiness Probe забезпечити розгортання без простою (Zero Downtime Deployment) неможливо:
- Ви викочуєте нову версію
v2. - Контейнер запустився в Linux, процес Java отримав PID, і Kubernetes бачить статус
Running. - Якщо проби готовності немає, Kubernetes з першої ж секунди починає надсилати запити користувачів на новий под, хоча JVM ще навіть не завантажила Spring ApplicationContext!
- Користувачі отримують потік помилок
502 Bad GatewayтаConnection Refused. - З Readiness Probe: Kubernetes чекає, поки под поверне
HTTP 200на/actuator/health/readiness, і лише після цього плавно перемикає трафік зі старої версії на нову.
Фундаментальні відмінності: Liveness vs Readiness
+─────────────────────────────────+
| ПРОБА ВПАЛА |
+────────────────┬────────────────+
│
┌──────────────────────────┴──────────────────────────┐
▼ ▼
[ Liveness Probe ] [ Readiness Probe ]
- Жорстка дія - М'яка дія
- 🔴 ПЕРЕЗАПУСК КОНТЕЙНЕРА - 🟡 ВІДКЛЮЧЕННЯ МЕРЕЖЕВОГО ТРАФІКУ
- Для зняття дедлоків та зависань - Для прогріву та захисту від перевантаження
| Характеристика | Liveness Probe | Readiness Probe |
|---|---|---|
| Реакція на помилку | Примусовий перезапуск контейнера (kill) |
Видалення IP з Endpoints (ізоляція від трафіку) |
| Життєвий цикл пода | Контейнер рестартує, пам’ять очищується | Под продовжує працювати й виконувати фонові завдання |
| Що перевіряти | Внутрішній життєвий цикл процесу (Deadlock) | Готовність пулів з’єднань, кешів, черг |
| Вплив на деплой | Не впливає на перемикання версій | Блокує Rolling Update до повної готовності |
Spring Boot 3 ReadinessState у коді
Spring Boot 3 автоматично керує компонентом ReadinessState:
ReadinessState.ACCEPTING_TRAFFIC: контекст піднятий, усі біни ініціалізовані, ліквідність пулів підтверджена. Actuator повертаєHTTP 200 OK.ReadinessState.REFUSING_TRAFFIC: сервіс тимчасово не готовий. Actuator повертаєHTTP 503 Service Unavailable.
Розробник може тимчасово зняти под із балансування на час фонової операції (наприклад, прогріву локального кешу Caffeine):
@Service
public class CacheWarmupService {
private final ApplicationEventPublisher eventPublisher;
public CacheWarmupService(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void reloadLargeDictionary() {
// 1. Тимчасово відключаємо трафік від K8s
AvailabilityChangeEvent.publish(eventPublisher, this, ReadinessState.REFUSING_TRAFFIC);
try {
// 2. Виконуємо важке завантаження даних із БД у пам'ять
loadMillionRecordsIntoCache();
} finally {
// 3. Повертаємо под у балансування
AvailabilityChangeEvent.publish(eventPublisher, this, ReadinessState.ACCEPTING_TRAFFIC);
}
}
}
🔴 Senior Level
Затримка поширення правил та PreStop Hook
Senior-інженер зобов’язаний знати, що видалення пода з балансувальника відбувається асинхронно:
- Kubelet фіксує провал проби й надсилає звіт до
kube-apiserver(~1 сек). - EndpointSlice Controller оновлює об’єкт
EndpointSlice(~1 сек). - Агент
kube-proxyна всіх нодах кластера перераховує правилаiptables/IPVS(~1–3 сек). - Сумарний лаг становить від 2 до 5 секунд! Упродовж цих секунд вхідні пакети від клієнтів усе ще летять у сокет пода.
Архітектурне рішення: тандем Readiness + PreStop Hook
Щоб під час зупинки пода не втратити жодного клієнтського запиту:
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"] # Пауза в 10 секунд перед відправкою SIGTERM
Під час 10-секундного сну Kubelet встигає гарантовано оновити iptables на всіх серверах кластера, трафік припиняє надходити, і лише потім Spring Boot отримує сигнал SIGTERM та починає graceful shutdown.
Readiness Gates (Зовнішні шлюзи готовності)
У сучасних хмарних середовищах (AWS EKS з ALB Ingress Controller або Google Cloud GKE) стандартної перевірки Kubelet недостатньо:
- Kubelet перевірив локальний порт пода і вважає його готовим (
PodReady=True). - Проте зовнішній балансувальник AWS ALB ще не встиг зареєструвати IP пода у своїй цільовій групі (Target Group) та провести власну перевірку здоров’я.
- Трафік, що приходить через Ingress, обривається.
Для розв’язання цієї проблеми використовуються Readiness Gates:
spec:
readinessGates:
- conditionType: "target-health.elbv2.k8s.aws/v2" # Зовнішній прапорець готовності
Под не перейде в статус Ready доти, доки хмарний контролер AWS ALB не підтвердить, що под успішно зареєстрований у зовнішньому балансувальнику навантаження!
Небезпека перевірки БД у Readiness (Каскадна відмова)
Класична пастка на Highload-проєктах:
- Якщо 200 подів перевіряють доступність PostgreSQL у Readiness Probe, то при короткочасній деградації БД (наприклад, блокування таблиці) усі 200 подів одночасно повернуть HTTP 503.
- Kubernetes моментально очистить
Endpointsсервісу до нуля. - Уся система вмить ляже з помилкою
503 Service Temporarily Unavailableдля 100% користувачів. Best Practice: У Readiness Probe перевіряються лише локальні критичні ресурси (вільна пам’ять, стан пулу потоків Tomcat). Для баз даних використовується Circuit Breaker (Resilience4j): якщо база гальмує, под залишається в балансуванні та віддає користувачеві закешовані дані або зрозумілий Fallback.
4 Tricky Questions
1. Чому для забезпечення 100% Zero-Downtime при Rolling Update однієї readinessProbe недостатньо, і обов’язково потрібен preStop hook із командою sleep?
Відповідь: Події видалення пода та оновлення мережевих правил відбуваються в Kubernetes паралельно і незалежно:
- При видаленні пода Kubelet негайно надсилає процесу контейнера сигнал
SIGTERM, і Spring Boot починає зупиняти контекст і закривати сокети. - Одночасно з цим
kube-apiserverнадсилає подію про видалення пода контролеруEndpointSlice, який передає команду агентамkube-proxyна десятках нод переписати правилаiptables. - Оновлення мережевих таблиць
iptablesзаймає від 1 до 4 секунд. - У цей проміжок часу клієнти продовжують надсилати запити на вмираючий под, чиї порти вже закриті процесом Spring Boot, унаслідок чого користувачі отримують помилки
Connection Refused. - Додавання
preStop: exec: command: ["sh", "-c", "sleep 10"]штучно затримує відправкуSIGTERMна 10 секунд, гарантуючи, що правилаiptablesвстигнуть оновитися на всіх нодах і трафік припиниться ДО того, як процес почне завершуватися.
2. Що станеться з мережевим трафіком та станом пода, якщо readinessProbe повертає помилку (HTTP 500), а livenessProbe у цей же момент повертає успіх (HTTP 200)?
Відповідь:
- Стан контейнера: контейнер НЕ буде перезапущений, він продовжить спокійно працювати в пам’яті. У виводі
kubectl get podsстатус залишитьсяRunning, але лічильник готовності зміниться на0/1 READY. - Мережевий трафік: контролер Kubernetes виключить IP-адресу цього пода зі списків
EndpointsтаEndpointSliceусіх асоційованих сервісів. - Результат: жоден зовнішній запит через
ClusterIP,NodePortчиIngressбільше не надійде на цей контейнер. Проте сам контейнер збереже можливість надсилати вихідні запити в зовнішні системи та продовжувати обробку внутрішніх фонових черг.
3. Для чого використовується параметр successThreshold у конфігурації readinessProbe, і чому за замовчуванням він дорівнює 1?
Відповідь:
successThresholdвизначає кількість послідовних успішних перевірок поспіль, які повинен повернути застосунок, перш ніж Kubernetes вважатиме под готовим і поверне його IP-адресу в балансування трафіку.- Значення за замовчуванням дорівнює
1, щоб мінімізувати затримку введення нового прогрітого пода в експлуатацію. - Проте при нестабільних навантаженнях або хвилеподібному прогріві (коли сервіс короткочасно відповідає успіхом, а потім знову просідає) збільшення
successThreshold: 2або3захищає сервіс від передчасної подачі користувацького трафіку на інстанс, який ще не до кінця стабілізувався.
4. Чи впливає провал readinessProbe на роботу механізму Headless Service (clusterIP: None)?
Відповідь:
Так, безпосередньо впливає.
Для Headless Service DNS-сервер CoreDNS формує A-записи на основі списку адрес в об’єкті Endpoints.
Якщо под провалює readinessProbe:
- Його IP-адреса видаляється із секції
subsets.addressesі переміщується в секціюsubsets.notReadyAddresses. - CoreDNS припиняє повертати IP-адресу цього пода у стандартних DNS-запитах.
- Проте якщо в специфікації Headless Service явно активовано прапорець
publishNotReadyAddresses: true, CoreDNS продовжить віддавати IP-адресу не готового пода (це використовується спеціалізованими кластерними системами, наприклад, для реплікації логів у кластері Elasticsearch або etcd до того, як нода стане готова обслуговувати клієнтські запити).
🎯 Шпаргалка для інтерв’ю
Головне про Readiness Probe
- Призначення: перевірка готовності приймати мережевий трафік користувачів.
- Дія при збої: видалення IP з
Endpoints/EndpointSlice; контейнер НЕ перезапускається! - Zero Downtime: блокує перемикання трафіку під час Rolling Update до повної готовності нової версії.
- Зв’язка з PreStop: зв’язка
readinessProbe+preStop: sleep 10запобігає втраті запитів через лаг оновленняiptables(2–4 сек). - Spring Boot 3 Actuator: стандартний ендпоінт
/actuator/health/readiness(ReadinessState). - Readiness Gates: очікування перевірки готовності зовнішніми хмарними балансувальниками (AWS ALB Target Group).
- Anti-Pattern: перевірка спільної БД усіма подами разом (загрожує відключенням 100% подів при збої БД).
Зведена таблиця поведінки перевірок
| Перевірка | Дія при відмові | Впливає на статус READY? | Впливає на роботу процесу? |
| :— | :— | :—: | :—: |
| livenessProbe | Примусовий перезапуск | ❌ Ні | 🔴 Процес вбивається (SIGKILL) |
| readinessProbe| Відключення від сервісу | 🟢 Так (0/1 READY) | 🟢 Процес продовжує працювати |
| startupProbe | Примусовий перезапуск | 🟢 Так (0/1 READY) | 🔴 Процес вбивається при перевищенні таймауту |
Червоні прапорці на співбесіді (Чого говорити не можна)
- ❌ «Якщо readinessProbe падає 3 рази поспіль, Kubernetes перезапускає под» — груба помилка, перезапуском займається лише Liveness/Startup.
- ❌ «Якщо под перейшов у статус Running, значить він вже може приймати трафік без readinessProbe» — статус Running означає лише те, що контейнер створений у Linux, Java може завантажуватися ще 60 секунд.
- ❌ «ReadinessProbe перевіряє тільки зовнішні мережеві порти» — проба може виконувати HTTP GET, TCP socket, gRPC або exec-команди.