Skip to content

Серверная инфраструктура проекта CyberDAS, включающая систему мониторинга, логирования и маршрутизации запросов.

License

Notifications You must be signed in to change notification settings

CyberDAS-Dev/Infrastructure

Repository files navigation

Infrastructure

Серверная инфраструктура проекта CyberDAS, включающая систему мониторинга, логирования и маршрутизации запросов.

Grafana

Что это?

Это набор конфигов и docker-compose файлов, настраивающих окружение на сервере проекта CyberDAS. Всё окружение состоит из набора обособленных контейнеров, выполняющих свою задачу. Если вы никогда не сталкивались с docker и вам не знакомо понятие контейнера, рекомендую пройти по этой ссылке: https://docs.docker.com/get-started/.

Маршрутизация

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

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

Но у traefik есть один огромный плюс: добавление новых контейнеров производится без дописывания глобального конфига. Если разработчик хочет опубликовать новый сервис, он просто присоединяет свой контейнер к определенной Docker network (в нашем случае она называется "proxy") и объявляет в одной строчке о том, что ему нужен доступ в веб. Вуаля! Docker делает всю остальную работу.

На примере (фрагмент docker-compose файла абстрактного сервиса):

services:
  backend:
    build: backend
    expose:
      - 5000
    networks:
      - proxy
    labels:
      - traefik.enable=true

networks:
  proxy:
    external: true

Что при этом произойдет?

  1. Приложение, которое работает в контейнере backend на 5000-ом порту окажется доступным по адресу https://backend.cyberdas.net
  2. Все HTTP запросы к контейнеру автоматически перенаправляются на протокол HTTPS
  3. На этот поддомен автоматически оформится SSL-сертификат и будет обновляться, до тех пор пока этот контейнер существует
  4. В логах доступа автоматически появится новая категория, позволяющая анализировать запросы только к этому контейнеру (ура, можно не вести своих access логов!)

Пара важных моментов:

  1. При отсутствии ключа TRAEFIK_REAL_CERTS в окружении, traefik будет обращаться к стейджинг АПИ LetsEncrypt (отлично подходит для тестов!). Если этот ключ есть в окружении, то traefik будет пытаться получить настоящие сертификаты.
  2. Раздача имен сервисам (backend.cyberdas.net из примера выше) происходит нехитрым образом: из полного имени контейнера, состоящего из имени самого контейнера и имени проекта, отрываемся имя проекта. То, что осталось - создается как сабдомен. Следите за коллизиями и именуйте семантически! Кстати, не все сервисы должны стоять на сабдоменах, и это поведение полностью кастомизируется. По всем вопросам обращайтесь к документации: https://doc.traefik.io/
  3. При локальной разработке получить доступ к сервисам можно обращаясь на локалхост; например, traefik.localhost.

Логирование

Логирование происходит в несколько этапов:

  1. Логи формируются в приложении, будь то traefik или БД
  2. Они отправляются в stdout/stderr, где их может читать Docker
  3. Docker, используя драйвер fluentd отправляет их по указанному адресу (в нашем случае localhost:24224)
  4. Fluentd производит первичную обработку и маршрутизацию логов, отправляя их Loki
  5. Loki хранит логи до востребования

Такая сложная последовательность действий - не моя прихоть.

Например, у Loki есть свой драйвер для Docker'а, но у него не хватает возможностей для первичной обработки. Без неё неотформатированные логи (например, от сторонних приложений, таких как traefik) очень сложно и долго обрабатываются в конечных системах.

А прослойка в виде Docker'а для отправки в Fluentd позволяет в любой момент поменять агента не внося правок в код приложений.

Главное не забыть что все компоненты этой системы должны видеть друг друга и правильно настроить сети.

И так, приняв такую тяжелую архитектуру, нужно понять как с ней работать:

  1. Fluentd крутится на локалхосте (127.0.0.1:24244), потому что он должен быть доступен не только из одного docker-compose. Благодяра этому, в любых контейнерах в пределах одной машины мы можем сделать так:
