Надежность — это не отсутствие сбоев. Это способность системы, команды и человека вместе подняться после падения, переосмыслить, перестроить и идти дальше — с новыми правилами игры, где человеческая уязвимость не угроза, а часть уравнения
Основные принципы
1. Степень риска действий, принимаемых по устранению инцидента, не должна быть выше степени влияния инцидента
- Важно оценить текущую ситуацию, чтобы понять, насколько серьёзны проблемы, сколько пользователей и систем они затрагивают, а также является ли ситуация стабильной или ухудшается.
- Для оценки серьёзности ситуации можно воспользоваться «золотыми сигналами» SRE:
- Задержка — время ответа, которое проще всего измерить в процентилях.
- Ошибки — их следует отслеживать относительно общего числа запросов и определять в количественном соотношении. Для этого можно использовать инструменты трассировки или специализированные системы управления ошибками, такие как Sentry.
- Частота запросов — измеряется в количестве запросов в секунду. Рекомендуется выводить данные по кодам ответа или отдельно для ошибок и успешных запросов.
- Насыщенность — процент использования ресурсов, таких как оперативная память или подключения к базе данных, а также нагрузки на CPU и I/O. Эти данные помогают в прогнозировании.
- Необходимо предоставить информацию о количестве пользователей, сталкивающихся с ошибками, и о функциональности, которая была нарушена. Важно выявить критически важные для бизнеса проблемы, а не сообщать обо всех.
- Ситуация считается стабильной, если, например, частота ошибок остаётся постоянной на уровне 10% запросов, или если время отклика на уровне 99-го перцентиля превышает SLO, но остаётся стабильным на уровне 95-го перцентиля.
- Чтобы избежать подобных ситуаций, необходимо внедрить планы реагирования и восстановления, о которых пойдёт речь ниже.
- В состоянии стресса многие инженеры могут действовать необдуманно, что может привести к ещё более серьёзным проблемам. Например, если во время запуска нового экземпляра приложения возникает ошибка, инженер может решить перезапустить все остальные экземпляры. Однако это может привести к каскадному сбою, поскольку ошибка была обнаружена в зависимой службе, которая требуется только для запуска приложения (ранее созданные реплики работали корректно). В такой ситуации более полезным решением будет изучить сообщение об ошибке в журналах, а затем сосредоточиться на поиске и устранении проблемы в другой службе, которую необходимо запустить, чтобы решить проблему.
2. Регулярно тестируйте планы по восстановлению и реагированию на инциденты
- Установите более низкий порог срабатывания системы оповещения и следите за временем реакции и действиями команд.
- Инструкции должны быть простыми и понятными, вплоть до использования выражений, подобных «нажми зелёную кнопку» (см. пункт 4 ниже).
- Обратите внимание на временные показатели, такие как MTTD (среднее время до первого контакта), MTTR (среднее время восстановления) и MTTM (среднее время удержания).
- После того как меры по предотвращению или минимизации последствий будут приняты, смоделируйте инцидент в тестовой среде, чтобы проверить их эффективность.
3. Изменения, по возможности, должны применяться постепенно, используйте канареечные релизы
- Для удобной реализации canary в Kubernetes можно использовать проекты Flagger или Argo Rollouts. Однако стоит учесть, что в них имеются некоторые нерешенные проблемы, которые могут привести к неполадкам.
- A/B-тестирование предоставляет возможность направлять определенный трафик на новую версию приложения. Это можно сделать на основе конкретного заголовка или исходя из запросов от конкретных пользователей, например: пользователей Android.
4. Должна быть “большая красная кнопка”, которая просто и быстро отменит изменения, которые привели к инциденту
- На этапе развертывания имеется кнопка, позволяющая откатить helm-релиз или выполнить подготовленный запрос на слияние для возврата к предыдущему состоянию.
- Также есть кнопка для активации пайплайна, который будет перенаправлять трафик непосредственно в кластер в случае недоступности WAF.
- В процессе планирования аварийного восстановления рекомендуется использовать эти кнопки для автоматизации действий в случае возникновения инцидента.
5. Проводить интеграционные тесты, наблюдая за тем, как наши изменения встариваются в общую архитектуру и взаимодействуют с другими компонентами
- Создание стенда preprod и организация постоянного потока трафика, аналогичного производственному. Таким образом, тестируя изменения на этом стенде, мы сможем оценить их влияние на всю систему.
- Вместо того, чтобы спрашивать: «Какой программный сервис вышел из строя?», мы задаём вопрос: «Какие взаимодействия между частями системы были недостаточно контролируемыми?»
- Вместо того чтобы пытаться устранить любой отдельный сбой, который может произойти в любой точке системы, мы работаем над тем, чтобы не допустить перехода системы в Состояние Опасности.
6. Необходимы резервные каналы связи в случае сбоя в основных каналах
- Если основной канал связи перестанет работать, у вас будет запасной канал в другом мессенджере и несколько способов связаться с сотрудником, помимо его мобильного телефона.
- Раз в квартал следует проверять резервные каналы связи и иногда намеренно использовать один из них для экстренных оповещений.
7. Предоставлять минимальную функциональность при ухудшении режима работы
- Сервис может выдавать шаблонные ответы на запросы и частично извлекать данные из базы.
- Например, режим авторизации позволяет аутентифицировать существующих пользователей, но не поддерживает несколько вариантов входа.
- Пользователи могут получать доступ к данным из резервной копии своего списка избранных фильмов, но без возможности добавления новых.
- В случае проблем с бэкенд-запросами, для части системы может быть доступен кэшированный контент, но только до тех пор, пока не будет восстановлена работоспособность основной системы.
8. Хаос-тестирование и тестирование катастрофоустойчивости
- Как и в пятом пункте, мы регулярно практикуем хаос-тестирование на этапе предварительной разработки, используя готовые решения, такие как Litmus или Chaos Mesh.
- Некорректное поведение части микросервиса. Например, если одна из функций микросервиса работает неправильно.
- Неправильная обратная связь с потребителем. Например, если потребитель получает неверные данные или не получает их вовсе.
- Отсутствие связи между микросервисом и потребителем. Например, если микросервис не получает сообщение от потребителя, даже если тот пытался отправить его.
- Проблемы с инфраструктурой. Например, если инфраструктура, на которой запущен микросервис, работает некорректно, например HPA понизил число реплик до минимума из-за ошибки.
- Мы также тестируем нашу систему на устойчивость к отказу, моделируя в среде preprod уже известные инциденты. Это позволяет нам оценить, насколько эффективно мы можем предотвращать и обнаруживать потенциальные проблемы.
- В процессе хаос-тестирования и тестирования на отказ мы всегда выделяем команду злоумышленников и команду специалистов по безопасности (SRE), которые совместно ищут и устраняют выявленные недостатки.
- Такой подход позволяет нам выявлять области системы, где отказ наиболее вероятен и может привести к серьезным последствиям.
9. Автоматизация реагирования на сбои, которые мы можем предвидеть
- Этот пункт можно рассматривать как подпункт четвёртого, поскольку «красная кнопка» срабатывает автоматически, когда известно, как решить проблему с симптомами А с помощью события B. Например, в менеджере пакетов Helm это означает, что при установке флага
--atomic
автоматически откатывается выпуск. В Kubernetes (k8s) автоматическое завершение отправки запросов к pod с неудачным статусом ReadinessProbe.
Например, инженеры SRE могут автоматизировать:
- Канареечные релизы с помощью сторонних утилит, таких как Flagger или Argo Rollouts. Или вручную балансировать трафик, например, на virtualService от istio, задавая «вес» для различных версий приложения.
- В случае возникновения определённых симптомов (ошибок, долгого времени ответа) сервис может быть переведён в режим ограниченной функциональности. Например, он может предоставлять шаблонные ответы на определённые запросы и только частично искать данные из базы данных для других запросов.
10. По возможности чаще выпускать релизы, что приведет к меньшему количеству инцидентов
- Определите бюджет ошибок, чтобы расставить приоритеты в работе. Если бюджет превышен, сосредоточьтесь на доработке и исправлении ошибок.
- Предусмотреть безопасность внесения изменений, чтобы система не вошла в Состояние Опасности. Вливать MR только с аппрува лида и т.д.
11. Альтернативное решение для критически важных систем, которое их заменит в случае, если в основной системе инцидент
- Необходимо создавать несколько пулов узлов в Kubernetes. Это позволит минимизировать последствия сбоя операционной системы (ОС) узла или узлов, которые могут привести к частичной потере доступности.
- Важно регулярно создавать резервные копии как репозиториев кода, так и документации.