Infra1: Service Discovery, Cloud Native Proxy и деплой

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

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


  1. Infra1: Service Discovery, Cloud Native Proxy и деплой - первая статья цикла про различные современные штуки, которые мы используем для запуска и масштабирования приложений.
  2. Infra2: Consul Registrator - вторая статья про замечательный инструмент.
  3. Infra3: Мониторинг, Event Logging и сбор логов - третья статья про мониторинг.
  4. Infra4: ...дальше видно будет...

Проблемы

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

Прежде всего появилась задача иметь множество стендов с разными версиями приложения (мы называем их стенды для МР'ов), чтоб разработчик мог выкатить для QA конкретную версию с конкретной фичей. Число одновременно разрабатываемых и поддерживаемых продуктов возросло и уже исчисляется десятками.

Требование к доступности возросло даже для дев-окружения. Кроме того с продуктов и стендов надо собирать метрики, проводить замеры производительности и прочее и прочее...

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

Service Discovery

Сегодня Обнаружение сервисов (Service Discovery) уже плотно вошло в нашу жизнь и останавливаться на этом я не буду. Расскажу лишь как именно мы его используем и с помощью каких инструментов.

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

Общая высокоуровневая схема размещения приложения

Приложение запускается в контейнерах. И для того чтобы прокси налету подхватывал адреса, доменные имена и всё необходимое для обслуживания запросов как раз и используется Service Discovery на базе Consul.

Consul

Это сердце. В небольших продуктовых окружениях часто бывает только один Consul-master, но по мере необходимости можно формировать отказоустойчивый кластер "на лету", в отличие от ZooKeeper например. Во внутренней инфраструктуре разработки у нас полноценный кластер с тремя мастерами и кучей агентов:

Dev-кластер Consul

На вкусностях, которые нам предоставляет Consul остановимся подробнее.

Хранение текущего состояния системы

В Consul это называется Consul Catalog. Там содержится информация о каждом экземпляре сервиса: адрес, порт и метаданные. В метаданные мы помещаем информацию о том где запущено сервис, кем и пр. эта информация используется для поиска (например по hostname). В лэйблах содержится информация для роутинга и мониторинга (ставим monitoring и прометей долбится в /metrics). Про сами тэги и их значения, а также примеры реальных конфигов для запуска сервисов будет отдельная статья в ближайшем времени.

Это наш внутренний сервис для различных реакций на внутренние вебхуки

Мониторинг состояния узлов сети

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

Мониторинг состояния сервисов

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

Healthcheck'и это крутая штука и консул поддерживает их целую кучу: HTTP, TCP, TTL, Docker, gRPC и даже Script. О том как их организовать будет написано позже.

Фильтровать можно, но иногда сложно...

Traefik

Официально этот инструмент характеризуется как:

Traefik is an Edge Router, it means that it's the door to your platform, and that it intercepts and routes every incoming request: it knows all the logic and every rule that determine which services handle which requests (based on the path, the host, headers, and so on ...)

Мы называем его по-старинке - "балансер". Он входит модную сейчас категорию Cloud Native Balancer, а значит легко интегрируется в различные облачные инфраструктуры. В нашем случае мы используем два типа источника данных для Traefik - это Consul Catalog и Consul KV. Отличие между ними в том, что первый (основной) сам берет данные из списка зарегистрированных сервисов и, основываясь на метаданных, строит свои таблицы маршрутизации. А второй это "полу-ручной" режим, в котором мы просто указываем где искать дополнительную конфигурацию.

Через этот инструмент у нас настроены разрешенные адреса, адреса, скрытые за Basic Auth, отображение ошибок, TLS, и разные другие штуки.

Панелька траефика

Deploy или как это работает вместе

И Traefik и Consul не требуют никакой особой конфигурации. Однажды запущенные они отлично живут и надёжно работают. Более того их можно вообще запустить руками и забыть (хотя мы конечно пишем для этого плейбуки в Ansible). А самое интересное происходит при деплое самих приложений и сервисов.

Как я уже писал выше у нас всё завёрнуто в контейнеры. Мы используем Docker и пока не планируем менять ни Container Runtime, ни Container Build. Наши приложения, как и полагается, ничего не знают об инфраструктуре в которой они запускаются и никакие настройки связанные с этим не прорастают внутрь кода.

А вот для склейки App -> Consul -> Traefik мы используем замечательный инструмент Consul Registrator. Замечательный он потому что он "просто работает". Он, как и Consul Agent, запускается на каждой ноде, присасывается к Docker и регистрирует все запущенные контейнеры на локальном агенте. Он знает какой порт выделил Docker для каждого контейнера, сколько этих портов и всё это передаёт в Consul. Дополнительную метаинформацию он берет из Label или Environment и таким образом можно гибко управлять регистрацией сервисов. Пока писал этот текст понял, что про такой замечательный инструмент стоит рассказать отдельно в следующей статье данного цикла.


Бонус

На вкусное оставил более детальную схему размещения продукта с отказоустойчивостью и резервированием:

Разнесение на зоны доступности можно реализовать постепенно, без отрыва от производства.