Технологический стек, выбранный для разработки программного продукта, критически важен для успешности последнего, а выбор инструментов DevOps не менее важен, чем процесс архитектурирования будущего сервиса.
Технологический стек – это набор инструментов, которые будут использоваться для разработки, сборки и доставки кода программного продукта его пользователям, и, что самое важное, управления процессом доставки его изменений, которых в быстро меняющихся условиях бизнеса может быть очень много.
Стек технологий можно представить на следующем изображении:
Рисунок 1 – Стек технологий
Считается, что у компании аутсорсера DevOps используется свой стек технологий, которого эта компания придерживается. В таком случае, обращаясь в такую компанию, вы автоматически становитесь заложником того стека, который эта компания пропагандирует. Это хорошо и плохо одновременно. Хорошо, поскольку такая компания хорошо знакома с этим стеком и использует его профессионально, а плохо, потому что система заказчика теряет гибкость. Наша точка зрения заключается в том, что продукт должен строиться на базе лучших практик и использовать надо тот стек, который принесет максимальную эффективность в жизненном цикле продукта, а особенности и нюансы реализации должны быть за пределами планирования.
Основными категориями стека в процессе пути к DevOps-подходу можно выделить следующие:
- система версионирования
- система автоматической сборки и доставки кода
- система тестирования и проверки кода
- процесс разработки
- процесс контроля за состоянием программного продукта
- выбор площадки для хостинга
Остановимся на каждом из пунктов, рассматривая каждую из групп детальнее.
Система версионирования
Это не только система, которая управляет изменениями в коде приложения. Система контроля версий и ее настройки и функциональные возможности по сути формируют процесс разработки кода, а также напрямую влияют на процесс его сборки и доставки, а иногда, в случае с Gitlab, это еще и система сборки и доставки кода, именно поэтому в списке категорий система версионирования – первая. Самые распространенные системы – уже названный Gitlab, а также Github, Bitbucket. Давайте рассмотрим каждый из них детальнее:
Средства разработки ПО
Отслеживание задач
Безопасность и конфиденциальность
Система CICD
Github actions нельзя считать полноценной системой CICD
Систему версионирования нельзя выбирать исключительно отдельно от всего проекта, стоит оценивать комплексно весь проект и необходимость использования того или иного решения. Например, если есть острая необходимость разместить систему версионирования в контуре предприятия, то в этом случае действительно подойдет только Gitlab, что повлияет на дальнейший выбор стека, а если на проекте будет использоваться Jenkins по каким-либо причинам, а система версионирования должна быть в облаке – вполне логично использовать GitHub, который является лидером на рынке систем версионирования.*
*в данной статье умышленно не рассмотрены TFS, SVN и схожие системы, поскольку их назначение и функциональные возможности сложно приравнять к чистой системе VCS.
Система сборки и доставки кода
Конечно же, систем CICD (сборки и доставки) большое количество и обо всех мы не поговорим, выделим только самые распространенные и популярные: Jenkins, GitlabCi* (не учитываем мобильную разработку и CircleCi, а также TFS для Microsoft).
Сравнивая эти две системы может получится следующая сравнительная таблица:
Как видно из сравнительной таблицы, оба решения решают поставленные задачи CICD. Оба поддерживают возможность написания сложноподчиненных скриптов сборки и доставки кода пользователям и их изменений. Как уже говорилось, решение о выборе системы версионности и системы CICD должны приниматься комплексно. Так, если проект уже начал создаваться в GitHub и изначально компилировался и доставлялся вручную или скриптами, то есть смысл использовать Jenkins и не мигрировать репозитории в Gitlab. Исключительно субъективное мнение – Gitlab лучше использовать в более простых линейных проектах, а там где нужна сложная логика сборки и доставки кода – лучше использовать Jenkins, которым с его большим количеством плагинов может покрыть практически любую задачу DevOps-инженера или команды разработки.
Процесс разработки
Этот аспект один из самых важных в процессе планирования использования инструментов DevOps и их использования в процессе жизненного цикла программного продукта. Его также называют GitFlow – система работы с git (система версионности кода), которая организовывает работу команд разработчиков с этой системой разработки. Этот процесс будет влиять на механизмы и инструменты сборки кода и его доставки на различные среды использования программного кода. В целом, процесс разработки или GitFlow должен отражать какие среды использования программного кода должны быть развернуты, из каких веток системы версионности код должен попадать в одну или другую среду, как разработчики должны создавать новые функции приложения и чинить проблемы в уже существующем коде.
Пример такого процесса может быть представлен на рисунке ниже:
Рисунок 2 – Процесс разработки
Этот же процесс управляет версиями приложения.
Выбор этого процесса зависит от многих факторов:
- выбор модели разработки (waterflow, agile);
- длина спринта;
- время тестирования RC;
- время тестирования пользователями;
- время на внесения изменений в уже выпущенный продукт;
- и многое другое.
Нет единого шаблона использования GitFlow. Каждая команда разработки использует свой, поскольку у каждой свой специфический программный продукт со своими специфическими бизнес требованиями, но важно помнить:
- Всегда должна быть стабильная ветка с кодом, которую можно собрать и доставить пользователям. Обычно это мастер, но ее название не обязательно.
- Создание новых функций должно происходить от текущей ветки, в которой ведутся разработки и сливаться в нее обратно.
- Перед выкатом приложения пользователям должны быть сформированы артефакты из ветки, в которую слили все новые функции и протестированы на тестовой среде, а при выявлении ошибок – правки должны быть внесены в эту же ветку.
- После успешного тестирования эти же артефакты, которые прошли тестирование, должны быть доставлены пользователям.
Процесс контроля за состоянием программного продукта
В этот пункт, по нашему мнению, должны быть включены те инструменты, которые позволят:
Первый пункт могут закрыть в комплексе Prometheus и Zabbix, в зависимости от выбранного способа размещения среды выполнения кода. Так, Prometheus соберет метрики внутри приложения и его функциональных модулей о загрузке CPU, RAM, DISK IO, 4XX и 5XX ошибок балансировщика (облачного или NGINX, или HAproxy) и даст обзорную картину функционирования приложения внутри системы. А Zabbix в свою очередь отлично справится с задачей мониторинга железа, на котором размещена система, конечно же, в зависимости от выбранного заказчиком способа размещения.
Сравнительная таблица Prometheus и Zabbix:
Второй пункт решается централизованным хранением и обработкой логов приложения и всех его частей, в том числе балансировщиков и внутренних сервисов, вплоть до системы выдачи SSL-сертификатов. Самый распространенный набор инструментов в этой сфере – ELK (Elasticsearch, Logstash, Kibana), где Elasticsearch занимается систематизацией и поиском логов, Logstash – отвечает за сбор и правильное форматирование событий приложения, а Kibana – за отрисовку систематизированной информации. Модификаций этого стека большое количество, которые зависят от стека, выбранного в процессе планирования. Важно то, что логи должны быть в едином месте с возможностью уведомления команды разработчиков о появлении важных событий в жизненном цикле программного продукта.
Также, хотелось бы заметить, что есть программные продукты, которые агрегируют в себе вышеупомянутые пункты, одним из которых является Datadog, который предоставляет единое пространство для сбора метрик, хранения и обработки событий приложения и удобного интерфейса по работе с ним. Если упомянутые в первом и втором пункте решения могут быть использованы бесплатно, то DataDog является платным решением.
Третий пункт говорит о том, что нужно выполнять резервное копирование:
- Резервное копирование базы данных (скриптами в системе CICD, скриптами в Cron) или использовать версионирование в s3 bucket. Все зависит от того, где вы храните постоянные данные, которые важно сохранить.
- В процессе создания инфраструктуры важно использовать методологию Iac (Infrastructure as a Code). Это позволит в случае катастрофы относительно быстро восстановить систему с нуля, а также просто повторить действия по настройке системы в случае линейного ее масштабирования. В качестве инструментов Iac, в зависимости от типа размещения инфраструктуры, используют – terraform, ansible, pulumia, которые позволяют декларативно описать будущую платформу, на которой будет размещаться приложение.
Выбор площадки для хостинга
Этот пункт мы поставили последним не зря. Выбор площадки размещения приложения может в целом кардинально изменить стек технологий, который могут применяться в процессе жизненного цикла продукта. При выборе площадки изначально нужно определиться: размещение будет On-premises (т.е. управление аппаратными серверами или виртуальными машинами будет осуществляться нами) или hosted (размещение у облачного провайдера).
Ярким примером On-premises размещения – будет размещение аппаратных мощностей в стойке (в соседнем здании или в дата-центре), где построение инфраструктуры будет идти с нуля и начинаться с выбора системы виртуализации и проектирования физической сети.
Облачным размещением будет считаться использование таких провайдеров как AWS, Azure, GCP, DigitalOcean, Яндекс.Cloud, SberCloud.
Зачастую облачные провайдеры предоставляют свой стек технологий, который вы можете использовать в процессе жизненного цикла программного продукта. Так, наверное, одним из самых широких и распространенных стеков будет AWS, где:
- в качестве системы версионирования может использовать CodeCommit
- в качестве системы CICD – CodeDeploy
- в качестве системы Iac – CloudFormation
- в качестве системы логирования и мониторинга – Cloudwatch
- а также много других сервисов, которые позволят реализовать любую модель разработки, которую только можно представить
Но минусом выбора такого размещения будет бюджет, именно поэтому, компании зачастую выбирают гибридную схему размещения:
- можно использовать ECS кластер AWS для размещения контейнеров или webapp Azure
- при этом использовать Gitlab или Github в качестве системы версионирования
- использовать Jenkins или GitlabCi в качестве системы CICD для создания контейнера и размещения сервиса и задач для развертывания вашего приложения в ECS-кластере или WebApp
- использовать cloudwatch для мониторинга совместно с Prometheus и Grafana
- использовать Elasticsearch, развернутый на ec2 инстансах AWS и с помощью AWS FireLens доставлять логи с ECS в созданный кластер Elasticsearch
- и т.д.
Одним из важных пунктов выбора размещения платформы для программного продукта будет бюджет, а также функциональные требования к продукту, поддержке и стабильности хостинга, на котором планируется разворачивать сервис или программный продукт.
Подводя итог всего вышеизложенного, важно отметить, что:
- Нельзя ограничиваться каким-то одним стеком или его вариацией – нужно исходить из бизнес-задач конкретного программного продукта и особенностей его функционирования и подбирать технологический стек под эти задачи.
- Важно придерживаться основных принципов разработки и методологии DevOps как при выборе стека, так и при его реализации.