https://github.com/rnd-soft/swarm-example
[MIRROR] Пример деплоя и настройки кластера из нескольких хостов с использованием docker(при необходимости swarm), ansible, consul и traefik. https://br.rnds.pro/rnds/swarm-example
https://github.com/rnd-soft/swarm-example
ansible consul docker docker-compose docker-swarm example portainer traefik
Last synced: 9 months ago
JSON representation
[MIRROR] Пример деплоя и настройки кластера из нескольких хостов с использованием docker(при необходимости swarm), ansible, consul и traefik. https://br.rnds.pro/rnds/swarm-example
- Host: GitHub
- URL: https://github.com/rnd-soft/swarm-example
- Owner: RND-SOFT
- Created: 2020-04-15T08:50:19.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2020-04-15T11:06:39.000Z (almost 6 years ago)
- Last Synced: 2025-01-20T20:33:13.833Z (about 1 year ago)
- Topics: ansible, consul, docker, docker-compose, docker-swarm, example, portainer, traefik
- Homepage:
- Size: 66.4 KB
- Stars: 4
- Watchers: 6
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Пример развертывания веб-приложения в простом кластере.
Этот пример сделан для доклада на митапе [DistilleryTech](https://www.facebook.com/DistilleryRussia/posts/3200475796663282)
Ссылка на репозиторий [тут](https://github.com/RND-SOFT/swarm-example).
Ссылка на презентацию [тут](https://docs.google.com/presentation/d/1tXcIYyGL_9YnOSJCBA_Q51zVNvXJ2zMwMfOYB2T1zUk/edit?usp=sharing)
## Введение
В данном примере находится рабочая конфигурация ansible для развертывания веб-приложения в кластере из трех хостов.
### О чем пример/доклад?
О том, как сделать простую инфраструктуру для разработки и эксплуатации приложения со всякими современными свистелками.
### Кому полезен?
* Командам без выделенного devops-направления
* Тем кто только начинает в docker и микросервисы
* Да и вообще тем, кто хочет разобраться как работают с кластером на простом примере.
### Используемые технологии
* [ansible](https://ru.wikipedia.org/wiki/Ansible) - система управления конфигурациями. Используется для автоматизации настройки и развертывания программного обеспечения
* несколько хостов(в данном случае созданные в VirtualBox)
* [traefik](https://docs.traefik.io/) - Edge Router, реверс-проксии, балансер и пр.
* [consul](https://www.consul.io/) - Service Discovery(обнаружение сервисов), K/V-хранилище, DNS и многое другое
* [registrator](https://github.com/gliderlabs/registrator) - небольшой сервис, регистрирующий запущенные контейнеры в consul
* docker - собственно docker. При необходимости в режиме swarm
* [portainer](https://www.portainer.io/) - веб-интерфейс для управления docker'ом, особенно удобно если у нас swarm
* [gitlab](https://about.gitlab.com/) - ПО, для запуска CI/CD. Из него выполняются все действия в автоматизированном режиме
Компоненты `traefik`, `consul` и `registrator` образуют группу `ingress`, которая выполняет функцию маршрутизации входных http-запросов к динамически поднимаемым контейнерам с приложением(ями).
## Запуск
Прежде всегод надо иметь инфраструктуру для развертывания данного кластера. Для этого подойдут любые(аппаратные или виртуальные) сервера с доступом по ssh, с установленным python и под управлением ОС Debian(поскольку это пример). В данном примере используются три сервера:
* 192.168.99.104 - cluster1 (роли: swarm manager)
* 192.168.99.105 - app1 (роли: swarm worker, db, consul, apps, persistent - тут хранятся данные)
* 192.168.99.106 - app2 (роли: swarm worker, gate, apps)
Им назначены определенные фукнции, которые они выполяют. Нет никаких проблем все функции делегировать одному хосту и все развернуть на нём одном.
Работать с docker'ом через сварм можно несколькими путями: через модуль docker/docker-swarm и через ssh/docker-compose. Если использовать модули docker то кататься будет хорошо, быстро, но вы никак не узнаете что и как было запущено. Вы увидите только результат - контейнеры, сети. Чтобы посмотреть настройки запуска контейнеров необходимо делать `docker inspect` и читать json.
Во втором варианте на сервер санчала закидывается docker-compose.yml а потом там выполнятеся `docker-compose up -d`. В этом случае docker-compose.yml остается и вы можете посмотреть что и откуда было запущено. Этот способ очень удобен при небольшом разамере кластера(до 5ти нод) или при начальном освоении кластерных подходов. Все файлы кладутся в папку `/storage/configs/<группа>/....`
Развертывание можно условно разделить на несколько шагов.
### Шаг 1 - настройка хостов
Выполняется в плейбуке [playbook/setup.yml](ansible/playbook/setup.yml)
Команда: `ansible-playbook -i example.ini playbook/setup.yml -D`
Что делает:
* настраивает ssh-доступы из gitlab
* ставит docker, docker-compose, подключает репозитории и пр.
Данный плейбук можно прокатить только один раз, или когда у вас добавляются хосты. Но если катать часто - ничего страшного.
### Шаг 2 - Запуск docker-swarm
Если у вас нет желания использовать swarm то плейбуки и таски можно немного изменить и просто работать с несколькими независимыми docker-хостами. Архитектура кластера от этого не изменится, но вот способы распределения приложений по нодам придется придумать. В данном случае используется swarm для облегчения деплоя - можно иметь соединение только с одной машиной(swarm manager) и все развертывать через неё, а ограничения накладываются через метки(labels) на нодах docker-swarm и в ограничениях(constraints) при описании сервисов.
Выполняется в плейбуке [playbook/swarm.yml](ansible/playbook/swarm.yml)
Команда: `ansible-playbook -i example.ini playbook/swarm.yml -D`
Что делает:
* переводит докеры на хостах в режим swarm
* переводит некоторые ноды(согласто группам в [example.ini](ansible/example.ini)) в режим manager
* собирает ноды в кластед docker swarm(инициализирует подключения через токены)
* раздает метки(labels) нодам
В данном примере у нас три метки(роли):
* gate - это шлюз который "торчит" в интернет. К нему стандартные требования безопасности для шлюзов. он обеспечивает TLS-терминацию и пр. В частности именно на шлюзах должен быть запущен traefik. Шлюзов может быть много
* apps - ноды на которых будут запущены наши веб-приложения. Тоесть именно бизнес-приложения, выполняющие бизнес-функции.
* persistent - ноды(в данной конфигурации обязательно **ОДНА**) на которой хранятся данные. База данных, consul могут быть запущены только на ней
Данный плейбук можно прокатить только один раз, или когда у вас добавляются хосты, меняются роли и пр. Но если катать часто - ничего страшного.
### Шаг 3 - Настройка кластерной инфраструктуры
Выполняется в плейбуке [playbook/infra.yml](ansible/playbook/infra.yml)
Команда: `ansible-playbook -i example.ini playbook/infra.yml -D`
Что делает:
* запускает все наши служебные сервисы
* запускает базу на `persistent` ноде. Катается на группе db НЕ через swarm
* катает portainer через swarm(на любой-первой `manger` ноде и через неё деплоит). Один portaner всего и portainer-agent на `каждой` ноде кластера
* катает portainer через swarm. На каждой `gate` ноде
* запускает consul на нодах `consul` НЕ через swarm
* запускает registrator на `всех` нодах НЕ через сварм
Запуск через swarm/не swarm обусловлен только удобством. Через swarm значит с использованием `docker deploy`. Не через сварм значит `docker-compose up -d`
Данный плейбук можно прокатить только один раз, или когда у вас добавляются хосты, меняются роли и пр. Но если катать часто - ничего страшного.
### Шаг 4 - Деплой приложения
Собственно именно этот шаг выполняется в CI/CD на регулярной основе.
Выполняется в плейбуке [playbook/app.yml](ansible/playbook/app.yml)
Команда: `ansible-playbook -i example.ini -e instance=dev playbook/app.yml -D`
Что делает:
* запускает наше приложение в кластере. На всех нодах `apps`. Через swarm.
## Что просходит?
Плейбук app.yml использует параметр `instance` и глобальный параметр `domain`. В данном примере `domain=example.local`. Это означает что с приложением после деплоя произойдут следуюшщие шаги:
* запустятся контейнеры. Им назначатся случайные порты на каждой машине на которой они запустились
* `registrator` увидит это и зарегистрирует информацию о них в `consul`. Укажет правильные ip хостов и эти случайные порты. При падении или перезапуске приложения `registrator` будет удалять/обновлять информацию в `consul`. Кроме того `registrator` зарегистрирует указанные healthcheck'и в консуле, и он начнет периодически проверять приложение на доступность.
* `traefik` будет ожидать что в `consul` появится приложение, выполнится healthcheck и только после этого добавит к себе соответствующий маршрут(virtual host). Этот маршрут будет иметь вид: `http://..`, например: `http://hello.dev.example.local`
Если вы хотите для QA развернуть отдельный инстанс, то это делается передачей в переменную instance нужного вам параметра. Например при деплое ветки `feature/fix-JIRA-100500`, из гитлаба можно передать туда COMMIT_REF_SLUG, который будет выглядеть так: `feature-fix-jira-100500` и в результате мы получем доступ по адресу: `http://hello.feature-fix-jira-100500.example.local`
Вот собственно и все. В данном репозитории лежит [.gitlab-ci.yml](.gitlab-ci.yml), который настроен на возможность развертывания стенда `dev` из ветки `master` и любого временно стенда из любой другой ветки или мердж-реквеста.
Команда RND-SOFT желает вам удачи.