Задача 7. Три probe и чем они друг от друга отличаются

Под тормозящей базы данных начинается лавина перезапусков, и становится только хуже. Разбираем разницу между liveness, readiness и startup, и почему liveness на зависимость от внешнего сервиса — опасная ошибка.
Опубликовано:

Задача

Сервис ходит в базу данных. Настроен liveness probe:

YAML
livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 10
  failureThreshold: 3
Нажмите, чтобы развернуть и увидеть больше

Эндпоинт /health проверяет соединение с БД: если запрос к базе не проходит, возвращается 503.

База начинает тормозить под нагрузкой. Через минуту все реплики сервиса уходят в цикл перезапусков, и ситуация становится хуже, чем была.

Вопрос: какая ошибка допущена в конфигурации?

Что кажется очевидным

«Порог failureThreshold слишком низкий» или «надо увеличить таймауты». Такие правки немного оттягивают проблему, но не устраняют её.

Как это работает на самом деле

Ошибка концептуальная: liveness probe проверяет не то, что нужно.

Три probe отвечают на три разных вопроса:

ProbeВопросПровал → что происходит
liveness«Процесс жив или завис?»Контейнер перезапускается
readiness«Готов ли принимать трафик?»Под убирают из endpoints (трафик прекращается, перезапуска нет)
startup«Приложение закончило запуск?»Контейнер перезапускается; пока идёт — остальные probe не выполняются

Ключевое различие — в цене ошибки. Провал readiness обратим и дёшев: перестал идти трафик, приложение восстановилось — трафик вернулся. Провал liveness означает убийство процесса.

Почему возникла лавина

Разберём цепочку:

  1. База тормозит → /health возвращает 503 на всех репликах одновременно.
  2. Liveness probe трижды подряд получает ошибку → kubelet перезапускает контейнеры.
  3. Перезапущенные приложения открывают новые соединения к уже перегруженной базе, заново прогревают пулы и кэши.
  4. Нагрузка на базу растёт → /health продолжает падать → новый круг перезапусков.

Получился контур с положительной обратной связью: механизм «самоисцеления» усиливает аварию. Причём перезапуск здесь не может помочь в принципе — проблема не в процессе, а во внешней зависимости.

Более того: пока под перезапускается, он не обслуживает и те запросы, которые не ходят в базу и могли бы работать.

Ответ

Ошибка в том, что liveness probe проверяет внешнюю зависимость. Перезапуск лечит зависший процесс, но не лечит недоступную базу — он лишь добавляет нагрузку и превращает частичную деградацию в полный отказ.

Проверка зависимостей — это работа readiness probe.

Что с этим делать

Разделите эндпоинты

YAML
# Жив ли процесс: максимально просто, без внешних вызовов
livenessProbe:
  httpGet:
    path: /healthz # отвечает 200, если event loop жив
    port: 8080
  periodSeconds: 10
  failureThreshold: 3

# Готов ли обслуживать: здесь проверяем зависимости
readinessProbe:
  httpGet:
    path: /ready # проверяет БД, кэш и т.п.
    port: 8080
  periodSeconds: 5
  failureThreshold: 2

# Медленный старт: даём время, не мешая liveness
startupProbe:
  httpGet:
    path: /healthz
    port: 8080
  periodSeconds: 5
  failureThreshold: 60 # до 5 минут на запуск
Нажмите, чтобы развернуть и увидеть больше

Правила, которые стоит принять как догму:

Осторожно с массовым провалом readiness

Есть обратная опасность: если все реплики одновременно провалят readiness, сервис останется без endpoints и перестанет отвечать полностью. Для зависимостей, отказ которых не полностью ломает сервис, разумнее оставлять под в строю и отдавать деградированный ответ, чем выводить из балансировки весь пул.

Настройка параметров

Диагностика

BASH
# Причина последнего перезапуска
kubectl describe pod my-app | grep -A5 "Last State"

# События probe
kubectl get events --field-selector reason=Unhealthy --sort-by=.lastTimestamp

# Счётчик перезапусков — растущий RESTARTS почти всегда означает
# проблемный liveness
kubectl get pods -w
Нажмите, чтобы развернуть и увидеть больше

Связанное: почему Running не значит Readyзадача 1.


Дальше: Задача 8. Держим сервис живым во время обслуживания нод.

Начать поиск

Введите ключевые слова для поиска статей

↑↓
ESC
⌘K Горячая клавиша