Что такое service discovery

Свой облачный хостинг за 5 минут. Часть 2: Service Discovery

Что такое service discovery. Смотреть фото Что такое service discovery. Смотреть картинку Что такое service discovery. Картинка про Что такое service discovery. Фото Что такое service discovery

Привет Хабр! В предыдущей статье я рассказал как построить свой облачный хостинг за 5 минут, используя Ansible, Docker и Docker Swarm. В этой части я расскажу о том, как сервисы, запущенные в облаке, находят друг друга, как происходит балансировка нагрузки между ними и обеспечивается их отказоустойчивость.

Это вводная статья, здесь мы сосредоточимся на обзоре инструментов, которые будут решать проблему «обнаружения сервисов» в нашем облаке. В следующей части мы приступим к практике, поэтому я решил дать вам время поближе ознакомиться с ними.

Содержание

Проблема

Давайте разберем наиболее типичную проблему и ее распространенное решение – у нас есть веб-приложение и мы должны обеспечить балансировку нагрузки и его отказоустойчивость.

Мы можем запустить несколько копий нашего веб-приложения, которые будет мониторить Supervisor. Supervisor будет перезапускать наше веб-приложение, если возникнут какие-то ошибки, а также будет добавлять такие события в журнал. Проблему балансировки нагрузки решит установка Nginx. Конфигурация Nginx будет выглядеть примерно так:

Работать указанная конфигурация будет так – если в течение 5 секунд число неудачных попыток при обращении к одному из веб-приложений достигнет 3-ех, то такое приложение отметится как неработоспособное на 5 секунд (если оно упало с ошибкой, то Supervisor перезапустит его). Таким образом вся нагрузка равномерно распределиться только между рабочими копиями приложений.

Недостатки

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

Но мы строим облако, где будет запущено то или иное приложение – мы не знаем. Нагрузка у нас может меняться для разных сайтов/веб-приложений по разному, поэтому неплохо бы иметь возможность менять количество запущенных копий наших приложений в зависимости от ситуации. Другими словами – мы не можем заранее настроить Nginx/Apache/etc на такую конфигурацию.

Было бы круто, если бы Nginx и другие наши сервисы приспособились к динамической природе нашего облака. Решением именно этой задачи мы и займемся в этой статье.

Требования

Нам нужно место, где наши сервисы смогут регистрировать себя и получать информацию друг о друге. Docker Swarm, который мы начали использовать в предыдущей статье, «из коробки» умеет работать с etcd, Consul и Zookeeper.

Нам необходимо, что бы наши сервисы автоматически регистрировались и удалялись из вышеуказанных систем (мы же не будем обучать этому каждое приложение). Для этих целей мы используем Registrator (ниже рассмотрим его более подробно), который «из коробки» работает с Consul, etcd и SkyDNS 2 (поддержка Zookeeper в планах).

Наши сервисы должны иметь возможность находить друг друга с помощью DNS запросов. Эту задачу могут решить Consul и SkyDNS 2 (который работает в паре с etcd).

Мониторинг здоровья сервисов нам тоже необходим. Он доступен нам в Consul (который мы и будем использовать) «из коробки» и его поддерживает Registrator (он должен передавать информацию о том, как должен происходить мониторинг того или иного сервиса).

Последнее, но не менее важное – нужен сервис для автоматической конфигурации наших составляющих. Если мы запустили 10 копий одного веб-приложения и 20 копий другого, он должен понимать и немедленно реагировать на это (меняя конфигурацию Nginx, например). Выполнять эту роль будет Consul Template (ниже рассмотрим его более подробно).

Consul

Что такое service discovery. Смотреть фото Что такое service discovery. Смотреть картинку Что такое service discovery. Картинка про Что такое service discovery. Фото Что такое service discovery

Из перечисленных выше вариантов (Consul, Zookeeper, etcd), Consul является наиболее самостоятельным проектом, который в состоянии решить нашу проблему обнаружения сервисов «из коробки».

Не смотря на то, что Consul, Zookeeper и etcd расположены здесь в одном ряду, я бы не стал их сравнивать между собой. Все 3 проекта реализуют распределенное key/value хранилище и на этом их общие черты заканчиваются.

Consul нас обеспечит DNS сервером, которого нет в Zookeeper и etcd (можно добавить с помощью SkyDNS 2). Более того, Consul даст нам мониторинг здоровья (которым не могут похвастаться ни etcd, ни Zookeeper), что также необходимо для полноценного Service Discovery.

В нагрузку с Consul мы получим Web UI (демо которого можно глянуть уже сейчас) и качественную официальную документацию.

Registrator

Что такое service discovery. Смотреть фото Что такое service discovery. Смотреть картинку Что такое service discovery. Картинка про Что такое service discovery. Фото Что такое service discovery

Registrator получает информацию от Docker‘а о запуске/остановке контейнеров (через сокет-соединение, с помощью Docker API) и добавляет/удаляет их в/из Consul‘a.

Информацию о том или ином сервисе Registrator автоматически получает на основе опубликованных портов и из переменных окружения Docker контейнера. Другими словами – это работает с любыми контейнерами, которые у вас есть и требует дополнительного конфигурирования только в том случае, если необходимо переопределить параметры полученные автоматически.

И раз все наши сервисы работают исключительно в Docker контейнерах (и сам Registrator в том числе), то в Consul‘е всегда будет информация о всех запущенных сервисах нашего облака.

Это все конечно круто, но еще круче то, что Registrator может рассказать Consul‘у, как проверять здоровье наших сервисов. Делается это с помощью тех же переменных окружения.

Consul умеет проверять здоровье сервисов, если для сохранения информации о них используется Consul Service Catalog (который мы и задействуем).

Если же используется Consul Key-value Store (который тоже поддерживается Registrator’ом и использует, например, Docker Swarm для сохранения информации о Docker нодах), такой функции нет.

Давайте рассмотрим пример:

После подобного запуска, список наших сервисов у Consul‘а будет выглядеть следующим образом:

Как вы видите, на основе опубликованных портов Registrator сделал вывод, что зарегистрировать надо 2 сервиса (http и https). Более того, у Consul‘a теперь есть вся необходимая информация о том, как проверять здоровье этих сервисов.

Во втором случае – каждые 15 секунд Consul будет дергать переданный нами URL. Если код ответа сервера будет 2xx, то наш сервис «здоров», если 429 Too Many Requests, то в «экстренном состоянии», если все остальное, то «земля ему пухом».

Больше примеров и более подробную информацию вы может почерпнуть из официальной документации.

Consul Template

Что такое service discovery. Смотреть фото Что такое service discovery. Смотреть картинку Что такое service discovery. Картинка про Что такое service discovery. Фото Что такое service discovery
Мы решили где хранить информацию о всех сервисах нашего облака, а также как она будет туда попадать и автоматически там обновляться. Но мы еще не разобрались, как же будем получать информацию от туда и как, в последствии, будем её передавать нашим сервисам. Именно этим и будет заниматься Consul Template.

Для этого надо взять конфигурационный файл нашего приложения (которое мы хотим настроить) и сделать из него шаблон, согласно правилам HashiCorp Configuration Language.

Давайте рассмотрим простой пример с конфигурационным файлом Nginx:

После того, как мы объясним Consul Template где находится данный шаблон, куда положить результат и какую комманду выполнить (он это тоже умеет) при его изменении (в данном случае перезагрузить Nginx), начнётся магия. В данном случае Consul Template получит адреса и номера портов всех копий приложения «cool-app«, которые помечены тегом «tag1» и находятся в «здоровом» состоянии и добавит их в конфигурационный файл. Если таких приложений нет, тогда, как вы уже догадались, останется все, что находится после <>.

При каждом добавлении и удалении сервиса «cool-app» с тегом «tag1» конфигурационный файл будет перезаписываться, а после этого Nginx будет перезагружен. Все это происходит автоматически и не требует вмешательства, мы просто запускаем нужное количество копий нашего приложения и не о чём не беспокоимся.

Больше примеров вы можете найти в официальной документации.

Заключение

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

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

На этом все. Всем спасибо за внимание. Стабильных вам облаков и удачи!

Подписывайтесь на меня в Twitter, я рассказываю о работе в стартапе, своих ошибках и правильных решениях, о python и всём, что касается веб-разработки.

Источник

Consul.io Часть 1

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

Что такое service discovery. Смотреть фото Что такое service discovery. Смотреть картинку Что такое service discovery. Картинка про Что такое service discovery. Фото Что такое service discovery

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

Распределенные архитектуры(SOA) и проблемы их построения

Что такое discovery?

Discovery — это инструмент (или набор инструментов) для обеспечения связи между компонентами архитектуры. Используя discovery мы обеспечиваем связность между компонентами приложения, но не связанность. Discovery можно рассматривать как некий реестр метаинформации о распределенной архитектуре, в котором хранятся все данные о компонентах. Это позволяет реализовать взаимодействие компонентов с минимальным ручным вмешательством (т.е. в соответствии с принципом ZeroConf).

Роль discovery в процессе построения распределенной архитектуры

Консистентность
Распределенная архитектура подразумевает, что компоненты можно масштабировать горизонтально, при этом они должны владеть актуальной информацией о состоянии кластера. Discovery-сервис обеспечивает (де)централизованное хранилище и доступ к нему для любого узла. Компоненты могут сохранять свои данные и информация будет доставлена ко всем заинтересованным участникам кластера.

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

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

Consul.io как реализация discovery

В данной статье рассматривается реализация discovery на базе Consul.
Consul — это децентрализованный отказоустойчивый discovery-сервис от компании HashiCorp (которая разрабатывает такие продукты как Vagrant, TerraForm, Otto, Atlas и другие).

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

Что еще необходимо знать про Consul:

Для распространения информации использует алгоритмы, которые базируются на модели eventual consistency.
Агенты для распространения информации используют протокол gossip.
Серверы для выбора лидера используют алгоритм Raft.
Лидер — это сервер, который принимает все запросы на изменение информации. Если провести аналогию с БД, то это master в контексте master/slave — репликации. Все остальные серверы реплицируют данные с лидера. Ключевое отличие от БД-репликации в том, что в случае выхода из строя лидера все остальные серверы запускают механизм выборов нового лидера и после выборов автоматически начинают реплицироваться с него. Механизм переключения полностью автоматический и не требует вмешательства администратора.
Каждый инстанс может работать в двух режимах: агент и сервер. Разница в том, что агент является точкой распространения информации, а сервер — точкой регистрации. Т.е. агенты принимают запросы только на чтение, а сервер может выполнять изменения уже имеющейся информации (регистрация и удаление сервисов). Фактически мы, в любом случае, выполняем запрос к локальному адресу, разница лишь в том, что запрос на чтение будет обработан агентом на локальном хосте, а запрос на изменение данных будет переадресован лидеру, который сохранит и распространит данные по всему кластеру. Если наш локальный агент не является лидером в данный момент, то наш запрос на изменение будет полностью обработан локально и распространен по кластеру.

Использование Consul в кластере

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

Что такое service discovery. Смотреть фото Что такое service discovery. Смотреть картинку Что такое service discovery. Картинка про Что такое service discovery. Фото Что такое service discovery

Агенты Consul, запущенные в режиме server, помимо своей основной роли, получают еще и роль потенциального лидера кластера. Рекомендуется использовать в кластере не менее трех агентов в режиме server для обеспечения отказоустойчивости. Использования режима server не накладывает никаких ограничений на основную функциональность агента.
При вводе нового узла в кластер, нам необходимо знать адрес любого узла в кластере. Выполнив команду:
consul join node_ip_address
мы регистрируем новый узел в кластере и, спустя короткое время, информация о состоянии всего кластера будет доступна этому узлу. Соответственно, новый узел окажется доступным для запросов от остальных узлов.

Типы узлов: internal, external

Рассмотрим пример запроса регистрации компонента (JSON должен быть передан в PUT-запросе):

Пример запроса на удаление компонента из каталога:
http://localhost:8500/v1/agent/service/deregister/[ServiceID]

Пример запроса на перевод сервиса в режим maintenance:
http://localhost:8500/v1/agent/service/maintenanse/[ServiceID]?enable=true|false

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

Если нам необходимо зарегистрировать какой-либо внешний сервис и у нас нет возможности “научить” его регистрироваться в Consul самостоятельно, то мы можем зарегистрировать его не как сервис-провайдер, а именно как внешний сервис (external service). После регистрации мы сможем получить данные о внешнем сервисе через DNS:

Помимо HTTP API вы можете использовать конфигурационные файлы агента с описанием сервисов.

Источник

Экосистема Docker: обнаружение сервисов (Service Discovery) и распределённые хранилища конфигураций (Distributed Configuration Stores)

Published on June 29, 2015

Серия туториалов

Этот туториал является 3-ой частью из 5-ти в серии статей Экосистема Docker.

Введение

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

Одной из ключевых технологий, на которую опираются многие инструменты работающие с Docker, является обнаружение сервисов (Service discovery). Обнаружение сервисов позволяет приложению или компоненту получать информацию об их окружении и “соседях”. Как правило, данный функционал реализуется при помощи распределённого хранилища “ключ-значение” (“key-value”), которое также может служить для хранения деталей конфигурации. Настройка инструмента обнаружения сервисов позволяет Вам разделить runtime-конфигурацию и сам контейнер, что позволяет использовать один и тот же образ в нескольких окружениях.

В данном руководстве мы обсудим преимущества обнаружения сервисов в кластеризованном Docker-окружении. Мы сфокусируемся на основных концепциях, но так же приведём и более конкретный примеры, где это будет уместно.

Обнаружение сервисов и глобально доступные хранилища конфигураций (Globally Accessible Configuration Stores)

Главная идея, лежащая в основе обнаружения сервисов, состоит в том, что любой новый экземпляр приложения должен быть в состоянии программно определить детали своего текущего окружения. Это необходимо для того, чтобы новый экземпляр мог подключиться к существующему окружению приложения без ручного вмешательства. Инструменты обнаружения сервисов обычно реализованы в виде глобально доступных реестров, которые хранят информацию об экземплярах приложений и сервисов, запущенных в данный момент. Большую часть времени реестр распределён по доступным в инфраструктуре хостам, чтобы сделать систему устойчивой к ошибкам (fault tolerant) и масштабируемой.

Хотя основная цель инструментов по обнаружения сервисов состоит в предоставлении деталей подключения для связи компонентов вместе, они так же могут использоваться для хранения любого типа конфигурационной информации. Многие приложения используют эту возможность в своих целях, сохраняя свою конфигурационную информацию с помощью инструмента обнаружения сервисов. Если контейнеры сконфигурированы таким образом, что они знают о необходимости проверять эти детали, они могут модифицировать своё поведение на основе найденных данных.

Как работает обнаружение сервисов?

Каждый инструмент обнаружения сервисов предоставляет API, который компоненты могут использовать для записи или получения данных. По этой причине для каждого компонента адрес обнаружения служб (service discovery address) должен быть либо жестко прописан в самом приложении/контейнере, либо предоставляться во время исполнения (runtime). Обычно, обнаружения сервисов реализовано в виде хранилища “ключ-значение”, доступного через стандартные методы http.

Инструмент обнаружения сервисов работает следующим образом: при запуске какого-либо сервиса, этот сервис регистрирует себя с помощью инструмента обнаружении сервисов. Инструмент обнаружения сервисов записывает всю информацию об этом сервисе, которая может понадобиться другим сервисам, работающим с данным, вновь запущенным, сервисом. Например, база данных MySQL может зарегистрировать IP-адрес и порт, на котором запущен демон, и, опционально, имя пользователя и учетные данные для входа.

При запуске потребителя первого сервиса, этот потребитель может запросить в реестре обнаружения сервисов информацию о первом сервисе. После этого потребитель может взаимодействовать с необходимыми компонентами, основываясь на полученной информации. Хорошим примером является балансировщик нагрузки (load balancer). Он может найти все backend-сервера, на которые можно распределять трафик, посылая запрос к службе обнаружения сервисов и изменяя свою конфигурацию соответствующим образом.

Как конфигурационное хранилище связано с обнаружением сервисов?

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

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

Как конфигурационное хранилище помогает в управлении кластером?

Вот пример информации о хосте, которая может храниться в распределенном хранилище “ключ-значение”:

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

Что насчёт обнаружения отказов (Failure Detection)?

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

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

Что насчёт перенастройки сервисов при изменении параметров?

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

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

Что насчет безопасности?

Ответ на этот вопрос во многом зависит от того, какие данные Вы помещаете в хранилище, и сколько уровней безопасности Вы считаете необходимыми для защиты своих данных. Почти все системы обнаружения сервисов позволяют шифровать соединения через SSL/TLS. Для некоторых сервисов приватность может быть не очень важна, и помещения системы обнаружения служб в приватную сеть может быть достаточно. Однако, для большинства сервисов, скорее всего, будет лучше предусмотреть дополнительные меры безопасности.

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

Какие инструменты обнаружения сервисов наиболее популярны?

Теперь, когда мы обсудили некоторые общие особенности инструментов обнаружения сервисов и глобально распределенных хранилищ “ключ-значение”, мы можем упомянуть некоторые проекты, связанные с этими концепциями.

Вот список некоторых из наиболее распространённых инструментов обнаружения сервисов:

Некоторые другие проекты, расширяющие базовые возможности инструментов обнаружения сервисов:

Заключение

Обнаружения сервисов и глобальные конфигурационные хранилища позволяют Docker-контейнерам адаптироваться к их текущему окружению и включаться в существующую систему компонентов. Это необходимое условие для предоставления простой автоматической масштабируемости и развёртывания путем предоставления компонентам возможности отслеживать изменения в их окружении и реагировать на них.

В следующем руководстве мы обсудим способы взаимодействия Docker-контейнеров и хостов при помощи настраиваемых сетевых конфигураций.

Источник

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

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