Питання 18 · Розділ 14

Що таке Readiness Probe?

Readiness probe -- K8s перевіряє, чи готовий Pod приймати трафік. Якщо probe fails -- Pod прибирається з Service endpoints, але НЕ перезапускається.

Мовні версії: English Russian Ukrainian

🟢 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 опитує вказаний endpoint з інтервалом periodSeconds. При успішній відповіді Pod отримує статус Ready: True і його IP додається в Endpoints (або EndpointSlice) всіх сервісів, які селектять цей Pod. При провалі — IP видаляється з Endpoints.

Типи перевірок:

  • httpGet — HTTP GET запит, очікує 2xx/3xx
  • tcpSocket — перевірка, що 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. Далі спрацьовує ланцюжок:

  1. EndpointSlice Controller (в kube-controller-manager) підписаний на зміни Pod’ів
  2. При зміні Ready умови, контроллер перераховує EndpointSlice
  3. kube-proxy (через iptables/IPVS) оновлює правила балансування
  4. Трафік перестає (або починає) направлятися на 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 endpoint не повинен бути публічним — він має бути доступний тільки зсередини кластера
  • Якщо probe використовує httpGet, переконайтеся, що він не розкриває внутрішню інформацію (версії, конфігурацію)
  • Не використовуйте exec probe з привілейованими командами — це потенційний вектор ескалації
  • В 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:

  1. Readiness Probe перероблено на перевірку тільки внутрішнього стану (thread pool, memory), без залежності від БД
  2. Додано Circuit Breaker для БД-залежних операцій
  3. Введено окремий /health/ready без БД та /health/degraded з БД — при проблемах з БД додаток віддає дані з кешу
  4. Налаштовано 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

  1. Розділяйте Liveness і Readiness ендпоинти — Liveness перевіряє “чи живий додаток”, Readiness перевіряє “чи може він працювати”
  2. Не перевіряйте зовнішні залежності напряму — використовуйте Circuit Breaker і повертайте Ready, якщо додаток може функціонувати в degraded mode
  3. Використовуйте startupProbe для важких JVM-додатків — щоб не ставити величезний initialDelaySeconds на Readiness
  4. Налаштуйте failureThreshold: 3 та periodSeconds: 5 — баланс між швидкістю реакції та стійкістю до шуму
  5. Моніторьте EndpointSlice розміри — при тисячах Pod’ів iptables правила kube-proxy стають bottleneck, перемикайтеся на IPVS mode
  6. 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 блокує оновлення