Хабрахабр

Управление микросервисами с помощью Kubernetes и Istio

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

Видео и перевод доклада — под катом.
В основе статьи — доклад Крейга Бокса на нашей прошлогодней конференции DevOops 2017.

Крейг Бокс (Craig Box, Твиттер) — DevRel из Google, отвечающий за направление микросервисов и инструменты Kubernetes и Istio. Его нынешний рассказ — про управление микросервисами на этих платформах.

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

Мы не хотим беспокоиться о них или, например, о MAC-адресах в приложениях, но стремимся думать о сервисах и связях, которые им необходимы. На высоком уровне мы рассматриваем сеть как трубу, которая просто перемещает биты. Если посмотреть с точки зрения OSI, то у нас есть сеть третьего уровня (с функциями определения маршрута и логической адресации), но мы-то хотим думать в терминах седьмого (с функцией доступа к сетевым службам).

Возможно, мы хотим видеть что-то вроде трассировки трафика вокруг проблемных сервисов. Как должна выглядеть настоящая сеть седьмого уровня? Мы хотим получать представление о том, что происходит в кластере, находить непредусмотренные зависимости, выяснять корневые причины возникновения сбоев. Чтобы можно было подключиться к сервису, и при этом уровень модели был поднят вверх с третьего уровня. Также нам необходимо избегать лишних накладных расходов, например, соединения с высокой задержкой или подключение к серверам с холодным или не до конца прогретым кешем.

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

Service Mesh — это слой, который позволяет нам решать вышеуказанные проблемы в среде микрообслуживания.

Монолит и микросервисы: плюсы и минусы

Но сначала спросим себя, почему мы вообще должны решать эти проблемы? Как раньше мы занимались разработкой ПО? У нас было приложение, которое выглядит примерно вот так — как монолит.

Почему бы и дальше не использовать этот подход?
Да потому что у монолита есть свои проблемы. Ведь здорово: весь код у нас на как ладони. Мы вынуждены создавать приложение на одном и том же языке или на совместимых языках, даже если над ним работают разные команды. Главная трудность в том, что если мы захотим пересобрать это приложение, то должны повторно развернуть каждый модуль, даже если ничего не изменилось. Пора это менять, пришло время микросервисов. Фактически отдельные части не могут быть протестированы независимо друг от друга.

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

Что получилось в итоге?

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

Мы заменили надежный вызов внутри модуля ненадежным удаленным вызовом процедуры. У нас были надежные вызовы внутри приложений, потому что вы просто вызывали функцию или модуль. А ведь не всегда сервис на другой стороне доступен.

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

Увеличились задержки, и одновременно сократились возможности их измерения. В новом подходе в сети возможно присутствие других пользователей, которые пытаются подключиться к службам. И эту проблему надо как-то решить. Теперь у нас есть пошаговые соединения во всех службах, которые создают один вызов модуля, и мы больше не можем просто посмотреть приложение в отладчике и узнать, что именно вызвало сбой. Очевидно, что нам необходим новый набор инструментов.

Что можно предпринять?

Мы можем взять наше приложение и сказать, что если RPC не работает с первого раза, то следует попробовать еще раз, а затем еще и еще. Есть несколько вариантов. Также мы можем добавить entry — exit traces чтобы сказать, что произошел запуск и завершение вызова, что для меня приравнивается к отладке. Немного подождать и снова попробовать или добавить Jitter. Нам придется взять на себя бремя содержания отдельных команд и постоянно держать в голове различные проблемы, которые могут возникнуть в SSL-библиотеках. Можно добавить инфраструктуру для обеспечения проверки подлинности соединений и научить все наши приложения работать с TLS-шифрованием.

Хотелось бы, чтобы пространство между приложениями стало разумным, чтобы появилась возможность отслеживания. Поддержание согласованности на различных платформах — это неблагодарная задача. Вот эти хотелки и реализует Service Mesh. Также нам нужна возможность изменения конфигурации во время выполнения, чтобы не перекомпилировать или не перезапускать приложения для перенастройки.

Istio

Поговорим о Istio.

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

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

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

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

Для обработки входа пользователей в систему у нас предусмотрен микросервис аутентификации, и у него есть состояния, сохраненные опять-таки за пределами нашего кластера в базе данных Cloud SQL.

Istio улучшает Kubernetes. Что делает Istio? При развертывании программного обеспечения kubernetes заметит его и спросит, хотим ли мы изменить и добавить еще один контейнер внутри каждого kubernetes. Вы устанавливаете его с помощью альфа-функции в Kubernetes под названием Инициализатор. Этот контейнер будет обрабатывать пути и маршрутизации, знать обо всех изменениях приложения.

Вот так схема выглядит с Istio.

Мы можем разгрузить функции, о которых уже говорили. У нас есть внешние машины, которые обеспечивают входящий и исходящий прокси для трафика в конкретном сервисе. Зато можем добавить внутрь другие вещи: автоматическое прерывание, ограничение скорости, canary release. Нам не нужно учить приложение, как выполнять телеметрию или трассировку с помощью TLS.

Kubernetes делает все на том же IP-адресе. Весь трафик теперь будет проходить через прокси-серверы на внешних машинах, а не напрямую к сервисам. Мы сможем перехватить трафик, который пошел бы на front или end сервисы.

Внешний прокси, который использует Istio, называется Envoy.

Работает в продакшн более года, запуская всю инфраструктуру микросервисов. Envoy на самом деле старше Istio, он был разработан в LYFT. Таким образом, Google, IBM и LYFT — это три компании, которые до сих пор над ним работают. Мы выбрали Envoy для проекта Istio в сотрудничестве с сообществом.

Был в продакшн более 18 месяцев, прежде чем стать проектом с открытым исходным кодом. Envoy написан на C++ версии 11. Он не займет много ресурсов, когда вы подключите его к вашим сервисам.

Это создание прокси-сервера для HTTP, включая HTTP/2 и протоколов, основанных на нем, таких как gRPC. Вот несколько вещей, которые умеет Envoy. Envoy контролирует вашу зону инфраструктуры, так что вы можете сделать свою часть автономной. Он также может выполнять переадресацию другим протоколам на двоичном уровне. Вы можете установить определенное количество попыток подключения к серверу, прежде чем прекратить обращение и передать своим серверам информацию о том, что сервис не отвечает. Он может обрабатывать большое количество сетевых соединений с повторами запросов и ожиданием.

Вы просто подключаетесь к нему с помощью API, очень похожим на kubernetes, и меняете конфигурацию во время выполнения. Не нужно беспокоиться о перезагрузке приложения, чтобы добавить в него конфигурацию.

Например, оповещение об ошибке injection. Команда Istio внесла большой вклад в платформу UpStream Envoy Platform. А также реализовали функции графического отображения и разделения трафика, чтобы обрабатывать случаи, когда используется canary-развертывание. Мы сделали так, чтобы можно было видеть, как приложение ведет себя в случае превышения количества запросов на объект, завершившихся неудачей.

Мы возьмем лишь два микросервиса, которые упоминали ранее. На рисунке показано, как выглядит архитектура системы Istio. Со стороны прокси-сервера Envoy, который мы развернули вместе с приложениями, происходит перенос трафика с помощью IP-таблиц в пространстве имен. В конечном счете, на схеме все очень похоже на программно-определяемую сеть. Pilot, который создает конфигурацию, смотрит на правила, которые можно изменить с помощью API для контрольной панели Istio, и затем обновляет Envoy так, чтобы он вел себя как сервис обнаружения кластера. Контрольная панель отвечает за управление консолью, но она не обрабатывает трафик сама.
У нас есть три компонента. Приложению не требуется наличие SSL, они могут соединяться по HTTP, и прокси будут обрабатывать все это за вас. Istio-Auth служит центром сертификации и передает TLS сертификаты на прокси-серверы.

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

Преимущества Istio

Итак, давайте поговорим подробнее о пяти вещах, которые мы получим от Istio. В первую очередь рассмотрим управление трафиком. Мы можем отделить контроль трафика от масштабирования инфраструктуры, поэтому ранее мы могли бы сделать что-то вроде 20 экземпляров приложения и 19 из них будет на старой версии, а один на новой, то есть 5% трафика будет приходиться на новую версию. С Istio мы можем развернуть любое количество экземпляров, которое нам нужно, и при этом указать, какой процент трафика нужно отправить на новые версии. Простое правило разделения.

Envoy будет периодически обновляться по мере изменения конфигурации, и это не приведет к сбоям в обслуживании. Все может быть запрограммировано «на лету» с помощью правил. Так как мы работаем на уровне доступа к сетевым службам, то можем просмотреть пакеты, и в этом случае есть возможность залезть в пользовательский агент, который находится на третьем уровне сети.

Внутренний вызывающий микросервис может определить, к какой конкретной версии ему нужно подключиться, а вы можете перевести его на другую версию, например, 2. Например, мы можем сказать, что любой траффик с iPhone подчиняется другому правилу, и мы собираемся направить определенную долю трафика на новую версию, которую хотим протестировать для определенного устройства. 0.

Когда у вас есть представление внутри кластера, вы можете понять как оно сделано. Второе преимущество — это прозрачность. Метрики уже есть в каждом компоненте. Нам не нужно в процессе разработки создавать инструментарий для метрик.

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

Не забудьте его развернуть внутри кластера. Так выглядит панель инструментов Istio, созданная с помощью сервиса Prometheus.

Можно вывести и более интересные вещи, например, какой процент приложений дает более 500 ошибок, что подразумевает отказ. В примере на скриншоте показан ряд отслеживаемых параметров, характерных для всего кластера. Istio знает, что поддерживает Prometheus, а тот в курсе, какие службы доступны в вашем кластере, поэтому Istio-Mixer может отправлять метрики в Prometheus без дополнительных настроек.
Давайте посмотрим, как это работает. Время ответа агрегируется во всех вызывающих и отвечающих экземплярах сервисов внутри кластера, этот функционал не требует настроек. Он нормализует их и отправляет на любые серверы, которые вы сконфигурировали. Если вы вызываете конкретную службу, прокси сервис отправляет информацию об этом вызове в Mixer, который фиксирует такие параметры, как ожидание времени ответа, статус кода и IP. И вам не придется ничего менять в инфраструктуре, если захотите добавить новую метрику. Специально для вывода основных показателей есть сервис Prometheus и адаптеры FLUX DB, но вы также можете написать собственный адаптер и вывести данные в любом формате для любого другого приложения.

Информация обо всех вызовах, которые маршрутизируются через Istio-Mixer, может быть отправлена в Zipkin. Если вы хотите провести более глубокое исследование, то воспользуйтесь системой распределенной трассировки Zipkin. Там вы увидите всю цепочку вызовов микросервисов при ответе пользователю и легко обнаружите службу, которая затягивает время обработки.

Envoy сам передает всю необходимую информацию в Mixer, который отправляет ее в трассировку, например, в Zipkin, stackdriver trace от Google или любое другое пользовательское приложение. На уровне приложений беспокоиться о создании трассировки практически не нужно.

Давайте поговорим об отказоустойчивости и эффективности.

Введем ошибки в эту связь и посмотрим, что произойдет. Тайм-ауты между вызовами сервисов нужны для проверки работоспособности, в первую очередь, балансировщиков нагрузки. Допустим, существует связь между сервисом A и сервисом B. Рассмотрим пример. По сути мы собираемся занять его на 300 миллисекунд, прежде чем он сообщит о неудачной попытке соединения. Мы ждем ответ от сервиса видео 100 миллисекунд и даем всего 3 попытки, если результат не получен.

У рейтинга таймаут составляет 200 миллисекунд и дается две попытки вызова. Далее, например, наш сервис кино должен посмотреть рейтинг фильма через другой микросервис. Но, мы помним, по истечении 300 мс сервис кино сообщит, что он нерабочий, и мы никогда не узнаем реальную причину сбоя. Вызов службы видео может привести к тому, что вы будете ждать 400 миллисекунд в случае, если рейтинг звездности вне доступа. Использование тайм-аутов и  тестирование того, что происходит в этих случаях — отличный способ найти в вашей архитектуре микросервисов всякие хитроумные баги.

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

Мы выполняем TLS-offloading, поэтому используем в Envoy современный хорошо допиленный SSL, с которым можно не волноваться о уязвимостях.

Еще одно преимущество Istio — безопасность.

Сервис Istio-Auth работает в нескольких направлениях. Какие базовые средства безопасности есть в Istio? Если мы говорим о потоке трафика, то у нас есть центр сертификации Istio, который выдает сертификаты для учетных записей служб, которые мы запускаем внутри кластера. Используется общедоступный фреймворк и набор стандартов идентификации для сервисов SPIFFE. Envoy использует ключи для двусторонней аутентификации TLS. Эти сертификаты соответствуют стандарту SPIFFE и распространяются Envoy, используя механизм защиты kubernetes. Таким образом, приложения бэкенда получают идентификаторы, на основе которых уже можно организовать политику.

Система будет реагировать на автоматическое масштабирование, поэтому вводя новую сущность, вы получаете новый сертификат. Istio самостоятельно обслуживает корневые сертификаты, чтобы вы не волновались об аннулировании и истекающих сроках. Вам не надо настраивать firewall. Никаких ручных настроек. Пользователи будут использовать сетевую политику и kubernetes, чтобы реализовать брандмауэры между контейнерами.

Mixer является точкой интеграции с инфраструктурными бэкэндами, которые вы можете расширить с помощью Service Mesh. Наконец, применение политик. Все сконструировано для оперативного контроля вызовов, которые идут через Envoy. Cервисы могут легко перемещаться внутри кластера, быть развернуты в нескольких средах, в облаке или локально. Например, вы разрешаете к какой-то своей службе 20 бесплатных запросов в день. Мы можем разрешать и запрещать конкретные вызовы, ставить предварительные условия для пропуска вызовов, ограничивать их скорость и количество. Если пользователь сделал 20 запросов, последующие не обрабатываются.

Управление квотами может использоваться в тех случаях, когда требуется, чтобы все, кто использует сервис, имели одинаковую скорость доступа. Предварительные условия могут включать в себя такие вещи, как, например, прохождение сервером проверки подлинности, ICL и его присутствие в белом списке. Это позволяет производителям и пользователям смотреть на эту телеметрию с помощью сервисов. Наконец, Mixer собирает результаты обработки запросов и ответов, годные для телеметрии.

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

Как начать работать с Istio

Istio поддерживает предыдущие версии kubernetes, но новая функция инициализатора, о которой я рассказывал, находится в версиях 1.7 и выше. Это альфа-функция в kubernetes. Я рекомендую использовать Google Container Engine Alpha clusters. У нас есть кластеры, которые вы можете включить на определенное количество дней и при этом использовать все продакшн возможности в них.

Мы только что выпустили версию 0. Прежде всего Istio — это проект с открытым исходным кодом на github. В версии 0. 2. С версии 0. 1 можно было управлять объектами в пределах одноименного пространства имен kubernetes. Еще мы добавили доступ для возможности управления сервисами, которые запускаются на виртуальных машинах. 2 мы поддерживаем работу в собственном пространстве имен и кластере kubernetes. В дальнейшем Istio будет поддерживать другие платформы, такие как Cloud Foundry. Вы можете развернуть Envoy на виртуальной машине и обезопасить сервисы, которые работают на ней.

Если у вас есть кластер под управлением Google Container Engine на 1. Краткое руководство по установке фреймворка находится здесь. 8 с включенными альфа-функциями, то установка Istio — это всего лишь одна команда.

Если вам понравился этот доклад, приходите 14 октября на конференцию DevOops 2018 (Питер): там можно будет не только послушать доклады, но и пообщаться с любым докладчиком в дискуссионной зоне.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть