Gitlab CI и BitrixVM: автоматическое развертывание площадки для тестирования кода

Введение

В данной статье описан мой опыт по настройке одного из этапов разработки, связанного с необходимостью тестирования написанного кода на виртуальной машине от битрикс. Для понимания статьи необходимо базового знать, что такое menu.sh в bitrixVM и принцип работы Gitlab CI и, соответственно, что описано в файле .gitlab-ci.yml.

В качестве вступления будет немного лирики. Если все предпосылки не интересны, можно сразу начинать читать с основной части по настройке.

Сейчас на слуху практики DevOps, CI/CD и прочие штуки, которые ещё не все люди воспринимают всерьёз. В моём же случае максимум, чем приходилось заниматься из этой области – это установка и настройка Gitlab runner на простых проектах на битрикс с тремя контурами – “прод”, “препрод” и “тест”, где runner выполняет git pull из нужной ветки при коммите. Получился самый простой и примитивный pipeline. И по большей части этого всегда хватало – разработчикам или сисадминам не надо ходить руками на сервер, чтобы выкатить код, а всё остальное делали тестировщики на тестовом или препродуктивном контуре.

Но можно было бы навсегда остаться где-то в прошлом, так и не попробовав чуть большего, что может предоставить Gitlab и прочие CI системы. Всё это было не нужно, пока не появился крупный проект, где процесс разработки стал куда более сложным, а тестировать несколько фичей на одном единственном контуре стало затруднительно. И вот тут-то все и вспомнили про практики DevOps, автоматизированное тестирование и прочее.

Мне была поставлена задача настроить автоматический деплой площадок\контуров\среды – называйте, как угодно, на которых независимо можно было бы тестировать каждую ветку (фичу).

Основная часть

Из общей базы у меня были лишь поверхностные знания, как это примерно должно работать из различных статей на хабре. Отсутствие знакомых, кто бы мог подсказать, как делать всё правильно, немного тормозило меня и шло вопреки перфекционизму – хотелось сделать хорошо и правильно, но я не знал, с чего начать.

В конечном итоге, начитавшись документации Gitlab, родилась идея, в основе которой заложено использование виртуальной машины от битрикс, где уже по большей части всё готово и настроено, нужно лишь внести немного автоматизации и настроить процесс интеграции с Gitlab.

Алгоритм развертывания площадки следующий:

  1. Есть разрабатываемый проект;
  2. Возникает потребность в новом функционале;
  3. Разработчик ветвится от основной ветки;
  4. В ветке с именем feature/01 разрабатывается новый функционал;
  5. Возникает потребность независимо от других задач протестировать код из feature/01;
  6. Разработчик открывает merge request;
  7. При открытии мержа создаётся environment – копируются файлы и база с эталона (прода), раскатываются конфиги веб-сервера и бд, а ветка в директории проекта переключается на feature/01;
  8. environment представляет собой обычный сайт с нужным функционалом из feature/01, который создается при выполнении определенного этапа из .gitlab-ci.yml, и по сути и является конечной целью.

Под капотом пунктов 5-7 кроется bash и немного магии, о которой расскажу более подробно.

Сервер

И всё начинается с сервера — необходимо подготовить тачку, на которой непосредственно будут разворачиваться необходимые сайты для тестирования. Условно этот сервер будет иметь hostname srv-bx-qa

  • На сервере установлено битрикс-окружение (apache, nginx, php, mysql – всё на одной ВМ);
  • Для скорости добавлен SSD-диск с разделом под БД и файлы и смонтирован по пути /mnt/u01;
  • В файле /root/.bash_profile закомментирована строка #~/menu.sh, которая вызывает автоматический запуск menu.sh при открытии оболочки – это мешает выполнению команд gitlab runner, а потому сразу отключается;
  • На самом сервере выполнена настройка и запущен gitlab runner с тэгом qa-env
  • С сервера srv-bx-qa настроен беспарольный доступ по ssh на сервер эталонный контур (прод), для копирования файлов через rsync – ядро и прочие необходимые файлы для битрикса будут эталонной основой для нового контура.

bitrix-env

Развертывание целевого environment (далее – контур или среда) происходит штатными средствами bitrix-env, только в отличие от ручного метода (скрипт menu.sh) используется API, описанный в документации

Например, создание сайта test1 через API будет выглядеть следующим образом:

/opt/webdir/bin/bx-sites -a create -s site1 -d site1_db -t kernel -u site1_user -p 'site1_user_pass' -r /mnt/u01/ext_www/site1

Аналогично и удаление:

/opt/webdir/bin/bx-sites -a detete -s site1

Всё вышеописанное заполняется обычно вручную при классическом создании\удалении сайта через menu.sh, в результате чего генерируются конфиги для веб-серверов и БД. А значит, есть возможность использовать автоматизацию при развертывании сайта, указывая динамически создаваемые имена. Например, в какой-нибудь CI-системе — Gitlab в данном случае, т.к. он используется в качестве СКВ.

Gitlab

В Gitlab располагается репозиторий исходного проекта, в корне которого файл .gitlab-ci.yaml выполняет описанные в нём инструкции при различных событиях (commit, merge request & etc) посредством gitlab-runner, который установлен на  целевом сервере srv-bx-qa.

Основные переменные

В .gitlab-ci.yaml используются встроенные переменные окружения внутри самого gitlab, на основе которых создаются доменные имена сайтов, имена БД, пользователей и т.д.

  • $CI_PIPELINE_SOURCE – указывает, что происходит событие “merge_request_event”, которое является условием срабатывания pipeline;
  • $CI_COMMIT_REF_NAME – имя ветки или тэга;
  • $CI_COMMIT_REF_SLUG – имя ветки или тэга, ограниченное 63 байтами и исключающее символы, которые не могут быть использованы в URL. Применяется для создания доменного имени на основе имени ветки.

На основе трех вышеописанных переменных создается уникальное доменное имя для будущего сайта.

Создание сайта

В .gitlab-ci.yaml описана job с именем “review” – она-то и будет создавать новый сайт:

review:
  stage: review
  script:
    - /opt/scripts/deploy_env.sh create
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    allow_failure: true
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_COMMIT_REF_SLUG.tech.domain.ru/
    on_stop: stop_review
    auto_stop_in: 4 days
  tags:
    - qa-env

Во фрагменте “кода” выше при выполнении job “review” будет выполнен скрипт /opt/scripts/deploy_env.sh create, который выполнит установку и подготовку серверного окружения. Условием срабатывания данной job является открытие мерж реквеста.

Помимо создания и подготовки сайта на самом сервере через bash-скрипт, создается environment – сущность уже в самом гитлабе, которая позволяет управлять непосредственно созданной площадкой в данном случае.

environment имеет имя, URL, по которому доступен сайт, и условия удаления. В данном случае среда автоматически самовыпилится через 4 дня, а для штатного удаления используется отдельная job с именем “stop_review”:

stop_review:
stage: review
variables:
# не подтягивать изменения. Необходимо, если ветка удалена
GIT_STRATEGY: none
script: /opt/scripts/deploy_env.sh delete
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
allow_failure: true
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
tags:
- qa-env

Наименование stage здесь должно быть аналогичным предыдущему, т.е. “review”. bash-скрипт /opt/scripts/deploy_env.sh delete будет при выполнении удаляет раскатанный сайт и всю созданную конфигурацию.

Отличительной особенностью является условие “manual” – в данном случае данная job будет выполнена при нажатии кнопки в самом gitlab, удалении environment или закрытии мерж реквеста. Это будут использовать тестировщики: сайт раскатывается автоматически, тестеры прогоняют свои тесты, а потом удаляют площадку вручную после завершения тестирования. Да, до автотестов ещё не дошли и люди ходят руками по сайту в поисках багов :)

В разделе CI / CD -> Jobs будет видно два задания:

скриншот гитлаба
Нажмите для увеличения

passed – это первая часть – создание сайта и всего необходимого, выполнилась при открытии мержа

manual – автоматически появляется и ожидает исполнения, т.е. ручного нажатия на кнопку “Play”

Проверить и открыть среду для тестирования в браузере можно по пути Opertions→Environments в интерфейсе Gitlab.

bash-скрипт

Создание и удаление сайта выполняется через функции несложного скрипта на bash, полный код представлен на github

Настройка проксирования

В результате создания среды доменные имена будут вида feature-01-your-qa.domain.ru. Для проксирования используется Nginx, слушающий запросы вида *.your-qa.domain.ru и с настроенным wildcard-сертификатом.

Заключение

В результате вышеописанных действий поставленная задача выполнена – тестировщики теперь имеют возможность тестировать ветки в изолированной среде и не мешать друг другу.

Вопрос лишь в том, насколько всё сделано правильно. Мне всегда кажется, что больше какая-то кустарщина. В любом случае, это был первый блин, и пока не ясно, вышел ли он комом, но в результате выполнения данной задачи были рассмотрены различные возможности по организации доставки кода и настройки площадок. Как известно, нет пределу совершенства, поэтому возможности Gitlab будут изучаться дальше и апробироваться на какие-то конкретных кейсах.

Более подробную информацию можно получить в документации гитлаб, а битрикс в данном случае – лишь частный случай, тем не менее, документация у них тоже вполне себе хорошая.

UPD. Спустя некоторое время использования, вылезли подводные камни придуманного решения:

1. Условие развёртывания контура (напомню, что это происходит при открытии мержа) только мешает, т.к. не всегда требуется раскатка площадки тестирования, а потому условие было перепилено на ручное в .gitlab-ci.yaml:

variables:
  GIT_STRATEGY: none
  
review:
  stage: review
  script:
    - "/opt/scripts/deploy.sh create"
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_COMMIT_REF_SLUG.domain.ru/
    on_stop: stop_review
    auto_stop_in: 1 days
  rules:
    - if: '$CI_COMMIT_REF_NAME =~ "feature" && $CI_PIPELINE_SOURCE == "web"'
      allow_failure: true
  tags: 
    - qa

И теперь пайплайн запускается вручную при необходимости – так даже удобнее, чем первоначальная идея. Но всё зависит от конечной цели.

2. И второй нюанс, который поставил крест на всей идее для полноценного использования: при наплыве тестировщиков развертывание сайтов становится крайне медленным и job`ы зависают. У меня в скрипте очень примитивные проверки статусов сайтов в цикле, и пока не истинны условия для выхода из цикла, job будет висеть. А условиями является проверка статуса вызова API и наличия\отсутствия конфигов.

В итоге не совсем понятно, где проблема: при ручном использовании menu.sh хотя бы с одной фоновой задачей, он уже всегда подтормаживал, а с примитивной автоматизацией и несколькими пользователями, которые постоянно раскатывают\удаляют площадки тестирования, и подавно. Или же диски не вывозят (на самом деле используется обычный SATA SSD с другими проектами ещё в нагрузку). Ну, и вся идея стала не очень удобна для использования, но был получен интересный опыт. Возможно, как дойдут руки, эту связку попробую применить уже к другому проекту на kubernetes.

У reg.ru есть возможность получить облачный сервер для развертывания bitrixVM, можно посмотреть подробнее по этой ссылке (реферальная): https://www.reg.ru/vps/cloud/?rlink=reflink-6744079

Используемые источники

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: