{"id":21062442,"url":"https://github.com/rnd-soft/swarm-example","last_synced_at":"2025-04-30T11:47:36.795Z","repository":{"id":80123465,"uuid":"255858359","full_name":"RND-SOFT/swarm-example","owner":"RND-SOFT","description":"[MIRROR] Пример деплоя и настройки кластера из нескольких хостов с использованием docker(при необходимости swarm), ansible, consul и traefik. https://br.rnds.pro/rnds/swarm-example","archived":false,"fork":false,"pushed_at":"2020-04-15T11:06:39.000Z","size":68,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-01-20T20:33:13.833Z","etag":null,"topics":["ansible","consul","docker","docker-compose","docker-swarm","example","portainer","traefik"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RND-SOFT.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-15T08:50:19.000Z","updated_at":"2025-01-14T05:25:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"3d42bb9a-9432-4432-aedb-2e6c20f8c3eb","html_url":"https://github.com/RND-SOFT/swarm-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RND-SOFT%2Fswarm-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RND-SOFT%2Fswarm-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RND-SOFT%2Fswarm-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RND-SOFT%2Fswarm-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RND-SOFT","download_url":"https://codeload.github.com/RND-SOFT/swarm-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243505963,"owners_count":20301619,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","consul","docker","docker-compose","docker-swarm","example","portainer","traefik"],"created_at":"2024-11-19T17:38:52.946Z","updated_at":"2025-03-14T01:14:23.096Z","avatar_url":"https://github.com/RND-SOFT.png","language":null,"readme":"# Пример развертывания веб-приложения в простом кластере.\n\nЭтот пример сделан для доклада на митапе [DistilleryTech](https://www.facebook.com/DistilleryRussia/posts/3200475796663282)\n\u003cbr\u003eСсылка на репозиторий [тут](https://github.com/RND-SOFT/swarm-example).\n\u003cbr\u003eСсылка на презентацию [тут](https://docs.google.com/presentation/d/1tXcIYyGL_9YnOSJCBA_Q51zVNvXJ2zMwMfOYB2T1zUk/edit?usp=sharing) \n\n## Введение\n\nВ данном примере находится рабочая конфигурация ansible для развертывания веб-приложения в кластере из трех хостов. \n\n### О чем пример/доклад?\n\nО том, как сделать простую инфраструктуру для разработки и эксплуатации приложения со всякими современными свистелками. \n\n### Кому полезен?\n\n* Командам без выделенного devops-направления\n* Тем кто только начинает в docker и микросервисы\n* Да и вообще тем, кто хочет разобраться как работают с кластером на простом примере.\n\n### Используемые технологии\n\n* [ansible](https://ru.wikipedia.org/wiki/Ansible) - система управления конфигурациями. Используется для автоматизации настройки и развертывания программного обеспечения\n* несколько хостов(в данном случае созданные в VirtualBox)\n* [traefik](https://docs.traefik.io/) - Edge Router, реверс-проксии, балансер и пр.\n* [consul](https://www.consul.io/) - Service Discovery(обнаружение сервисов), K/V-хранилище, DNS и многое другое\n* [registrator](https://github.com/gliderlabs/registrator) - небольшой сервис, регистрирующий запущенные контейнеры в consul\n* docker - собственно docker. При необходимости в режиме swarm\n* [portainer](https://www.portainer.io/) - веб-интерфейс для управления docker'ом, особенно удобно если у нас swarm\n* [gitlab](https://about.gitlab.com/) - ПО, для запуска CI/CD. Из него выполняются все действия в автоматизированном режиме\n  \n\nКомпоненты `traefik`, `consul` и `registrator` образуют группу `ingress`, которая выполняет функцию маршрутизации входных http-запросов к динамически поднимаемым контейнерам с приложением(ями).\n\n## Запуск\n\nПрежде всегод надо иметь инфраструктуру для развертывания данного кластера. Для этого подойдут любые(аппаратные или виртуальные) сервера с доступом по ssh, с установленным python и под управлением ОС Debian(поскольку это пример). В данном примере используются три сервера:\n* 192.168.99.104 - cluster1 (роли: swarm manager)\n* 192.168.99.105 - app1 (роли: swarm worker, db, consul, apps, persistent - тут хранятся данные)\n* 192.168.99.106 - app2 (роли: swarm worker, gate, apps)\n\nИм назначены определенные фукнции, которые они выполяют. Нет никаких проблем все функции делегировать одному хосту и все развернуть на нём одном.\n\nРаботать с docker'ом через сварм можно несколькими путями: через модуль docker/docker-swarm и через ssh/docker-compose. Если использовать модули docker то кататься будет хорошо, быстро, но вы никак не узнаете что и как было запущено. Вы увидите только результат - контейнеры, сети. Чтобы посмотреть настройки запуска контейнеров необходимо делать `docker inspect` и читать json. \n\nВо втором варианте на сервер санчала закидывается docker-compose.yml а потом там выполнятеся `docker-compose up -d`. В этом случае docker-compose.yml остается и вы можете посмотреть что и откуда было запущено. Этот способ очень удобен при небольшом разамере кластера(до 5ти нод) или при начальном освоении кластерных подходов. Все файлы кладутся в папку `/storage/configs/\u003cгруппа\u003e/....`\n\n\nРазвертывание можно условно разделить на несколько шагов.\n\n### Шаг 1 - настройка хостов\n\nВыполняется в плейбуке [playbook/setup.yml](ansible/playbook/setup.yml)\n\u003cbr\u003eКоманда: `ansible-playbook -i example.ini playbook/setup.yml -D`\n\u003cbr\u003eЧто делает:\n* настраивает ssh-доступы из gitlab\n* ставит docker, docker-compose, подключает репозитории и пр.\n\nДанный плейбук можно прокатить только один раз, или когда у вас добавляются хосты. Но если катать часто - ничего страшного.\n\n### Шаг 2 - Запуск docker-swarm\n\nЕсли у вас нет желания использовать swarm то плейбуки и таски можно немного изменить и просто работать с несколькими независимыми docker-хостами. Архитектура кластера от этого не изменится, но вот способы распределения приложений по нодам придется придумать. В данном случае используется swarm для облегчения деплоя - можно иметь соединение только с одной машиной(swarm manager) и все развертывать через неё, а ограничения накладываются через метки(labels) на нодах docker-swarm и в ограничениях(constraints) при описании сервисов.\n\nВыполняется в плейбуке [playbook/swarm.yml](ansible/playbook/swarm.yml)\n\u003cbr\u003eКоманда: `ansible-playbook -i example.ini playbook/swarm.yml -D`\n\u003cbr\u003eЧто делает:\n* переводит докеры на хостах в режим swarm\n* переводит некоторые ноды(согласто группам в [example.ini](ansible/example.ini)) в режим manager\n* собирает ноды в кластед docker swarm(инициализирует подключения через токены)\n* раздает метки(labels) нодам\n\nВ данном примере у нас три метки(роли):\n* gate - это шлюз который \"торчит\" в интернет. К нему стандартные требования безопасности для шлюзов. он обеспечивает TLS-терминацию и пр. В частности именно на шлюзах должен быть запущен traefik. Шлюзов может быть много\n* apps - ноды на которых будут запущены наши веб-приложения. Тоесть именно бизнес-приложения, выполняющие бизнес-функции. \n* persistent - ноды(в данной конфигурации обязательно **ОДНА**) на которой хранятся данные. База данных, consul могут быть запущены только на ней\n\nДанный плейбук можно прокатить только один раз, или когда у вас добавляются хосты, меняются роли и пр. Но если катать часто - ничего страшного.\n\n### Шаг 3 - Настройка кластерной инфраструктуры\n\nВыполняется в плейбуке [playbook/infra.yml](ansible/playbook/infra.yml)\n\u003cbr\u003eКоманда: `ansible-playbook -i example.ini playbook/infra.yml -D`\n\u003cbr\u003eЧто делает:\n* запускает все наши служебные сервисы\n* запускает базу на `persistent` ноде. Катается на группе db НЕ через swarm\n* катает portainer через swarm(на любой-первой `manger` ноде и через неё деплоит). Один portaner всего и portainer-agent на `каждой` ноде кластера\n* катает portainer через swarm. На каждой `gate` ноде\n* запускает consul на нодах `consul` НЕ через swarm\n* запускает registrator на `всех` нодах НЕ через сварм\n\nЗапуск через swarm/не swarm обусловлен только удобством. Через swarm значит с использованием `docker deploy`. Не через сварм значит `docker-compose up -d`\n\nДанный плейбук можно прокатить только один раз, или когда у вас добавляются хосты, меняются роли и пр. Но если катать часто - ничего страшного.\n\n### Шаг 4 - Деплой приложения\n\nСобственно именно этот шаг выполняется в CI/CD на регулярной основе. \n\nВыполняется в плейбуке [playbook/app.yml](ansible/playbook/app.yml)\n\u003cbr\u003eКоманда: `ansible-playbook -i example.ini -e instance=dev playbook/app.yml -D`\n\n\u003cbr\u003eЧто делает:\n* запускает наше приложение в кластере. На всех нодах `apps`. Через swarm.\n\n\n## Что просходит?\n\nПлейбук app.yml использует параметр `instance` и глобальный параметр `domain`. В данном примере `domain=example.local`. Это означает что с приложением после деплоя произойдут следуюшщие шаги:\n* запустятся контейнеры. Им назначатся случайные порты на каждой машине на которой они запустились\n* `registrator` увидит это и зарегистрирует информацию о них в `consul`. Укажет правильные ip хостов и эти случайные порты. При падении или перезапуске приложения `registrator` будет удалять/обновлять информацию в `consul`. Кроме того `registrator` зарегистрирует указанные healthcheck'и в консуле, и он начнет периодически проверять приложение на доступность.\n* `traefik` будет ожидать что в `consul` появится приложение, выполнится healthcheck и только после этого добавит к себе соответствующий маршрут(virtual host). Этот маршрут будет иметь вид: `http://\u003cservice_name\u003e.\u003cinstance\u003e.\u003cdomain\u003e`, например: `http://hello.dev.example.local`\n\nЕсли вы хотите для QA развернуть отдельный инстанс, то это делается передачей в переменную instance нужного вам параметра. Например при деплое ветки `feature/fix-JIRA-100500`, из гитлаба можно передать туда COMMIT_REF_SLUG, который будет выглядеть так: `feature-fix-jira-100500` и в результате мы получем доступ по адресу: `http://hello.feature-fix-jira-100500.example.local`\n\n\nВот собственно и все. В данном репозитории лежит [.gitlab-ci.yml](.gitlab-ci.yml), который настроен на возможность развертывания стенда `dev` из ветки `master` и любого временно стенда из любой другой ветки или мердж-реквеста.\n\nКоманда RND-SOFT желает вам удачи.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frnd-soft%2Fswarm-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frnd-soft%2Fswarm-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frnd-soft%2Fswarm-example/lists"}