Поиск и регистрация сервисов с Consul

Допустим, есть у нас распределённое приложение, в которое входят два вида сервисов: web и db. Для большей надёжности они запускаются сразу в нескольких экземплярах, на разных хостах, иногда приходят в онлайн, иногда уходят, какие-то подвисли, какие-то ещё нет… В общем, хаос. Как в таком случае отдельно взятому сервису web отыскать себе живой db?

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

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

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

Но её и не обязательно решать самому, когда для этого уже есть инструменты. Например, Consul.

Поиск и регистрация сервисов с Consul

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

Вот как это работает. Мы устаналиваем Консул-агент на каждом хосте, где планируют жить сервисы. Задача этого агента — знать, какие сервисы рядом с ним работают, и живы ли они. Потом эту информацию он отдаёт Консул-серверу, а тот, собрав данные со всего кластера, делится ей со всеми через DNS, HTTP API запросы или даже через UI.

План

Сегодня мы построим маленький кластер таких агентов. Подсунем им пару-тройку сервисов для знакомства, а затем попробуем собрать списки сервисов через HTTP или DNS запросы.

Я думаю, что трёх виртуальных машин для этого хватит: одна для Consul сервера, и две других для агентов с сервисами. Так как у меня локально уже установлены VirtualBox и docker-machine, я буду использовать их для надругательства над хостами, но любой другой гипервизор с провизором виртуальных машин тоже бы подошли.

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

Но куча слов написано, ничего не сделано — пора за работу.

Создаём кластер

Установка Consul сервера

Начнём с начала: нам нужна виртуальная машина. Следующей командой можно создать вполне себе готовый Linux хост по имени consul-server, используя VirtualBox и docker-machine:

Это займём от силы минуту-две, и в результате получится готовая машина, в которую мы тут же зайдём по SSH для «установки» Consul:

Легкотня.

Настройка сервера

Сейчас будет немного сложнее. То есть, всё просто, но очень много.

Наш Консул должен уметь три вещи:

  1. выглядеть как сервер,
  2. раздавать какой-нибудь UI,
  3. принимать входящие соединения от других Консул-агентов, чтобы собрать кластер.

Во-первых, чтобы сделать из Consul агента Consul сервер нужно просто передать -server параметр при запуске. Я видел документацию, этого действительно хватает.

Во-вторых, -ui параметр включает веб-UI. Серьёзно. Правда, слушать он будет на  127.0.0.1, что для сервиса внутри виртуальной машины — неудобство. Если найти внешнюю апйишку этой машины, то её можно будет передать через -client параметр, и тогда UI станет доступен снаружи.

Найти же внешнюю айпишку — просто. Изнутри её можно узнать, посмотрев настройки eth1 сетевого интерфейса (например,  ifconfig eth1). А снаружи — через  docker-machine ip consul-server.

В-третьих, сервер должен уметь принимать запросы от других Консул-агентов. Внешнюю айпишку из предыдущего шага можно так же передать в качестве  -advertise %ip%  параметра, и задача решена.

Наконец, Consul откажется запускаться, если ему не указать, где хранить данные. Чтобы его заткнуть, хватит какой-нибудь временной папки, переданной через -data-dir параметр.

Итоговая команда запуска сервера будет выглядеть вот так:

Запускаем, даём серверу немного времени назначить и выиграть выборы лидера кластера, и идём любоваться на web UI по айпишке виртуальной машины и порту 8500:

Consul server

«Nodes» страница показывает все хосты, входящие в кластер. Пока там только один, но это не надолго.

Установка Consul агентов

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

В конфигурации обычного агента есть несколько отличий от серверной. Во-первых, -server больше не нужен. Во-вторых, UI нам тоже больше не нужен — он же есть у сервера.

В-третьих, так как агент должен подсоединиться к существующему кластеру, ему нужно указать айпишку кого-то, кто уже там. consul-server — и есть кластер, его адрес — 192.168.99.104, так что передаём его в -retry-join параметр, и работа сделана.

Итоговые команды запуска агентов выглядят так:

После запуска оба новых агента и хоста появятся в UI сервера:

Consul cluster

Та-дам! Консул-кластер готов. Дело за сервисами.

Регистрация сервисов

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

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

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

После этого мы можем снова пойти на UI сервера, но в этот раз заглянуть на страницу «services»:

Consul services

Теперь там аж пять сервисов: 2 web, 2 db и сам Consul. Все сервисы отмечены как доступные, так что сторонние приложения (да и сами сервисы) могут делать поисковые запросы к Consul, чтобы узнать, где кто находится.

Делаем поисковые запросы

Самый простой поисковый запрос мы уже попробовали: сходили на UI и посмотрели своими глазами. Есть и более масштабируемый способ — сделать запрос по HTTP API или DNS.

Поиск сервисов через HTTP API

Мы можем получить имена всех сервисов кластера такой простой командой:

Конечно, кроме имён тут ничего нет, но для адресов есть другая точка входа:

Здорово, правда? Через чистый HTTP можно разузнать всё о сервисах, которые работают в данном кластере, и как к ним доступиться. Если какой-то сервис упадёт, то его не будет и в результатах запроса.

Поиск сервисов через DNS

Consul сервер ещё может подрабатывать и DNS сервисом. Тот слушает на порту 8600, и если отправить ему сервис-запрос через какую-нибудь dig утилиту, то можно узнать много интересного.

Допустим, нам всё ещё интересно, где находится db сервис:

В ответе есть и полные имена сервисов, и адреса хостов, на которых они живут. Если бы мы запустили этот же запрос ещё раз, то порядок сервисов в ответе стал бы другим. Эту особенность можно использовать для балансировки нагрузки.

Итого

Сегодня мы сделали много всего: создали виртуальные машины, настроили Консул-кластер, зарегистрировали в нём сервисы и поискали их через HTTP API и DNS. И хотя это было много отдельных шагов, все они были относительно несложные: запустить экзешник, найти внешний айпи адрес, задать JSON с сервисами, и т.п. — не ракету построить.

Конечно, задать сервис в конфигурации через "name": "web" — не то же самое, что действительно установить nginx на хосте. Но Консулу, на самом деле, по барабану. Если его проверки говорят, что с сервисом всё в порядке, значит он существует, и с ним действительно всё в порядке. Как эти проверки выглядят, мы и посмотрим в следующий раз.

2 комментария для “Поиск и регистрация сервисов с Consul

  1. А для первого консула не нужно задавать опцию -bootstrap? Без неё у меня по кругу валило
    {code}
    2019/11/12 14:49:39 [ERR] agent: failed to sync remote state: No cluster leader
    2019/11/12 14:49:48 [ERR] agent: coordinate update error: No cluster leader
    {code}

    когда задал опцию -bootstrap
    $ ./consul agent -server -ui -client 192.168.99.109 -data-dir /tmp/consul -advertise 192.168.99.109 -bootstrap
    то кластер создался.

    1. Возможно, теперь этот параметр действительно нужен. Я практически уверен, что когда пост создавался, оно работало без него, но всё-таки прошло 2 года — в нашей индустрии практически вечность.

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

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