Infra1: Service Discovery, Cloud Native Proxy и деплой
Для одного из наших динамично развивающихся проектов появилась задача актуализировать документацию, описать инфраструктурные моменты и вообще закрыть весьма большую тему с мультитенантностью.
Кроме того внутренняя инфраструктура разработки RNDSOFT имеет аналогичное строение, подходы и используемые инструменты. В результате было решено гармонично совместить процесс написания документации с выпуском цикла статей по подходам, используемым на многих продуктах, инструментам и особенностям нашей инфраструктуры.
- Infra1: Service Discovery, Cloud Native Proxy и деплой - первая статья цикла про различные современные штуки, которые мы используем для запуска и масштабирования приложений.
- Infra2: Consul Registrator - вторая статья про замечательный инструмент.
- Infra3: Мониторинг, Event Logging и сбор логов - третья статья про мониторинг.
- Infra4: ...дальше видно будет...
Проблемы
Инфраструктура создается и развивается не с пустого места - она решает какие-то насущные задачи. Когда у нас было мало продуктов, нам не требовалась масштабируемая и гибкая инфраструктура, но с числом проектов возросла сложность инфраструктуры разработки и появились требования.
Прежде всего появилась задача иметь множество стендов с разными версиями приложения (мы называем их стенды для МР'ов), чтоб разработчик мог выкатить для QA
конкретную версию с конкретной фичей. Число одновременно разрабатываемых и поддерживаемых продуктов возросло и уже исчисляется десятками.
Требование к доступности возросло даже для дев-окружения. Кроме того с продуктов и стендов надо собирать метрики, проводить замеры производительности и прочее и прочее...
За много лет мы сформировали неплохую инфраструктуру, подходящую как под заказную так и под продуктовую разработку, и пришла пора начать делиться решениями.
Service Discovery
Сегодня Обнаружение сервисов (Service Discovery
) уже плотно вошло в нашу жизнь и останавливаться на этом я не буду. Расскажу лишь как именно мы его используем и с помощью каких инструментов.
Начну с продуктов. В нашей компании разрабатывается несколько изолированных друг от друга продуктов (Финтех, телемедицина, дистанционное обучение и пр.) и поэтому для них мы используем изолированные пространства, некоторые из которых похожи друг на друга как близнецы. А вот в инфраструктуре разработки требования не такие жесткие и там используются общие части.
Приложение запускается в контейнерах. И для того чтобы прокси налету подхватывал адреса, доменные имена и всё необходимое для обслуживания запросов как раз и используется Service Discovery
на базе Consul
.
Consul
Это сердце. В небольших продуктовых окружениях часто бывает только один Consul-master,
но по мере необходимости можно формировать отказоустойчивый кластер "на лету", в отличие от ZooKeeper
например. Во внутренней инфраструктуре разработки у нас полноценный кластер с тремя мастерами и кучей агентов:
На вкусностях, которые нам предоставляет 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
и таким образом можно гибко управлять регистрацией сервисов. Пока писал этот текст понял, что про такой замечательный инструмент стоит рассказать отдельно в следующей статье данного цикла.
Бонус
На вкусное оставил более детальную схему размещения продукта с отказоустойчивостью и резервированием: