Что такое 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 секунд! В течение этих 3 секунд входящие пакеты от клиентов всё ещё летят в сокет пода.
Архитектурное решение: тандем 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-команды.