Istio Circuit Breaker: Отключение Неисправных Контейнеров

Праздники закончились, и мы вернулись со второй публикацией из серии Istio Service Mesh.

Istio Circuit Breaker: отключение неисправных контейнеров

Сегодняшняя тема – Circuit Breaker, что в переводе на русский электротехники означает «выключатель», в просторечии – «выключатель».

Только в Istio этот автомат отключает не закороченную или перегруженную цепь, а неисправные контейнеры.



Как это должно работать в идеале

Когда микросервисы управляются Kubernetes, например, на платформе OpenShift, они автоматически масштабируются вверх и вниз в зависимости от нагрузки.

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

И — в идеале — всё это должно работать идеально.

Мы помним, что микросервисы маленькие и эфемерные.

Фемерность, под которой здесь подразумевается легкость возникновения и исчезновения, часто недооценивается.

Рождение и смерть очередного экземпляра микросервиса в поде — вещи вполне ожидаемые, OpenShift и Kubernetes с этим хорошо справляются, и всё прекрасно работает — но опять же в теории.



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

Теперь представьте, что конкретный экземпляр микросервиса, то есть контейнер, пришел в негодность: либо не отвечает (ошибка 503), либо, что еще неприятнее, отвечает, но слишком медленно.

Другими словами, он становится глючным или не отвечает на запросы, но автоматически из пула не удаляется.

Что следует сделать в этом случае? Повторить попытку? Должен ли я удалить его из схемы маршрутизации? А что значит «слишком медленно» — сколько это в цифрах и кто их определяет? Может, просто передохнуть и попробовать еще раз позже? Если да, то сколько позже?

Что такое выброс пула в Istio

И тут на помощь приходит Istio со своими машинами защиты Circuit Breaker, которые временно удаляют неисправные контейнеры из пула ресурсов маршрутизации и балансировки нагрузки, реализуя процедуру Pool Ejection. Используя стратегию обнаружения выбросов, Istio обнаруживает модули кривой, выходящие за рамки нормы, и удаляет их из пула ресурсов на определенное время, называемое «окном сна».

Чтобы показать, как это работает в Kubernetes на платформе OpenShift, начнем со скриншота нормально работающих микросервисов из примера в репозитории.

Демонстрации Red Hat для разработчиков .

Здесь у нас есть два модуля v1 и v2, в каждом из которых работает один контейнер.

Когда правила маршрутизации Istio не используются, Kubernetes по умолчанию использует равномерно сбалансированную циклическую маршрутизацию:

Istio Circuit Breaker: отключение неисправных контейнеров



Готовимся к аварии

Прежде чем выполнять выброс пула, вам необходимо создать правило маршрутизации Istio. Допустим, мы хотим распределить запросы между подами в соотношении 50/50. Кроме того, мы увеличим количество контейнеров v2 с одного до двух, вот так:
  
   

oc scale deployment recommendation-v2 --replicas=2 -n tutorial

Теперь мы устанавливаем правило маршрутизации, чтобы трафик распределялся между подами в соотношении 50/50.

Istio Circuit Breaker: отключение неисправных контейнеров

Вот как выглядит результат применения этого правила:

Istio Circuit Breaker: отключение неисправных контейнеров

Можно придраться к тому, что у этого экрана не 50/50, а 14:9, но со временем ситуация улучшится.



Сделать глюк

Теперь давайте отключим один из двух контейнеров v2, чтобы у нас был один исправный контейнер v1, один исправный контейнер v2 и один неисправный контейнер v2:

Istio Circuit Breaker: отключение неисправных контейнеров



Исправление сбоя

Итак, у нас есть неисправный контейнер и пришло время Pool Ejection. Используя очень простую конфигурацию, мы исключим этот вышедший из строя контейнер из любых схем маршрутизации на 15 секунд в надежде, что он вернется в работоспособное состояние (либо перезапустите, либо восстановите работоспособность).

Вот как выглядит этот конфиг и результаты его работы:

Istio Circuit Breaker: отключение неисправных контейнеров



Istio Circuit Breaker: отключение неисправных контейнеров

Как видите, отказавший контейнер v2 больше не используется для маршрутизации запросов, поскольку он был удален из пула.

Но через 15 секунд он автоматически вернется в бассейн.

Собственно, мы только что показали, как работает Pool Ejection.

Начнем строить архитектуру

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

  У НАСА есть один громкий девиз — «Failure Is Not the Option», автором которого считается руководитель полета.

Джин Кранц .

На русский это можно перевести как «Неудача невозможна», а смысл здесь в том, что все можно заставить работать, если у вас достаточно воли.

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

И как с ними бороться в случае с микросервисами? На наш взгляд, лучше рассчитывать не на силу воли, а на возможности контейнеров, Кубернетес , Красная шляпа OpenShift , И Истио .

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

И так же, как электрический выключатель отключает проблемный участок цепи, программное обеспечение Istio Circuit Breaker открывает соединение между потоком запросов и проблемным контейнером, когда с конечной точкой что-то не так, например, когда сервер вышел из строя или начал глючить.

замедлять.

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



Автоматический выключатель в теории

Circuit Breaker — это прокси-сервер, который контролирует поток запросов к конечной точке.

Когда эта точка перестает работать или, в зависимости от заданных настроек, начинает тормозить, прокси разрывает соединение с контейнером.

Затем трафик перенаправляется в другие контейнеры просто из-за балансировки нагрузки.

Соединение остается открытым в течение определенного периода сна, скажем, двух минут, а затем считается полуоткрытым.

Попытка отправить следующий запрос определяет дальнейшее состояние соединения.

Если с сервисом все в порядке, соединение возвращается в рабочее состояние и снова закрывается.

Если со службой по-прежнему что-то не так, соединение разрывается и окно сна снова включается.

Вот как выглядит упрощенная диаграмма состояний автоматического выключателя:

Istio Circuit Breaker: отключение неисправных контейнеров

Здесь важно отметить, что все это происходит на уровне, так сказать, архитектуры системы.

Поэтому в какой-то момент вам придется научить свои приложения работать с Circuit Breaker, например предоставлять в ответ значение по умолчанию или, если возможно, игнорировать существование службы.

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



Автоматический выключатель на практике

Например, мы запустим две версии нашего микросервиса рекомендаций в OpenShift. Версия 1 будет работать нормально, но в версии 2 мы встроим задержку для имитации замедления работы сервера.

Для просмотра результатов воспользуйтесь инструментом осада :

siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).

nip.io



Istio Circuit Breaker: отключение неисправных контейнеров

Вроде все работает, но какой ценой? На первый взгляд у нас 100% доступность, но присмотритесь — максимальная длительность транзакции составляет целых 12 секунд. Очевидно, что это узкое место, и его необходимо расширять.

Для этого мы воспользуемся Istio, чтобы исключить вызовы замедления контейнеров.

Вот как выглядит соответствующая конфигурация с использованием автоматического выключателя:

Istio Circuit Breaker: отключение неисправных контейнеров

Последняя строка с параметром httpMaxRequestsPerConnection сигнализирует о том, что соединение с должно быть разорвано при попытке создать еще одно — второе — соединение в дополнение к существующему.

Так как наш контейнер имитирует медленный сервис, такие ситуации будут возникать периодически, и тогда Istio вернет ошибку 503, но вот что покажет siege:

Istio Circuit Breaker: отключение неисправных контейнеров



Хорошо, у нас есть выключатель, что дальше?

Итак, мы реализовали автоматическое отключение, вообще не трогая исходный код самих сервисов.

Используя Circuit Breaker и описанную выше процедуру Pool Ejection, мы можем удалять тормозные контейнеры из пула ресурсов до тех пор, пока они не вернутся в нормальное состояние, и проверять их состояние с заданной периодичностью — в нашем примере это две минуты (параметр SleepWindow).

Обратите внимание, что способность приложения реагировать на ошибку 503 по-прежнему задается на уровне исходного кода.

Существует множество стратегий использования прерывателя цепи в зависимости от ситуации.

В следующем посте: Мы поговорим о трассировке и мониторинге, которые уже встроены или легко добавляются в Istio, а также о том, как намеренно вносить ошибки в систему.

Теги: #разработка Linux #виртуализация #ИТ-инфраструктура #открытый исходный код #Kubernetes #istio #Red Hat #Openshift

Вместе с данным постом часто просматривают: