consul что это за программа
Основы работы с системой обнаружения сервисов Consul
Consul – это распределенная, высокодоступная система обнаружения и конфигурирования сервисов. Consul может представить сервисы и ноды в гибком и мощном интерфейсе, который позволяет клиентам всегда иметь актуальный вид инфраструктуры, в которую они входят.
Consul предоставляет множество различных функций, которые обеспечивают согласованность информации о вашей инфраструктуре. Сюда входят механизмы обнаружения сервисов и нод, система тегов, проверка работоспособности, общесистемное хранение ключей и значений и многое другое.
В этом мануале мы рассмотрим базовые функции и методы работы с Consul. В следующем мануале вы узнаете, как запустить Consul в среде производства.
Требования и цели
В этом мануале вы узнаете, как использовать Consul для создания системы обнаружения и настройки сервисов вашей инфраструктуры.
Для демонстрации примеров мы будем использовать три сервера и один клиент. Серверы используются для обработки запросов и постоянного согласования системы. Клиент также является членом системы и может подключаться к серверам для получения информации об инфраструктуре. Клиенты могут также содержать сервисы, которыми будет управлять Consul.
Для данного мануала (и остальных мануалов этой серии) вам понадобятся 4 компьютера. Первые три будут серверами, а последний будет агентом (который действует как клиент и может использоваться для запроса информации о системе).
Чтобы в дальнейшем у вас была возможность реализовать некоторые механизмы безопасности, вам нужно назвать все машины в рамках одного домена. Это значит, что в будущем вы сможете использовать wildcard SSL-сертификат.
Имя хоста | IP-адрес | Роль |
server1.example.com | 192.0.2.1 | Загрузочный сервер consul |
server2.example.com | 192.0.2.2 | Сервер consul |
server3.example.com | 192.0.2.3 | Сервер consul |
agent1.example.com | 192.0.2.50 | Клиент consul |
Для работы мы используем 64-битные серверы Ubuntu 14.04, но любой современный дистрибутив Linux будет работать аналогичным образом.
Загрузка и установка Consul
Сначала нужно загрузить и установить consul на каждой из наших машин. Для каждой из перечисленных выше машин следует предпринять следующие шаги. Вы должны войти в систему как root.
Установите утилиту unzip для извлечения исполняемого файла Consul. Также нужно использовать приложение screen, чтобы поддерживать несколько сеансов в одном окне терминала. Это полезно, поскольку Consul обычно занимает весь экран, когда не работает как сервис.
Обновите индекс локальных пакетов и установите требуемое ПО:
apt-get update
apt-get install unzip screen
Запустите сессию screen:
Нажмите enter, если вы получите сообщение об авторском праве. После этого вы вернетесь в окно терминала, но теперь он работает в сессии screen.
Теперь можно загрузить Consul. Страница проекта предоставляет ссылки для загрузки бинарных пакетов для Windows, OS X и Linux.
Перейдите на эту страницу и щелкните правой кнопкой мыши на операционной системе и архитектуре, которая используется на ваших серверах. В этом руководстве мы будем использовать ссылку «amd64» в разделе «linux». Скопируйте ссылку на пакет.
В терминале перейдите в каталог /usr/local/bin, где будет храниться исполняемый файл. Введите wget и пробел, а затем вставьте URL-адрес, который вы скопировали с сайта:
cd /usr/local/bin
wget https://dl.bintray.com/mitchellh/consul/0.3.0_linux_amd64.zip
После этого можно распаковать и удалить архив:
Теперь у вас есть доступ к команде consul.
Запуск сервера consul
Чтобы начать работу с consul, нужно запустить серверы. При настройке в многосерверной среде этот шаг необходимо выполнить поэтапно.
Первое, что нужно сделать, это запустить программу consul на одном из серверов в режимах server и bootstrap. Режим server означает, что consul запускается как экземпляр сервера, а не клиент. Параметр bootstrap используется для первого сервера. Это позволяет ему стать ведущим сервером кластера без выборов (так как это будет единственный доступный сервер).
В таблице хостов (в требованиях) server1 указан как загрузочный. На server1 запустите загрузку:
Сервер запустится в текущем терминале, данные логов будут выводиться по мере возникновения событий. В конце данных лога вы увидите следующие строки:
Как видите, лидер кластера не был найден, так как это первая нода. Однако, поскольку в команде есть опция bootstrap, этот сервер смог сам войти в состояние лидера, чтобы инициировать кластер с одним хостом.
Запуск других серверов
На server2 и server3 теперь можно запустить сервис consul без опции bootstrap:
Вы также увидите логи для этих серверов. В конце будут такие предупреждения:
Это происходит потому, что они не могут найти лидера кластера и не могут сами стать лидерами. Это происходит потому, что серверы еще не связаны друг с другом.
Теперь нужно объединить эти серверы. Это можно сделать по-разному, но самый простой способ – подключиться с сервера server1.
Поскольку сервер consul запускается в текущем окне терминала server1, нужно создать еще один терминал screen, чтобы выполнить дополнительные операции. Создайте новое окно терминала в текущей сессии server1, набрав:
Это откроет новый экземпляр терминала, сохранив предыдущую сессию. Вы можете переключаться между терминалами, набрав:
Вернитесь в новый терминал, подключитесь к другим двум экземплярам, указав их IP-адреса:
consul join 192.0.2.2 192.0.2.3
Это должно немедленно соединить все три сервера в один кластер. Вы можете проверить это:
consul members
Node Address Status Type Build Protocol
server1.example.com 192.0.2.1:8301 alive server 0.3.0 2
server2.example.com 192.0.2.2:8301 alive server 0.3.0 2
server3.example.com 192.0.2.3:8301 alive server 0.3.0 2
Вы можете получить эту информацию с любого другого сервера, создав новый сеанс терминала в screen, как описано выше.
Удаление загрузочного сервера и повторное подключение в качестве обычного сервера
Теперь все три сервера объединены в кластер.
Поскольку server1 был запущен в режиме начальной загрузки, он имеет право принимать решения, не обращаясь к другим серверам. Но серверы в кластере должны действовать как равные и принимать решения по кворуму, потому нужно удалить эту привилегию server1 после того, как кластер был загружен.
Для этого остановите сервис consul на server1. Это позволит оставшимся в кластере машинам выбрать лидера. Затем нужно перезапустить consul на server1 без опции bootstrap и снова подключить его к кластеру.
На сервере server1 вернитесь в терминал consul:
Перезапустите его без опции bootstrap:
Вернитесь в терминал и заново подключите сервер к кластеру.
CTRL-A N
consul join 192.0.2.2
Теперь все три сервера находятся в одинаковой позиции. Они будут копировать информацию друг друга и обрабатывать ситуации, когда один из них становится недоступным. Теперь к кластеру могут присоединиться другие серверы: просто запустите сервер без bootstrap и добавьте его в кластер.
Добавление клиента и обслуживание веб-интерфейса
Теперь, когда кластер доступен, можно подключиться к нему с помощью клиентской машины.
Разместить веб-интерфейс consul можно на клиентской машине (это позволит взаимодействовать с кластером и следить за его состоянием). Для этого перейдите на страницу загрузки веб-интерфейса. Кликните правой кнопкой мыши на кнопке загрузки и скопируйте ссылку.
На клиентской машине перейдите в домашний каталог. Введите wget и пробел, а затем вставьте URL-адрес, который вы скопировали со страницы:
Когда загрузка будет завершена, распакуйте и удалите архив:
Здесь будет каталог dist, который содержит все файлы, необходимые для отображения веб-интерфейса. Нужно просто указать этот каталог при подключении к кластеру.
Чтобы подключиться к кластеру, используйте вызов consul, который вы использовали для серверов, но с другими флагами.
Чтобы машина работала в режиме клиента, ей не нужен флаг server. По умолчанию интерфейс каждой ноды доступен с по локальному интерфейсу loopback. Чтобы получить доступ к веб-интерфейсу удаленно, вместо этого нужно указать внешний IP-адрес клиента.
Направьте consul в каталог, в котором размещен веб-интерфейс, чтобы обслуживать этот контент. Кроме того, сервер сразу присоединится к кластеру, передавая IP-адрес одного из серверов в. Это позволит избежать необходимости присоединяться после.
Команда подключения получится довольно длинная. Она будет выглядеть так:
Клиент подключится к кластеру как к обычный агент (не сервер). Этот агент будет отвечать на запросы на своем внешнем IP-адресе вместо обычного интерфейса 127.0.0.1. Потому вам нужно будет использовать дополнительный флаг rpc-addr в любых командах consul.
Например, если вы хотите запросить список членов кластера у клиента, вам нужно будет указать правильный интерфейс и порт, который вы выбрали:
Вывод может показаться запутанным, но он дает возможность подключиться к интерфейсу consul. Для этого вам нужно указать адрес клиента и добавить :8500/ui в браузере:
Вы можете посмотреть разные меню и изучить интерфейс. Он позволяет визуализировать кластер и отслеживать состояние ваших машин и сервисов.
Добавление сервисов и проверок
Теперь в consul нужно добавить сервисы. Вы можете сделать это несколькими способами, но проще всего создать каталог конфигурации для хранения определений сервисов.
Для примера установим Nginx на клиентскую машину. Остановите текущую сессию клиента:
apt-get install nginx
Создайте каталог конфигураций для хранения определений сервисов:
Внутри этого каталога создайте файл web.json, который описывает веб-сервис:
В этом файле должна быть структура для определения сервиса. В рамках этой структуры мы определим подструктуру для проверки работоспособности сервиса.
Базовая структура выглядит следующим образом:
Здесь нужно определить имя сервиса и сообщить consul, какой порт он должен проверять. Кроме того, можно предоставить consul список тегов, которые можно использовать для произвольной категоризации сервиса (для сортировки).
В итоге структура выглядит так:
Это все, что нужно для определения сервиса. Однако также нужно определить метод, с помощью которого consul может проверить работоспособность сервиса. Обычно consul копирует ручные проверки системного администратора.
Для проверки данного сервиса добавьте простой веб-запрос curl (как говорится в документации consul). На самом деле вам не нужно знать, что можно извлечь с помощью curl, главное – удалось ли выполнить команду без ошибок. Потому весь вывод команды можно сбросить.
Также нужно установить интервал, в который будет выполняться проверка. Это значение всегда является компромиссом между производительностью и актуальностью информации. Чтобы относительно скоро узнать, если пошло не так, установите небольшой интервал:
<
«service»: <
«name»: «web server»,
«port»: 80,
«tags»: [«nginx», «demonstration»],
«check»: <
«script»: «curl localhost:80 > /dev/null 2>&1»,
«interval»: «10s»
>
>
>
Сохраните и закройте файл.
Теперь можно просто перезапустить сессию клиента consul и направить на каталог:
Нода перезапустится и подключится к кластеру. Если вы вернетесь в интерфейс, вы увидите в нем сервис.
Вернитесь на клиентскую машину, создайте новый терминал и остановите веб-сервер.
CTRL-A C
service nginx stop
Обновив UI, вы увидите, что теперь проверка показывает, что сервис не работает.
Заключение
Теперь у вас есть общее представление о том, как работает consul. Примеры, приведенные в этом мануале, не отображают пользы consul в среде производства. Об этом мы поговорим в следующем мануале.
Установка агента Consul и примеры регистрации сервисов
Установленный агент Consul позволяет обмениваться информацией с кластером, отправляя состояние работы сервисов, которые запущены на узле. Мы рассмотрим процесс установки агента на компьютер под управлением Linux на базе Deb (Ubuntu, Debian) или RPM (Rocky Linux, CentOS). Также мы приведем примеры регистрации и настройки проверки сервисов.
Подготовка системы
Предварительно, необходимо настроить брандмауэр. Открываем порты 8300,8301,8302,8500. В зависимости от системы управления netfilter, команды будут отличаться.
а) iptables (как правило для систем на базе deb):
Для сохранения правил используем один из методов, предложенных в данной инструкции.
б) firewalld (чаще для RPM-based):
Установка агента
На различные системы агент устанавливается, почти, одинаково.
Для начала, установим дополнительные пакеты:
Для этого, как раз, используются разные команды (в зависимости от операционной системы).
apt install wget unzip
yum install wget unzip
Теперь можно приступать к установке консула.
На странице со списком релизов необходимо посмотреть на все версии и выбрать необходимую. Также мы можем посмотреть версию consul на сервере:
. и установить такую же.
Так или иначе, создаем переменную с номером версии:
И скачиваем архив с бинарным файлом:
Распаковываем его в каталог /usr/bin:
Проверяем, что команды консул выполняются:
Мы должны увидеть версию программы:
Настройка и запуск агента
Настроим запуск агента в качестве сервиса. Для этого мы создадим юнит в systemd.
Создаем учетную запись, от которой будет работать агент:
* в данном примере мы создадим системную (-r) учетную запись consul. Для удобства восприятия мы также добавим комментарий (-c).
Создаем каталоги для приложения консул:
И выставим на них соответствующие права:
chown consul:consul /var/lib/consul /etc/consul.d
chmod 775 /var/lib/consul /etc/consul.d
* в данном примере мы указали, что владельцем данных каталогов будет созданная учетная запись consul. Права будут полные у владельца, остальные смогут читать данные.
Создаем конфигурационный файл:
<
«server»: false,
«datacenter»: «dc1»,
«node_name»: «agent01»,
«data_dir»: «/var/lib/consul»,
«bind_addr»: «192.168.0.100»,
«client_addr»: «127.0.0.1»,
«retry_join»: [«192.168.0.15», «192.168.0.20», «192.168.0.25»],
«encrypt»: «zpjf5a4reDbJFpT6FeaF0LGxD0zBRPSRbIoUkLBt0ps=»,
«log_level»: «warn»,
«enable_syslog»: true,
«telemetry»: <
«disable_compat_1.9»: true
>
>
Consul.io Часть 2
В первой части мы подробно рассмотрели какие проблемы и задачи ставит перед нами распределенная архитектура приложения. Мы определили какие инструменты мы можем использовать для решения этих проблем и отметили важность реализации discovery на начальном этапе проекта. А также, выбрали Consul основным приложением на базе которого мы будем рассматривать реализацию discovery-сервиса.
В заключительной части мы рассмотрим как Consul работает с протоколом DNS, разберем основные запросы к HTTP API, посмотрим какие виды Health Checks мы можем использовать и, конечно, разберем для чего нужен K/V storage. И что самое важное, ближе познакомимся с некоторыми особенностями на практике.
Интерфейс DNS
Узел кластера
Сервис
Запрос на поиск сервиса по имени выполняется на всех узлах кластера. В отличии от запроса на разрешение имени узла, запрос на поиск сервиса предоставляет больше возможностей. Кроме, собственно, IP-адреса сервиса (то есть А-записи) вы можете выполнить запрос на получение SRV-записи и узнать порты, на которых запущен сервис.
Вот так выглядит обычный запрос на поиск всех узлов, на которых запущен сервис с именем rls :
Из этого ответа можно увидеть, что в составе кластера присутствуют два узла, на которых запущен сервис с именем rls и то, что DNS-интерфейс Consul вернул IP-адреса всех узлов. Если мы повторим запрос несколько раз, то увидим, что записи периодически меняются местами, то есть первое место не закреплено за первым найденным сервисом. Это и есть пример простой DNS-балансировки, о которой мы говорили выше.
Если мы запросим SRV-запись, то ответ будет таким:
В ANSWER SECTION перечислены доменные имена узлов в формате, требуемом Consul (обратите внимание, узлов, но не сервисов!) и порты, на которых запущен запрашиваемый сервис. IP-адреса узлов (и, соответственно, сервисов) перечислены в ADDITIONAL SECTION ответа.
SRV-запросы на поиск сервисов в соответствии с RFC-2782
Помимо “обычного” построения доменного имени мы можем построить его по более строгим правилам RFC-2782 для выполнения запроса на получение SRV-записи. Формат имени выглядит так:
_service._tag.service[.datacenter].[domain]
Название сервиса и tag имеют underscore (_) в виде префикса. (В оригинальном RFC вместо tag должно стоять название протокола, это сделано для предотвращения коллизий при запросе).
В случае использования имени в формате RFC-2782, сервис с именем nginx и имеющий tag названный web, будет выглядеть так:
_web._nginx.service.consul
Ответ будет точно таким же, как и в случае “простого” запроса:
По умолчанию, все доменные имена в рамках Consul имеют TTL = 0, то есть совсем не кешируются. Нужно иметь это в виду.
HTTP API
agent
Управление локальным агентом Consul. Все операции, доступные на этом endpoint, затрагивают данные локального агента. Можно получить информацию о текущем состоянии агента, его роли в кластере, а также получить доступ к управлению локальными сервисами. Изменения, выполненные над локальными сервисами, будут синхронизированы со всеми узлами кластера.
coordinate
Consul использует сетевую томографию для вычисления сетевых координат. Эти координаты используются для построения эффективных маршрутов в рамках кластера и многих полезных функций, таких как, например, поиск ближайшего узла с заданным сервисом или переключение на ближайший датацентр в случае аварии. Функции API в этом разделе используются только для получения информации о текущем состоянии сетевых координат.
event
Обработка пользовательских событий. Пользовательские события используются для выполнения каких-либо действий в рамках кластера: например для автоматического деплоя, перезапуска сервисов, запуска определенных скриптов или иных действий в рамках процесса оркестрации.
health
Проверка текущего состояния узлов и сервисов. Данный endpoint используется только для чтения и возвращает текущее состояние узлов и сервисов, а также списки выполняемых проверок.
kv
Этот endpoint имеет только один метод и используется для управления данными в распределенном key/value-хранилище, предоставленным Consul. Единственный метод в этом endpoint выглядит так:
/v1/kv/consul что это за программа
Разница в обработке заключается в методе запроса. GET вернет значение по ключу, PUT сохранит новое значение или перезапишет старое, а DELETE удалит запись.
query
Управление подготовленными запросами (Prepared queries). Подобные запросы позволяют выполнять сложные манипуляции над конфигурацией Consul и могут быть сохранены и выполнены позже. Сохраненным запросам присваивается уникальный ID. C его помощью запрос может быть выполнен в любое время без необходимости повторной подготовки.
session
Механизм сессий в Consul используется для построения распределенных блокировок. Сессии представляют собой связующий слой между узлами, выполняемыми проверками и k/v-хранилищем. У каждой сессии есть имя и оно может быть сохранено в хранилище. Имя используется для реализации блокировок в рамках последовательных действий с узлами и сервисами в конкурентном режиме. Механизм работы сессий описан в документации Consul.
status
Этот endpoint используется для получении информации о статусе кластера. Здесь можно узнать текущего лидера и получить информацию обо всех участниках кластера.
Health Checks
K/V storage
Хранилище, предоставляемое Consul является распределенной key-value базой данных и может использоваться для сохранения любых данных, доступных для любого участника кластера (в соответствии с правилами ACL, конечно же). Сервисы могут сохранять в этом хранилище данные, которые необходимы для других участников кластера. Это могут быть значения конфигурационных опций, результаты каких-либо вычислений или, как мы указали выше, k/v-хранилище может использоваться для реализации распределенных блокировок при помощи механизма сессий. Использование k/v-хранилища позволит нам сделать кластер более эффективным и уменьшить процент ручного вмешательства. Сервисы могут корректировать свое состояние в зависимости от информации в хранилище, гарантированно предоставленным кластером. Обратите внимание: не стоит сохранять в это хранилище какие-либо данные, связанные с бизнес-логикой ваших сервисов. Хранилище, предоставляемое Consul, используется для хранения и распространения метаинформации о состоянии участников кластера, а не о данных, которые они обрабатывают.
Записки программиста
Использование Consul для service discovery и других задач
Многие слышали, что есть такая штука под названием Consul, созданная в HashiCorp, компании, подарившей миру Vagrant, Packer и целый ряд других замечательных вещей. Кто-то даже знает, что Consul предназначен для service discovery, как и, например, etcd или ZooKeeper. Но далеко не всем известно, что помимо service discovery также Consul имеет огромное количество других возможностей. Например, встроенный мониторинг сервисов, распределенные локи, и другие. В этой заметке мы познакомимся с Consul, а также научимся пользоваться хоть и не всем, но существенной частью его функционала.
Коротко о главном
Когда говорят «service discovery», имеют ввиду, что есть некая система, которая знает, где какой сервис находится. Например, вы используете PostgreSQL. У вас есть несколько шардов базы данных, у каждого шарда есть мастер и множество реплик. Когда падает мастер, вручную или автоматически производится фейловер, в результате которого одна из бывших реплик становится мастером. Другими словами, роль мастера является переходящей. Кроме того, число реплик не обязательно является постоянным. Так вот, service discovery — это такая штука, которая может ответить вашему приложению на вопросы «а кто сейчас является мастером у шарда N?» или «дай мне список всех реплик шарда N».
Конечно, можно тупо хранить всю эту информацию в конфигах. Но в случае, когда серверов и приложений на них много, вариант с service discovery становится удобнее. Как минимум, потому что все данные лежат в одном месте, и потому не разъезжаются, а также потому что конфигурация обновляется сильно быстрее, чем при заливке конфигов на все сервера по scp. Также при использовании кластерных платформ вроде Kubernetes, Mesos или Nomad вы не знаете заранее, на каких именно машинах какие сервисы поднимаются и сколько их сейчас, плюс они могут часто переезжать с одной машины на другую. А значит, вы никогда их не найдете, не имея под рукой решение вроде Consul.
Конкретно Consul для решения задачи service discovery предлагает REST API. Также он имеет встроенный DNS сервер, что позволяет использовать его даже в приложениях, которые ничего не знают ни о каком Consul. При этом Consul умеет масштабироваться на несколько датацентров и в отличие, скажем, от etcd, работает не только на Linux и MacOS, но также и на FreeBSD, и даже на Windows. Еще внушает доверие, что HashiCorp тестирует Consul при помощи Jepsen.
В Consul информация о существующих сервисах называется каталогом. Каталог хранится на нескольких серверах Consul, которые общаются между собой при помощи протокола Raft. Помимо серверов также существуют агенты. Агенты устанавливаются на всех машинах, где крутятся сервисы, и сообщают серверам Consul’а текущее состояние как машины, так и сервисов на ней, используя протокол gossip. Таким образом, если машина падает, или одному из сервисов на ней становится плохо, сервера Consul’а узнают об этом, и информация о соответствующих сервисах перестает отдаваться клиентам. Сами сервера также могут быть использованы в качестве агентов.
Помимо service discovery и мониторинга в Consul также есть много другого полезного функционала. С некоторым мы еще успеем познакомимся далее.
Установка и настройка Consul
Все описанные действия были проверены мной на Ubuntu 14.04 LTS, запущенной в трех LXC контейнерах. Скорее всего, на других дистрибутивах Linux и версиях Ubuntu ситуация будет мало чем отличаться. Далее предполагается, что все машины находятся в сети 10.0.3/24.
Consul написан на языке Go и распространяется в виде единственного бинарника (и исходных кодов, само собой разумеется). К сожалению, компания HashiCorp не предоставляет готовых пакетов для Debian/Ubuntu или CentOS/RHEL. Здесь добрый человек создал репозиторий, используя который, можно самостоятельно собрать deb-пакет. Также удалось найти PPA, хоть и не с самой новой версией Consul. Однако ничто не мешает поставить Consul, используя этот PPA, а потом при необходимости подменить бинарник.
Если хотим самый свежак, также выполняем команды вроде таких:
Правим файл /etc/consul.d/20-agent.json как-то так:
… делая тем самом Consul сервером, а не агентом.
На других нодах делаем так же. Затем объединяем их в кластер:
Агенты подключаются аналогично, только в конфиге достаточно указать DC.
Должны увидеть что-то вроде:
Также информацию о кластере можно полчить через API:
Если не работает, курим логи — /var/log/upstart/consul.log.
А так можно пробросить порт до веб-панельки:
Панелька выглядит примерно так (кликабельно, 67 Кб, 1369 x 793):
Она немного глючная, например, не видит появления новых сервисов без нажатия F5. Но в остальном вроде вполне неплоха.
Использование key-value хранилища
Самый простой способ использования Consul — это использовать его тупо в качестве key-value базы данных. В этом случае можно даже не поднимать никаких агентов и не заморачиваться по поводу мониторинга сервисов.
Эти данные разлатаются по вему кластеру. На соседней машине можно сказать:
Как видите, значение лежит в base64, декодировать его можно так:
Заметили выше ModifyIndex? Это поле предусмотрено специально для compare and swap:
Еще можно подождать изменений ключа так:
Если параметр wait не указан, ждать будем вечно.
Service discovery через REST API
… где файл req.json содержит:
Важно! Сервисы нужно добавлять через агент, который крутится на той же машине, что и сам сервис. Иначе сервис добавится, но где-то через минуту будет удален:
Список всех доступных сервисов и их тэги:
Вся информация по одному сервису:
Сказать по правде, не до конца понимаю, почему нужны два поля — Address и ServiceAddress. Подозреваю, это на случай, если мы хотим мониторить нашим агентами сторонние сервисы.
Список сервисов на заданной машине:
Удаление сервиса из агента:
Проверить, жив ли сервис, можно так:
Ответ в этом случае приходит довольно большой, поэтому здесь он не приводится.
Service discovery при помощи DNS
;; QUESTION SECTION:
;postgresql-replica.service.consul. IN A
;; ANSWER SECTION:
postgresql-replica.service.consul. 0 IN A 10.0.3.223
postgresql-replica.service.consul. 0 IN A 10.0.3.224
Можно запросить SRV запись, чтобы в ответе были еще и номера портов:
Ответ в этом случае:
;; QUESTION SECTION:
;postgresql-replica.service.consul. IN SRV
;; ANSWER SECTION:
postgresql-replica.service.consul. 0 IN SRV 1 1 5432
postgresql-slave-2.node.dc1.consul.
postgresql-replica.service.consul. 0 IN SRV 1 1 5432
postgresql-slave.node.dc1.consul.
;; ADDITIONAL SECTION:
postgresql-slave-2.node.dc1.consul. 0 IN A 10.0.3.224
postgresql-slave.node.dc1.consul. 0 IN A 10.0.3.223
Ноль в обоих ответах— это TTL, то есть DNS-ответ не должен кэшироваться.
Хелсчеки
Вы могли заметить, что выше при получении информации о сервисах Consul не сказал нам, работают ли вообще сейчас эти сервисы, или нет.
Получить информацию о состоянии сервиса и его хоста можно через такую ручку:
В данном примере сервис лежит.
А так можно узнать состояние хоста и сервисов на нем:
Информация о кластере и leader election
Consul позволяет посмотреть, кто сейчас есть в кластере:
Также мы можем узнать, кто сейчас лидер:
А так можно получить очень размашистую информацию об агенте, содержащую, помимо прочего, IP текущей машины:
Возникает закономерное желание попытаться получить leader election при помощи этого API для своего приложения в 20 строк кода на Python. Но это вряд ли удачная идея. Во-первых, потому что легко наплодить гонок и получить в один момент времени двух лидеров. Решать эту проблему нужно путем ожидания ACK от мажорити кластера, притом в ACK следует включать номер текущего term’а в Raft’е или иной счетчик. Во-вторых, по-хорошему в этом случае необходимо при выполнении любого действия проверять, являемся ли мы по-прежнему лидером.
Как верно сообщил мне @sum3rman, куда проще использовать другой подход, предположительно называемый leader lease. Раз у нас уже есть KV-хранилище с поддержкой CAS, мы можем просто писать в него, что машина такая-то является лидером до истечении такого-то времени. Пока лидер живет и здравствует, он может периодически продлевать это время. Если лидер умрет, его быстро кто-то подменит. В таком варианте достаточно синхронизировать на машинах время при помощи ntpd и при выполнении лидером любого действия проверять, что у него в запасе достаточно времени, чтобы завершить это действие.
Еще один интересный вариант leader election поверх Consul описан в самой документации Consul’а. Он полагается на уже знакомый нам механизм хелсчеков, а также сессии. Сессии по сути представляют собой распределенные локи, автоматически освобождаемые по TTL или при падении сервиса. В рамках этой заметки сессии мы не рассматриваем. Но возможность эта весьма интересная, и я всячески рекомендую с ней познакомиться.
Замечание про безопасность
Примите во внимание, что по умолчанию в Consul не используется какое-либо шифрование трафика. Также, получив доступ всего лишь к одной машине вашего кластера, можно довольно просто устроить DoS всего приложения.
Тут, правда, следует сделать ряд оговорок. Во-первых, все зависит от того, как вы используете Consul. Например, если он используется только как KV хранилище, доступ к нему очень легко ограничить при помощи Nginx и iptables. Во-вторых, имеет право на жизнь точка зрения, что получив доступ к одному из фронтэндов, злоумышленник скорее всего получит доступ и к БД, а значит сможет устроить DoS, просто записав в эту БД ерунду. Поэтому на этом этапе защищаться уже поздно, так зачем создавать себе лишние неудобства?
В любом случае, все эти вопросы выходят за рамки настоящего поста, но в заключении вы найдете пару ссылок по теме.
Заключение
Я бы сказал, что Consul — это не service discovery, а целый фреймворк для построения распределенных систем, умеющий помимо самого service discovery еще и локи, KV, лидер элекшен, мониторинг, ACL, сетевые координаты, events, prepared queries и, наверное, что-то еще, о чем я забыл, или что в нем успеет появиться к моменту, когда вы будете читать эти строки. Интересно, что благодаря встроенному мониторингу, при желании Consul’ом можно полностью заменить Zabbix или Nagios.
А используете ли вы Consul и если да, то как впечатления?
Дополнение: Реальный пример использования Consul вы можете найти в заметке Stolon: создаем кластер PostgreSQL с автофейловером.