- PVSM.RU - https://www.pvsm.ru -
1 ноября 2017 года я стал руководителем рабочей группы разработки в отделе программных разработок Timeweb. А 12 ноября 2018 руководитель отдела спросил, когда же будет готова статья для Хабрахабр, потому что отдел маркетинга спрашивает, добровольцы кончились, а контент-план требует чего-то ещё)
Поэтому хочу дать ретроспективу, как менялись процессы разработки, тестирования и поставки наших продуктов в течение последнего года. Про унаследованные процессы и инструменты, docker, gitlab и то, как идёт у нас разработка.
В нашем gitlab около 250 проектов: это клиентские приложения, внутренние инструменты, библиотеки, хранилища конфигурации. Десятки из них активно развиваются и поддерживаются: в них коммитят на протяжении рабочей недели, тестируют, собирают, релизят.
Помимо большого объёма унаследованного кода, всё это тянет за собой соответствующее количество унаследованных процессов и сопутствующих инструментов. Как и любое наследие, их тоже надо поддерживать, оптимизировать, подвергать рефакторингу, а порой и заменять.
Из всего этого обилия проектов наиболее близки для клиентов
О разных изменениях в инструментах и процессах за минувший год я и расскажу.
В первый рабочий день я попробовал поднять локально панели управления. На тот момент это было пять веб-приложений в одном репозитории:
— ПУ виртуального
— ПУ
— ПУ вебмастеров,
— STAFF (инструмент поддержек),
— Guidelines (демо стандартизированных фронтовых компонентов).
Для запуска локально использовался Vagrant. В Vagrant запускался ansible. Для запуска и настройки потребовалась помощь коллег и около дня чистого времени. Пришлось ставить особенную версию Virtual Box (на текущей стабильной были проблемы), работа из консоли внутри виртуальной машины здорово нервировала: тривиальные команды вроде npm/composer install ощутимо подтормаживали.
Производительность самих приложений в виртуальной машине была далека от возможной, учитывая используемый стек технологий и мощность машины. Не говоря о том, что виртуальная машина есть виртуальная машина, и она по определению занимает значительную часть ресурсов вашего ПК.
Окружение для локальной разработки было переписано для запуска в контейнерах docker. Контейнеризация на базе docker — наиболее распространённое решение для изолирования окружения приложений на всех этапах его жизненного цикла. Поэтому особых альтернатив тут нет.
Из плюсов:
— локально приложение стало отзывчивее, контейнеры требуют меньше, чем ВМ,
— запуск нового экземпляра, как показала практика, занимает считанные минуты и требует только docker(-compose) не ниже определённых версий. После клонирования достаточно выполнить:
make install-dev
make run-dev
Не обошлось и без компромиссов:
— пришлось написать shell-обвязки для докеризированных команд (composer, npm и т.п.). Они, как и docker-compose.yml, не совсем кроссплатформенны, в сравнении с Vagrant. Например, запуск под Mac требует дополнительных усилий, а под Windows, вероятно, будет проще запустить в виртуалке linux дистрибутив с docker. Но это приемлемый компромисс, т.к. команда использует только debian-based дистрибутивы, это допустимое ограничение для коммерческой разработки,
— для поддержки виртуальных хостов локально запускается контейнер, основанный на github.com/jwilder/nginx-proxy [2]. Не то чтобы костыль, но дополнительное ПО, о котором иногда надо помнить, хотя проблем оно не вызывает.
Да, каждому в команде пришлось хоть немного осознать, что такое docker. Хотя благодаря упомянутым shell-скриптам и Makefile разработчики выполняют 95% своих задач, не задумываясь о контейнерах, зато в гарантированно одинаковом окружении.
Эти странные словосочетания — имена машин с тестовыми стендами панелей управления, новой и старой соответственно.
Рецепты ansible использовались исключительно внутри Vagrant, так что главного преимущества достигнуто не было: версии пакетов в проде и на стендах отличались от того, в чём работали разработчики.
Несоответствие версий пакетов серверного ПО на старых стендах с тем, что было у разработчиков, приводило к проблемам. Синхронизация осложнялась тем, что у системных администраторов используется другая система управления конфигурацией, и интегрировать её с репозиторием разработчиков не представляется возможным.
После контейнеризации не составило большого труда расширить конфигурацию docker-compose для использования на тестовых стендах. Была создана новая машина, для развёртывания стендов по DOCKER_HOST.
Разработчики теперь уверены в актуальности локального и тестовых окружений.
Конфигурирование проектов в TeamCity процесс кропотливый и неблагодарный. Конфигурация CI хранилась отдельно от кода, в xml, к которому не применимы нормальное версионирование, и обзор изменений. Также мы испытывали проблемы со стабильностью процесса сборки на агентах TeamCity.
Поскольку gitlab уже использовался как хранилище для репозиториев, начать использовать его CI было не только логично, но и легко и приятно. Теперь вся конфигурация CI/CD лежит прямо в репозитории.
За год почти все проекты, собиравшиеся TeamCity, благополучно переехали в gitlab-ci. Мы получили возможность быстро реализовывать самые разные фичи по автоматизации CI/CD процессов.
Нагляднее всего будут скриншоты pipelines:
Илл. 1. feature-branch: включены все имеющиеся автоматические проверки и тесты. По завершении отправляет комментарий со ссылкой на pipeline в задачу redmine. Ручные задачи для сборки и запуска стенда с этой веткой.
Илл. 2. develop scheduled build with code freeze (checkout:rc): сборка develop по расписанию с code freeze. Сборка образов для стендов отдельных панелей управления происходит параллельно.
Илл. 3. tag pipeline: релиз одной из панелей управления. Ручная задача для отката релиза.
Кроме этого, из gitlab-ci происходит смена статусов и назначение ответственного в redmine на этапах In Progress → Review → QA, уведомление в Slack о релизах и обновлениях staging и откатах.
Это удобно, но мы не учли один методологический момент. Внедрив подобную автоматизацию в одном проекте, люди быстро привыкают к ней. И в случае переключения на другой проект, где такого ещё нет, либо процесс отличается, можно забыть подвинуть и переназначить задачку в redmine или оставить комментарий со ссылкой на Merge Request (что тоже делает gitlab-ci), заставив, таким образом, ревьюера искать нужный MR самостоятельно. При этом просто копировать куски .gitlab-ci.yml и сопутствующего shell-кода между проектами не хочется, ведь придётся поддерживать копипасту.
Вывод: автоматизация хорошо, но когда она одинаковая на уровне всех команд и проектов — ещё лучше. Буду признателен уважаемой публике за идеи, как красиво организовать переиспользование подобной конфигурации.
Постепенно наш CI стал занимать неприлично много времени. Тестировщики от этого сильно страдали: каждое исправление в master к релизу приходилось ждать по часу. Это выглядело вот так:
Илл. 4. pipeline 80 lvl min duration.
Пришлось на несколько дней погрузиться в анализ медленных мест и поиск путей к ускорению с сохранением функциональности.
Наиболее долгими местами в процессе оказалась установка npm-пакетов. Без особых проблем заменили его на yarn и сэкономили в нескольких местах до 7 минут.
Отказались от автоматического обновления staging, предпочли ручной контроль состояния этого стенда.
Ещё добавили несколько раннеров и разделили в параллельные задания сборку образов приложений и все проверки. После этих оптимизаций pipeline основной ветки с обновлением всех стендов стал занимать в большинстве случаев 7-8 минут.
Для деплоя в production и на qa-стенд использовался (и продолжает использоваться на момент написания статьи) Capistrano. Основной сценарий у этого инструмента: клонирование репозитория на целевой сервер и выполнение там же всех задач.
Раньше деплой запускался руками QA-инженера, располагающего нужными ssh-ключами, из Vagrant. Затем, по мере отказа от Vagrant, Capistrano переехал в отдельный контейнер. Сейчас деплой производится из контейнера с Capistrano с gitlab-runners, отмеченных специальными тегами и имеющих нужные ключи, автоматически при появлении нужных тегов.
Проблема здесь в том, что весь процесс сборки:
а) заметно потребляет ресурсы боевого сервера (особенно node/gulp),
б) нет возможности держать в актуальном состоянии версии composer, npm. node и т.п.
Логичнее производить сборку на билд-сервере (в нашем случае это gitlab-runner), а на целевой сервер выкладывать готовые артефакты. Это избавит боевой сервер от сборочных утилит и чуждой ему ответственности.
Сейчас мы рассматриваем deployer как замену capistrano (т.к. рубистов у нас нет, как нет и желания работать с его DSL) и планируем перенос сборки на сторону gitlab. В некоторых некритичных проектах мы его уже успели попробовать и пока довольны: выглядит проще, с ограничениями не столкнулись.
Разработка осуществляется недельными циклами. В течение пяти дней идет разработка новой версии: в develop принимаются улучшения и исправления, запланированные к выпуску на следующей неделе. В пятницу вечером автоматически происходит code freeze. В понедельник начинается тестирование новой версии, вносятся доработки, и к середине-концу рабочей недели происходит релиз.
Раньше мы использовали ветки с именами вида rc18-47, что означает релиз кандидат 47-й недели 2018 года. Code freeze заключался в checkout rc-ветки от develop. Но в октябре этого года перешли к тегам. Тэги ставились и раньше, но постфактум, после релиза и слияния rc с master. Теперь появление тега приводит к автоматическому деплою, а заморозка это слияние develop в master.
Так мы избавились от лишних сущностей в git и переменных в процессе.
Сейчас мы “подтягиваем” отстающие по процессу проекты к аналогичному workflow.
Автоматизация процессов, их оптимизация, как и разработка, — дело постоянное: пока активно развивается продукт и работает команда, будут и соответствующие задачи. Появляются новые идеи, как избавиться от рутинных действий: реализуются фичи в gitlab-ci.
С ростом приложений процессы CI начинают проходить непозволительно долго — пора работать над их производительностью. Поскольку подходы и инструменты устаревают — надо уделять время рефакторингу, пересматривая их, и обновлять.
Автор: samizdam
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/git/301244
Ссылки в тексте:
[1] Хостер: https://www.reg.ru/?rlink=reflink-717
[2] github.com/jwilder/nginx-proxy: https://github.com/jwilder/nginx-proxy
[3] Image: https://timeweb.com/ru/services/vds/?utm_source=habr&utm_medium=smo&utm_campaign=dev_promo
[4] Источник: https://habr.com/post/432150/?utm_campaign=432150
Нажмите здесь для печати.