DevOps инфраструктура для стартапов ч.1
Это первая часть из цикла статей посвященных инфраструктуре для стартапов. Всего их будет две, поделенные, по-моему мнению, на логически законченные блоки.
Часть первая. Настройка окружения
Часть вторая. CI/CD и советы
Для кого эта статья
Эта статья будет полезна, если вы:
Запускаете стартап или пет-проект и хотите минимальными усилиями и затратами настроить инфраструктуру
Уже немного разбираетесь в Docker и хотите что-то посерьёзнее, но без оверинженеринга
Ищете альтернативу Kubernetes, которую можно легко развернуть и поддерживать без отдельного DevOps-инженера
Не боитесь немного покопаться в настройках, но при этом хотите сохранить гибкость и контроль
Не подойдёт, если:
У вас высоконагруженное продакшн-окружение с миллионами пользователей
Есть бюджет на полноценный DevOps-отдел
Уже используете Kubernetes и не хотите откатываться в "попроще"
Если вы узнаете себя в первом списке — читайте дальше. Ниже расскажем, как мы пришли к Docker Swarm и почему он оказался отличным выбором в условиях стартапа.
Введение
Начнем с небольшой предыстории. Я, как и любой студент технического вуза, мечтаю о карьере в IT, а то и о собственном стартапе. И ровно год назад моя мечта осуществилась, своими руками и общими усилиями была собрана команда классных ребят из ИТМО под названием Шампиньоны.
Изначально мы были командой из 4 разрабов и 1 дизайнера, ходили на всякие хакатоны, но мы поняли, что этого мало. Мы можем больше. Так мы обрели людей по недостающим компетенциям и начали заниматься продуктовой разработкой. Вместе с этим начали сталкиваться с новыми вызовами — и инфраструктура стала одним из них.
Один из нас уже писал статью на хабр про то, как мы поймали майнер на одном из серверов, а теперь же на своем примере поделимся инфраструктурным решением.
Как только стартап начинает разработку продукта, а то и нескольких, то остро встает вопрос о том, как наиболее выгодно поднять инфраструктуру, чтобы добиться идеального баланса. Подобно CAP теореме, выводятся сотни различных других, так и с инфраструктурой можно вывести свою — CPF.
Cheap
Performance
Fault Tolerance
Стартапы с деньгами эфемерны, и даже там не всегда есть средства на полноценного DevOps-инженера для поддержки системы. Отсюда вытекает, что девопсом зачастую будут заниматься сами разработчики, но как же этот процесс сгладить?
Как решать?
Для поднятия базовой инфраструктуры в голову приходит сразу два варианта:
Монолитная с докером — если не самый надежный хостинг, то сильно страдает надежность, а с вертикальным расширением сильно растет и цена. Также сложно поддерживать изолированно различные окружения (dev/test/prod)
Распределенная с кубером — сложно поднять, легко уронить, стоимость devops инженера, который знает кубер определенно выше
Хочется оговориться, что мы рассматриваем все в рамках стартапа, где по определению не бывает много денег.
Зная все минусы, хочется какой-то третий вариант — и он есть! Многие наверняка сталкивались со статьей "Docker swarm для самых маленьких", так и я её давно заприметил. Далеко не сразу получилось придумать, как внедрить его в существующую систему. По ходу работы в команде обнаруживались различные классные инструменты: portainer, watchtower, traefik. Вместе с ними и получилось подружить docker swarm.
Почему именно он?
Это тот же Docker, только с нотками кубернетеса. Мастер и воркер ноды, стэки/поды, концепции очень близки и главное позволяют развернуть инфраструктуру на нескольких серверах. Это повысит отказоустойчивость и упростит работу с различными окружениями. Любой разработчик минимально знающий Docker способен задеплоить приложение, соответственно и стоимость данного решения будет минимальна.
Инфраструктура на Docker Swarm
Все упомянутые далее скрипты и конфиги можно найти в репозитории нашей команды.
Первичная настройка
Чтобы не ходить по разным статьям и сайтам, написал скрипт для минимально быстрой настройки машинки.
Для мастер ноды используйте m
, для воркера — w
:
curl -fsSL https://raw.githubusercontent.com/shampsdev/startup-infrastructure/refs/heads/main/init.sh | bash -s -- [m/w]
Теперь проинициализируем мастер ноду и подключим к ней воркеры. Все машинки находятся в одной приватной сети, поэтому их можно подключать, через внутренний ip. Для этого необходимо указать флаг --advertise-addr
docker swarm init --advertise-addr 10.16.3.1
> docker swarm join --token genarated_token 10.16.3.1:2377
Указанную команду вводим на своих воркер нодах. Хостнеймы и все свои ноды можно проверить с помощью команды docker node ls
.
А чтобы было проще с ними взаимодействовать, то с помощью сварма к нодам можно добавить лейблы. Таким образом можно настроить гибкий деплой различный сервисов. К нему мы перейдем в следующей главе.
docker node update --label-add TAG=dev [hostname]
И последним этапом настройки станет добавление оверлей сети для траефика. Overlay-сеть позволяет контейнерам на разных нодах Docker Swarm иметь сетевой доступ друг к другу:
docker network create -d overlay --attachable traefik
Также, по желанию, вы можете отключить историю тасок с помощью команды:
docker swarm update --task-history-limit 0
Команда отключает сохранение истории выполненных задач в Docker Swarm. По умолчанию Docker сохраняет историю для мониторинга и отладки. Установив лимит на 0, вы отключаете её, что полезно, если не требуется отслеживать изменения и нужно снизить нагрузку на систему, особенно в крупных кластерах с частыми обновлениями.
Настройка Portainer
Portainer будет выступать в роли GUI нашей системы. Он поддерживает работу в Swarm-режиме и позволяет удобно управлять стеками, сервисами, томами и другими сущностями Docker. Особенно полезен для быстрой настройки и визуального контроля над инфраструктурой, а также отлично подходит для настройки CI/CD процессов — как для одиночных серверов, так и для кластеров.
После того, как скопируете себе докер компоуз для портейнера, исправьте лейбл с строчкой Host(your.domain.com
) на нужный вам домен.
curl -o docker-compose.yaml https://raw.githubusercontent.com/shampsdev/startup-infrastructure/refs/heads/main/portainer-traefik/portainer.docker-compose.yaml
Поскольку ключевые понятия — стеки, таски и реплики — уже подробно описаны в других статьях, здесь я сосредоточусь только на необходимых командах. Так как мы используем Docker Swarm, docker-compose up
работать корректно не будет — для развертывания нужно использовать стек:
docker stack deploy -c docker-compose.yaml portainer
Теперь заходим на сервер по адресу http://<ip>:9000
и проходим первичную регистрацию администратора:
После того, как создали админ пользователя -- перезапустите сервис:
docker service update --force portainer_portainer
Поздравляю — Portainer установлен и работает! Благодаря его интерфейсу вы можете:
запускать сервисы в GUI
отслеживать состояние контейнеров и стеков
просматривать логи
управлять конфигурацией без командной строки
работать с Secrets, сетями, томами и пр.
Как именно пользоваться Portainer’ом — тема для отдельной статьи, но в рамках этой серии мы ещё увидим пример его взаимодействия с Traefik.
Настройка Traefik
Traefik — это reverse proxy и load balancer, который просто интегрируется с Docker Swarm, Kubernetes и другими оркестраторами. Он автоматически отслеживает изменения в конфигурации и маршрутизирует трафик на основе меток и правил. В рамках нашей инфраструктуры Traefik будет выполнять роль маршрутизатора входящего трафика, обеспечивая:
автоматическую маршрутизацию по поддоменам
автоматическую выдачу и обновление SSL-сертификатов (через Let’s Encrypt)
балансировку нагрузки
базовую защиту на уровне доступа
мониторинг через встроенный дашборд
интеграцию с системами мониторинга
Далее — развернём его в рамках Docker Swarm и настроим базовые правила.
Настроим конфиг траефика через портейнер
Для этого зайдем во вкладку Configs > Add config. Далее необходимо указать уникальное имя для конфига. Я предпочитаю такой нейминг: service-config-v1
. Содержимое можно скопировать из репозитория, там сразу подготовлена база для сбора метрик.
К сожалению, необходимо вводить такое версионирование, так как менять конфиги налету нельзя, придется делать копии.Считаю, что в Openshift'e
реализован идеальный вариант, когда есть один конфиг и внутри него можно контролировать версии, но мы и не с кубером работаем.
Настроим стек traefik
Теперь зайдем в Stacks > Add stack. Компоуз файл для стека можно взять из репозитория traefik.docker-compose.yaml
. Однако перед тем, как запускать сервис, необходимо сгенерировать пароль для дашборда с помощью следующей команды:
echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g
Для дашборда используется basic auth и подробную информацию можно найти в документации траефика. Поэтому полученный пароль необходимо подставить для basicauth.users=
Важно: при работе с Traefik 3.x лучше не полагаться на GPT и ИИ как на единственный источник информации — обязательно сверяйтесь с официальной документацией, так как многое меняется.
Все. Вы настроили реверс прокси и балансировщик, который автоматически выдает и обновляет SSL без лишней головной боли.
Лейблы для Traefik
Для деплоя стека с доменом необходимо указать следующие лейблы траефика:
Лейбл | Назначение |
traefik.enable=true | Подключает сервис к маршрутизации Traefik |
traefik.docker.network=traefik | Указывает, в какой сети искать сервис. Лучше создавать отдельные сети для каждого сервиса |
traefik.http.routers.<name>.entrypoints=https | Через какие порты сервис будет доступен (обычно 80 и 443) |
traefik.http.routers.<name>.rule=Host(`example.com`) | Задает домен и правила маршрутизации для сервиса |
traefik.http.routers.<name>.certresolver=letsEncrypt | Резолвер для TLS/SSL-сертификатов. Название, как в конфиге |
traefik.http.services.<name>.loadbalancer.server.port=80 | Внутренний порт контейнера, на который отправляется трафик |
Важно: при работе в swarm-режиме траефик должен быть расположен на
manager
ноде. В примере нашей инфраструктуры используется 2 сервера и траефик расположен на мастере, так что никаких проблем не возникнет. Однако, если вы захотите вынести траефик на отдельный сервер, то его необходимо сделать менеджером с помощьюdocker node promote [name/ID]
Traefik — мощный инструмент, но он требует понимания некоторых особенностей при работе в Docker Swarm. Мы рассмотрели базовую настройку, включая автоматическое получение SSL-сертификатов, защиту dashboard и маршрутизацию трафика.
Если вы дошли до этого места — спасибо. Надеюсь, этот материал был полезен, а главное — показал, что даже без миллионов и команды DevOps-инженеров можно делать инфраструктуру с умом.
До встречи в следующей части!