services:
  backend:
    build: backend
    logging:
      driver: fluentd
      options:
        fluentd-address: localhost:24224
        tag: app.backend
  1. Тэги - это важно. Вся маршрутизация и обработка логов в Fluentd основывается на тэгах. Сам конфиг лежит в fluentd/fluent.conf. В этом проекте такое соглашение: все самописные приложения имеют первоуровневым тэгом app и обязаны предоставлять структурированные JSON-логи, обязательно указывая level и поле app_name, которое в идеале совпадает с именем контейнера (не забываем про коллизии!). Сторонние приложения - тяжелый случай, так как формат их логов зачастую неконтроллируемый, поэтому для них можно, и даже нужно, делать кастомные тэги и писать свои обработчики.
  2. Не нужно писать свои access логи, так как traefik предоставляет очень богатый набор данных, которого хватит с головой. Только в будущем нужно трэйсинг добавить.

В случае возникновения вопросов обращайтесь к документации: https://docs.fluentd.org/

Мониторинг

Погодите, а разве на логах мы не закончили? Что это еще за мониторинг такой?

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

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

А самое важное то, что с помощью метрик можно создавать красивые дэшборды.

Закончив с вопросом "зачем" и поняв важность мониторинга, перейдем к вопросу "как".

  1. Так как наша базовая единица - это контейнер, то полезно будет следить за базовыми характеристиками всех контенейров на системе. Сколько памяти и процессорного времен они потребляют, сколько посылают и принимают по сети. Для этого есть специальный (угадайте, что) контейнер - cAdvisor. Работает без особых конфигов и сразу на все контейнеры.
  2. Помимо этого интерес представляют характеристики самого хоста, на котором работают контейнеры. Учитывая то, что контейнеры очень любят быть большими, и то, что мы собираем логи, - место на жестком диске может кончится довольно неожиданно. Также, хочется следить за свопом и температурой железа. И да, на это тоже есть контейнер - node-exporter. Тоже хватает одного на всю систему.
  3. Теперь у нас есть данные. Но их еще нужно куда-то записывать. В этом поможет Prometheus. Но на этом его функционал не заканчивается. С его же помощью записываются метрики с приложений типа traefik.

Но мы не будем останавливаться только лишь на сборе и хранении данных. В проекте присутствует система уведомлений о каких-то критичных событиях, критерии для которых вычисляются на основе метрик, - Alertmanager.

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

Если вам тоже кажется, что как-то сервисов стало через чур много, то вам не кажется.

Небольшое лирическое отступление: до того как остановиться на этом стэке, я рассматривал ELK (ElasticSearch, Logstash, Kibana), который предназначается для той же задачи. Когда я всё это поставил, то под 70% памяти на хосте забрала система для... мониторинга? Короче говоря, лучше иметь 6 сервисов, которые вместе потребляют 300 МБ оперативной памяти, чем 3 сервиса, которые вместе потребляют 4 ГБ оперативной памяти.

Для управления всем этим добром есть конфиги. Коротко о них:

  1. В конфиге Prometheus указаны все сервисы, с которых снимаются метрики. В случае добавления нового сервиса, его нужно будет указать там.
  2. Рядом с конфигом Prometheus лежит список правил, вызывающих алерты.
  3. Конфиг Loki очень загадочный и непонятный. Рекомендую не трогать
  4. Alertmanager позволяет в своем конфиге указать получателей и способы группировки эвентов. Но он плохо задокументирован, поэтому тоже лучше не трогать.
  5. В папке с Grafana можно настроить источники данных 'по умолчанию', а также добавить парочку дэшбордов, которые будут доступны 'из коробки'.

А как это всё запустить?

Одной кнопочкой.

docker-compose -f docker-compose.yml -f monitoring-compose.yml up -d

И, вуаля, ваш компьютер превращается в сервер. Ну почти. Только контейнеры с сервисами поставьте. И статичный IP оформите.

На самом деле еще нужно поменять настройки в файле .env. Они довольно очевидные

About

Серверная инфраструктура проекта CyberDAS, включающая систему мониторинга, логирования и маршрутизации запросов.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages