Что такое Readiness Probe?
Readiness probe -- K8s проверяет, готов ли Pod принимать трафик. Если probe fails -- Pod убирается из Service endpoints, но НЕ перезапускается.
🟢 Junior Level
Простое определение
Readiness Probe (Проба готовности) — это проверка в Kubernetes, которая определяет, готов ли Pod принимать входящий трафик. Если проба провалена — Kubernetes убирает Pod из балансировщика, но не перезапускает его.
Readiness probe – K8s проверяет, готов ли Pod принимать трафик. Если probe fails – Pod убирается из Service endpoints, но НЕ перезапускается.
Аналогия
Представьте магазин. Двери открыты (Pod запущен), но кассир ещё не прошёл инструктаж, кассы не подключены. Менеджер (Readiness Probe) говорит: “Пока не принимай клиентов”. Как только всё готово — двери открываются для покупателей.
Пример YAML
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: my-app:1.0
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
Пример kubectl
# Проверить readiness статуса Pod'а
kubectl get pods
# STATUS: Running (1/1 READY) — готов, Running (0/1 READY) — не готов
kubectl describe pod my-app | grep -A 10 Readiness
Когда использовать
- Приложение требует время на прогрев (загрузка кэша, инициализация БД)
- Во время деплоя, чтобы трафик шёл только на готовые Pod’ы
- Если приложение может временно “отключиться” при перегрузке
🟡 Middle Level
Как это работает
Readiness Probe выполняется kubelet’ом на каждой ноде. kubelet опрашивает указанный эндпоинт с интервалом periodSeconds. При успешном ответе Pod получает статус Ready: True и его IP добавляется в Endpoints (или EndpointSlice) всех сервисов, которые селектят этот Pod. При провале — IP удаляется из Endpoints.
Типы проверок:
httpGet— HTTP GET запрос, ожидает 2xx/3xxtcpSocket— проверка, что TCP-порт открытexec— выполнение команды внутри контейнераgrpc— gRPC health check (с Kubernetes 1.24+)
Практические сценарии
Сценарий 1: Spring Boot с Actuator
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
periodSeconds: 5
failureThreshold: 3
Сценарий 2: Временное отключение при перегрузке
Если очередь задач превысила лимит, приложение может вернуть 503 на /health/ready, чтобы временно снять себя с балансировки и разгрузиться.
Сценарий 3: Rolling Update Kubernetes не начнёт удалять старые Pod’ы, пока новые не пройдут Readiness Probe. Это обеспечивает Zero Downtime.
Таблица распространённых ошибок
| Ошибка | Последствие | Решение |
|---|---|---|
| Проверка БД в Readiness при каскадном сбое | Все Pod’ы отключатся одновременно, 503 для всех | Возвращать Ready, если приложение может работать частично (кэш, fallback) |
| Слишком частый periodSeconds (1 сек) | Лишняя нагрузка на приложение | Ставить 3-10 секунд |
| Отсутствие readinessProbe | Трафик идёт на ещё не готовые Pod’ы, ошибки 502/503 | Всегда добавлять для stateful-приложений |
| Проверка только TCP-порта | Приложение слушает порт, но не обрабатывает запросы | Использовать httpGet с реальным health-эндпоинтом |
Сравнительная таблица: Liveness vs Readiness
| Характеристика | Liveness Probe | Readiness Probe |
|---|---|---|
| Действие при сбое | Перезапуск контейнера | Удаление из Service Endpoints |
| Цель | Обнаружить зависания, deadlocks | Гарантировать, что трафик идёт только на готовые Pod’ы |
| Проверка зависимостей | Не рекомендуется | Рекомендуется (БД, внешние API) |
| Влияние на Rolling Update | Не влияет | Блокирует обновление до готовности |
| startupProbe взаимодействие | Отключается до успеха startupProbe | Отключается до успеха startupProbe |
Failed readiness: Pod убирается из балансировки, но продолжает работать. Failed liveness: Pod перезапускается. Это критическое различие.
Когда НЕ использовать
- Stateless-приложения без прогрева: Если приложение готово мгновенно после старта, Readiness Probe добавляет только задержку
- Фоновые воркеры без входящего трафика: Если Pod не обслуживает HTTP-запросы, Readiness не имеет смысла (хотя может быть полезен для мониторинга)
- Однорепликовые Deployment’ы с maxUnavailable=1: Если единственный Pod отключается от трафика, сервис становится полностью недоступен
Startup probe – отдельный probe для медленных приложений. Пока startup probe не прошёл – liveness и readiness не запускаются. Для Java-приложений с долгим стартом.
🔴 Senior Level
Глубинная механика: kubelet и EndpointSlice
Readiness Probe выполняется kubelet’ом в отдельной goroutine. kubelet поддерживает цикл проверок через probeManager, который хранит состояние каждой пробы в workerqueue. Результаты агрегируются в containerStatus и передаются через CRI (Container Runtime Interface).
Когда kubelet фиксирует изменение статуса Readiness, он обновляет PodStatus в API Server. Далее срабатывает цепочка:
- EndpointSlice Controller (в kube-controller-manager) подписан на изменения Pod’ов
- При изменении
Readyусловия, контроллер пересчитывает EndpointSlice - kube-proxy (через iptables/IPVS) обновляет правила балансировки
- Трафик перестаёт (или начинает) направляться на Pod
Latency цепочки: kubelet detect (~periodSeconds) → API Server write (~10-50ms) → EndpointSlice reconcile (~500ms) → kube-proxy sync (~1s) → трафик переключён. Итого: 2-5 секунд от провала пробы до реального прекращения трафика.
Trade-offs
| Аспект | Trade-off |
|---|---|
| Частота проверок | Частые пробы = быстрее реакция, но выше нагрузка на приложение и API Server |
| Проверка зависимостей | Проверка БД = честный статус, но риск каскадного отказа |
| failureThreshold | Низкий = быстрое отключение, но чувствительность к сетевым флуктуациям. Высокий = стабильнее, но дольше реакция |
| httpGet vs tcpSocket | httpGet точнее, но дороже. tcpSocket быстрее, но не проверяет бизнес-логику |
Edge Cases (5+)
Edge Case 1: Частичная готовность Приложение имеет 10 эндпоинтов. 9 работают, 1 зависит от упавшей БД. Readiness Probe на одном эндпоинте либо “убьёт” весь Pod (если проверяет БД), либо “соврёт” (если не проверяет). Решение: продуманная стратегия health-эндпоинтов с градацией.
Edge Case 2: Терминация Pod при draining ноды
При kubectl drain нода переводится в состояниеcordoned. Pod’ы получают SIGTERM, но Readiness Probe продолжает работать до полной терминации. Если Pod провалит Readiness во время graceful shutdown, трафик переключится. Но если SIGTERM займёт больше terminationGracePeriodSeconds, kubelet отправит SIGKILL.
Edge Case 3: Pod в Pending с Readiness Pod в состоянии Pending (не удалось выделить ресурсы) никогда не начнёт выполнять Readiness Probe — kubelet не запускает пробы, пока контейнер не перейдёт в Running.
Edge Case 4: Race condition при масштабировании HPA
HPA масштабирует Deployment, новые Pod’ы создаются. Если Readiness Probe имеет большой initialDelaySeconds, HPA может решить, что реплик недостаточно, и создать ещё. Это приводит к over-provisioning. Решение: адекватные таймауты + behavior.stabilizationWindowSeconds в HPA.
Edge Case 5: Readiness Gate
Kubernetes 1.14+ поддерживает Readiness Gates — внешние условия, которые должны быть True для PodReady. Например, контроллер Service Mesh может выставить readiness gate только после регистрации Pod в mesh. Это добавляет внешнюю зависимость к стандартной проверке kubelet.
Edge Case 6: Headless Service и Readiness
Для Headless Service (clusterIP: None) удаление Pod из Endpoints влияет на DNS-резольвинг. Клиенты, кеширующие DNS, могут продолжать слать трафик на недоступный Pod до истечения TTL.
Performance Numbers
| Метрика | Значение |
|---|---|
| kubelet probe overhead | ~1-5ms CPU на одну httpGet пробу |
| API Server update latency | 10-100ms при обновлении PodStatus |
| EndpointSlice propagation | 500ms-2s до kube-proxy sync |
| Полное отключение трафика | 2-5 секунд от probe failure до остановки трафика |
| kube-proxy iptables sync | ~1s для 1000 Services, ~5s для 5000 Services |
| kube-proxy IPVS sync | ~100ms для 1000 Services |
Security
- Readiness Probe эндпоинт не должен быть публичным — он должен быть доступен только изнутри кластера
- Если probe использует
httpGet, убедитесь, что он не раскрывает внутреннюю информацию (версии, конфигурацию) - Не используйте
execprobe с привилегированными командами — это потенциальный вектор эскалации - В multi-tenant кластерах: NetworkPolicy должен ограничивать доступ к health эндпоинтам только от kubelet
Production War Story
Ситуация: Крупный e-commerce кластер, Black Friday. Все Pod’ы имеют Readiness Probe, проверяющий PostgreSQL. Во время пика БД начала замедляться из-за contention на write locks. Таймаут probe превысил failureThreshold, и все 200 Pod’ы одновременно отключились от трафика.
Результат: Полный 503 на 90 секунд, пока БД не стабилизировалась и Pod’ы не вернулись в Endpoints. Потеря ~$500K выручки.
Post-mortem и fix:
- Readiness Probe переделан на проверку только внутреннего состояния (thread pool, memory), без зависимости от БД
- Добавлен Circuit Breaker для БД-зависимых операций
- Введён отдельный
/health/readyбез БД и/health/degradedс БД — при проблемах с БД приложение отдаёт данные из кэша - Настроен Prometheus alert на
kube_endpoint_address_available < expected
Monitoring (Prometheus/Grafana)
Ключевые метрики:
# Pod'ы не готовые к трафику
sum(kube_pod_status_ready{condition="false"}) by (namespace)
# Частота провалов Readiness Probe
kubelet_pod_worker_duration_seconds{probe_type="readiness"}
# Latency проб
kubelet_pod_worker_duration_seconds_bucket{probe_type="readiness"}
# EndpointSlice без адресов
kube_endpoint_address_available{condition="not_ready"}
Grafana Dashboard:
- Panel 1: Количество Pod’ов в Ready/Not Ready состоянии (по namespace)
- Panel 2: Readiness Probe success rate over time
- Panel 3: Latency между probe failure и EndpointSlice update
- Panel 4: Correlate с БД latency и БД connection pool usage
Highload Best Practices
- Разделяйте Liveness и Readiness эндпоинты — Liveness проверяет “живо ли приложение”, Readiness проверяет “может ли оно работать”
- Не проверяйте внешние зависимости напрямую — используйте Circuit Breaker и возвращайте Ready, если приложение может функционировать в degraded mode
- Используйте startupProbe для тяжёлых JVM-приложений — чтобы не ставить огромный
initialDelaySecondsна Readiness - Настройте
failureThreshold: 3иperiodSeconds: 5— баланс между скоростью реакции и устойчивостью к шуму - Мониторьте EndpointSlice размеры — при тысячах Pod’ов iptables правила kube-proxy становятся bottleneck, переключайтесь на IPVS mode
- Graceful shutdown + preStop hook — дайте приложению время завершить активные запросы перед удалением из Endpoints:
lifecycle: preStop: exec: command: ["sh", "-c", "sleep 10"]
🎯 Шпаргалка для интервью
Обязательно знать:
- Readiness Probe проверяет «готов ли Pod к трафику»; при провале — удаление из Service Endpoints
- Failed readiness: Pod убирается из балансировки, но НЕ перезапускается (отличие от liveness)
- Обновляет EndpointSlice → kube-proxy обновляет iptables/IPVS → трафик переключается (2-5 сек)
- Не проверяйте внешние зависимости напрямую — риск каскадного отказа
- Readiness Gates (K8s 1.14+) — внешние условия для готовности (Service Mesh)
- Для Rolling Update: K8s не удаляет старые Pod’ы пока новые не пройдут Readiness
- Spring Boot:
/actuator/health/readiness— стандартный endpoint
Частые уточняющие вопросы:
- «Что будет если readiness провалена?» — Pod убирается из Endpoints, но продолжает работать
- «Почему нельзя проверять БД при каскадном сбое?» — Все Pod’ы одновременно отключатся → полный 503
- «Readiness для Stateless приложения?» — Может не понадобиться, если готово мгновенно
- «Headless Service + Readiness?» — Влияет на DNS-резольвинг; кэшированный DNS может устареть
Красные флаги (НЕ говорить):
- «Readiness перезапускает Pod при провале» (нет, только убирает из балансировки)
- «Readiness = Liveness» (разные действия при сбое)
- «Проверяю БД в readiness для всех сервисов» (риск каскадного отказа)
- «Readiness не нужна — Pod Running значит готов» (Running ≠ ready)
Связанные темы:
- [[Что такое liveness probe]] — проверка живучести
- [[Зачем нужны health checks]] — все три пробы вместе
- [[Как организовать rolling update в Kubernetes]] — readiness блокирует обновление