Как балансировщик понимает, что экземпляр сервиса нездоров?
- Чем liveness-проба отличается от readiness?
- Что такое outlier detection?
- Зачем нужны sticky sessions и чем они плохи?
Активные проверки — балансировщик сам опрашивает /health; пассивные — следит за ошибками и задержками реальных запросов и выкидывает выбросы (outlier detection).
- Readiness — «готов принимать трафик» (убрать из балансировки), liveness — «процесс завис» (перезапустить)
- Liveness не должна проверять базу и зависимости — иначе сбой базы перезапустит всё
- Медленный старт и прогрев, корректное снятие с балансировки при остановке
А ещё Sticky sessions мешают балансировке и отказоустойчивости — лучше stateless и общее хранилище сессий
Подробно
Активные проверки. Балансировщик или оркестратор раз в несколько секунд обращается к служебному эндпоинту. После N неудач подряд экземпляр исключается, после M успехов — возвращается (гистерезис, чтобы не мигал).
Пассивные проверки (outlier detection). Смотрим на реальные ответы: 5xx, таймауты, рост задержки. Экземпляр, у которого ошибок заметно больше, чем у остальных, временно исключается (ejection) с растущим временем изоляции. Ловит то, что /health не видит: сервис отвечает на проверку, но реальные запросы падают. Envoy, Istio, Linkerd делают это из коробки. Ограничение — не выкидывать больше заданной доли экземпляров, иначе при общей проблеме выкинем всех.
Kubernetes различает три пробы:
- startup — пока не прошла, остальные не проверяются: даёт время медленному старту;
- readiness — готов ли принимать трафик сейчас. Не прошла — под убирают из Service, но не перезапускают. Может учитывать прогрев кэшей, доступность критичных зависимостей, перегрузку;
- liveness — жив ли процесс. Не прошла — контейнер перезапускают. Должна быть простой и проверять только сам процесс (не завис ли цикл обработки). Если liveness проверяет базу, то при сбое базы Kubernetes перезапустит все поды разом — и они вдобавок ударят по базе при старте.
Подключение и отключение экземпляров:
- медленный старт — новый экземпляр с холодным кэшем и JIT получает долю трафика постепенно;
- graceful shutdown — сначала readiness = false и пауза, пока балансировщики узнают, потом завершение текущих запросов.
Sticky sessions — привязка клиента к экземпляру (по cookie или хешу IP), чтобы держать сессию в памяти. Минусы: неравномерная нагрузка, потеря сессий при падении или выкатке, трудности автомасштабирования. Лучше вынести сессию в Redis или подписанный токен и сделать сервис stateless. Оправдано для WebSocket и локальных кэшей, где привязка даёт выигрыш, — тогда через consistent hashing.
Пример
readinessProbe: # «можно ли слать трафик»
httpGet: { path: /ready, port: 8080 }
periodSeconds: 5
failureThreshold: 2
livenessProbe: # «не завис ли процесс» — без проверки базы
httpGet: { path: /live, port: 8080 }
periodSeconds: 10
failureThreshold: 3
startupProbe:
httpGet: { path: /live, port: 8080 }
failureThreshold: 30 # до 5 минут на стартЧто хотят услышать
- Активные и пассивные проверки, outlier detection.
- Readiness против liveness и почему liveness не проверяет зависимости.
- Медленный старт и корректное снятие с балансировки.
- Минусы sticky sessions и альтернатива.
Частые ошибки
- Проверять в liveness доступность базы.
- Считать, что /health = 200 означает, что сервис обслуживает запросы нормально.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Liveness должна проверять базу, чтобы перезапускать сервис при её сбое
- ✗Readiness перезапускает контейнер, а liveness убирает его из балансировки
- ✓Активно опрашивают /health и пассивно следят за ошибками запросов
- ✗Пассивные проверки требуют отдельного эндпоинта /passive
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.