Самовосстановление и наблюдаемость

Что это такое

Самовосстановление — это когда кластер замечает, что реальность больше не совпадает с объявленным: pod погиб, узел исчез, процесс перестал отвечать, — и действует, чтобы восстановить соответствие. Наблюдаемость — то, как вы узнаёте, что это произошло, и удалось ли. Первое — свойство, ради которого оркестратор стоит своей сложности; второе — то, что не даёт этому свойству стать невидимым источником изменений.

Почему это важно

Система, перезапускающая свои отказавшие компоненты, охотно скрывает хроническую неисправность: pod’ы перезапускаются, сервис остаётся доступен, и никто не узнаёт, что причина — утечка памяти, пока это не станет сбоем. Поэтому проверки здоровья, управляющие восстановлением, — ещё и поверхность диагностики, и их отказы — самый полезный сигнал, который платформа производит. Чтение перезапусков, переходов readiness и вытеснений как данных, а не как фонового шума, и превращает автоматику оркестратора в то, что вы понимаете.

Ключевые идеи

Проверки здоровья — триггер каждого автоматического действия

Отказ liveness-проверки вызывает перезапуск; отказ readiness-проверки выводит pod из обслуживания, не убивая его. Обе пишете вы, и обе формируют поведение кластера — потому это самые многорешающие несколько строк в манифесте. Liveness-проверка, зависящая от нижележащего сервиса, будет перезапускать здоровые pod’ы всякий раз, когда тот сервис медленный, превращая краткую проблему зависимости в бесконечный цикл перезапусков.

liveness  отказ   -> контейнер перезапускается (и отказ повторяется, пока не исправят)
readiness отказ   -> выведен из endpoints сервиса, но продолжает работать

Пробам нужно время на старт и время на остановку

Период запуска не даёт медленно инициализирующемуся процессу быть убитым раньше готовности, а период милосердия при завершении даёт pod’у завершить работу в полёте. Оба значения по умолчанию достаточно малы, чтобы быть неверными для настоящих сервисов. Сочетание короткого периода милосердия с процессом, игнорирующим сигнал завершения, — обычная причина ошибок во время постепенного развёртывания.

Реплики и бюджеты нарушений делают выпуск безопасным

Выпуск заменяет pod’ы постепенно по политике, говорящей, сколько может быть недоступно. Объявление бюджета нарушений, запрещающего опускать приложение ниже минимального доступного числа, и не даёт операции обслуживания или плохому выпуску снять слишком много ёмкости за раз. Оно превращает намерение о доступности в то, что кластер обеспечивает.

Перезапуски — доказательство, а не шум

Растущее число перезапусков означает, что нагрузка нездорова, даже если пользователи этого не заметили. То же касается pod’ов, раз за разом вытесняемых за превышение памяти. Наблюдение за этими двумя счётчиками превращает класс скрытых отказов в раннее предупреждение, и оба видны из собственного состояния кластера без дополнительных инструментов.

Нужны все три сигнала, и платформа не даёт ни одного автоматически

Метрики говорят, что сервис деградировал; логи — что видел код; трассировки — какой вызов был медленным. И ни одного из них кластер не даёт из коробки. Что он даёт — единое место, куда их можно прикрепить, потому что каждая рабочая нагрузка описана одинаковыми объектами. Выдача идентификатора корреляции из каждого pod’а и делает эти три соединимыми, когда что-то идёт не так.

Собственные события кластера объясняют большинство загадок

Отказы в планировании, сбои вытягивания образа, отказы проб и вытеснения — всё это появляется как события, прикреплённые к объекту. Читать их обычно быстрее, чем логи, потому что платформа прямо говорит, что именно отказалась сделать и почему.

Практика

Правильно разделите liveness и readiness

Возьмите сервис с внешней зависимостью, сделайте liveness-проверку зависящей только от процесса, а readiness-проверку включите зависимость, затем сделайте зависимость медленной.

Готово, когда: pod становится unready, но число его перезапусков не растёт.

Выпустите версию под нагрузкой с безопасным бюджетом

Разверните новую версию сервиса, создавая устойчивый трафик, с бюджетом нарушений, сохраняющим минимальное доступное число.

Готово, когда: нагрузочный тест не сообщает об отказавших запросах, а счётчики перезапусков остаются нулевыми.

Частые ошибки

  • Liveness зависит от внешнего сервиса — медленная зависимость запускает перезапуски и превращает мелкую проблему в сбой; исправить: держите liveness локальной.
  • Пропущен период запуска — медленная инициализация убивается до завершения и зацикливается навсегда; исправить: дайте достаточно времени на старт до начала проб.
  • Игнорирование сигнала завершения — запросы в полёте теряются при каждом выпуске; исправить: завершайтесь плавно в пределах периода милосердия.
  • Отношение к перезапускам как к норме — хроническая неисправность скрывается за здоровым с виду сервисом; исправить: оповещайте о счётчиках перезапусков и вытеснений.
  • Сбор состояния с узлов — оно исчезает при переселении pod’а; исправить: собирайте метрики, логи и трассировки с самих pod’ов.

Что читать дальше