- Настройка CI/CD в GitLab для синхронизации проекта с веб-серверами
- Установка и регистрация Runner
- Установка
- Регистрация
- Создание CI/CD для проекта
- Настройка Rsyncd
- Настройка на веб-серверах
- GitLab Shell Runner. Конкурентный запуск тестируемых сервисов при помощи Docker Compose
- Содержание
- Предпосылки
- GitLab Shell Runner
- Подготовка docker-compose.yml
- Подготовка Makefile
- Подготовка .gitlab-ci.yml
- Запуск интеграционных тестов
- Очистка раннера
- Результат
Настройка CI/CD в GitLab для синхронизации проекта с веб-серверами
Runner в GitLab позволяют автоматизировать рутинные задачи при обновлении проектов в репозитории. В нашем примере мы рассмотрим ситуацию, когда у нас используется сервер GitLab для хранения проекта и 5 веб-серверов, куда должны попадать изменения после выполнения git push. Мы настроим наш CI/CD на синхронизацию файлов с помощью rsyncd. Предполагается, что у нас уже установлен GitLab на Linux, в противном случае, воспользуйтесь инструкцией для Ubuntu или CentOS.
Нам потребуется выполнить:
Установка и регистрация Runner
Runner — это отдельное приложение, которое запускается для выполнения заданий CI/CD. Его можно установить любой компьютер под управлением любой популярной операционной системы (Linux, Windows, BSD, Mac OS и так далее). Также доступны различные варианты установки — из репозитория, скачивание бинарника или запуск как приложения в Docker или кластере Kubernetes. Мы выполним установку из репозитория Linux на тот же сервер, где работает наш GitLab.
Установка
По умолчанию, Runner не устанавливается вместе с GitLab. Для его установки необходимо сначала настроить репозиторий — наши действия зависят от используемой системы.
а) система на базе deb-пакетов (Debian / Ubuntu):
curl -L «https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh» | sudo bash
б) система на базе RPM-пакетов (Red Hat / CentOS):
curl -L «https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh» | sudo bash
После настройки репозитория, выполняем установку. Команда также зависит от типа операционной системы.
а) для Debian / Ubuntu:
apt-get install gitlab-runner
б) для Red Hat / CentOS:
yum install gitlab-runner
После установки gitlab-runner разрешаем автозапуск сервиса и стартуем его:
systemctl enable gitlab-runner —now
Регистрация
Для корректной работы Runner его нужно связать с нашим проектом в GitLab. Для этого сначала заходим на портал последнего — переходим на страницу проекта — в меню слева выбираем Settings — CI / CD:
Находим раздел Runners:
Справа от названия кликаем по Expand:
Находим параметры для регистрации нового раннера:
. и оставляем страницу открытой — она понадобиться на следующем шаге.
В командной строке нашего сервера GitLab вводим:
* установить и запустить Runner можно не только на локальном сервере GitLab, но мы рассмотрим только данный способ.
Система в интерактивном режиме запросит данные для регистрации — вводим их:
Enter the GitLab instance URL (for example, https://gitlab.com/):
https://gitlab.dmosk.ru/
Enter the registration token:
zX_Kvkxk7ywrgwYHsod5
Enter a description for the runner:
[git-server.dmoks.ru]: DMOSK Metrics API
Enter tags for the runner (comma-separated):
dmosk, metrics, api
Registering runner. succeeded runner=zX_Kvkxk
Enter an executor: parallels, virtualbox, docker+machine, docker-ssh+machine, kubernetes, custom, docker, docker-ssh, shell, ssh:
shel
- https://gitlab.dmosk.ru/ — адрес нашего сервера GitLab. Его можно увидеть на странице с параметрами, которую мы оставили открытой на предыдущем шаге. В моем случае, на данной странице ссылка была типа http, однако, при регистрации Runner мы ее должны поменять на https (если наш сервер использует его).
- zX_Kvkxk7ywrgwYHsod5 — токен для регистрации раннера. Его смотрим на странице с параметрами, которые мы открывали выше.
- DMOSK Metrics API — произвольное описание для нашего раннера.
- dmosk, metrics, api — теги. Рекомендуется максимально точно описывать раннер тегами.
- shell — выбираем исполнителя из предложенных вариантов. В нашем случае это просто командный интерпретатор.
В конце мы должны увидеть:
Runner registered successfully. Feel free to start it, but if it’s running already the config should be automatically reloaded!
* если мы получим ошибку «status couldn execute post against certificate signed by unknown authority», переходим к решению ниже.
Обновим страницу с параметрами для регистрации раннера — ниже мы должны увидеть, что у нас появился один новый элемент. Кликаем по изображению редактирования справа от токена:
Выставляем следующие галочки для настройки Runner:
- Paused Runners don’t accept new jobs — если наш обработчик заданий приостановлен, он не принимает новые задания.
- This runner will only run on pipelines triggered on protected branches — Runner должен запускаться только на защищенных ветках.
- Indicates whether this runner can pick jobs without tags — раннер может запускать задания без тегов.
- When a runner is locked, it cannot be assigned to other projects — если обработчик заблокирован, его нельзя назначать для других проектов.
И так, обработчик зарегистрирован и настроен. Переходим к созданию CI/CD.
Создание CI/CD для проекта
На первоначальном этапе, мы создадим простой сценарий, который просто будет выводить путь до каталога на сервере, в котором находится проект.
Переходим в GitLab на страницу проекта и кликаем по Set up CI/CD:
* данной кнопки может и не быть.
. или можно просто в корне проекта создать файл:
Задаем содержимое нашего сценария:
test:
stage: test
script: echo $CI_PROJECT_DIR/
* Из расширения файла понятно, что формат текста должен быть yml, а значит, отступы имеют значения. В данном примере мы создаем pipeline с одним единственным этапом, которое называется test. По данному заданию будет запускаться скрипт вывода значения переменной $CI_PROJECT_DIR — путь, по которому клонируется проект и где выполняется задание (если установлен $builds_dir, эта переменная устанавливается относительно данного значения. Список возможных переменных можно посмотреть на официальном сайте в разделе документации GitLab CI/CD environment variables.
После сохранения файла ждем несколько секунд и перезапускаем страницу — мы должны увидеть успешный результат выполнения сценария CI/CD:
Кликнем по значку зеленой галочки и в открывшейся странице кликаем по нашей единственной стадии:
Мы должны увидеть ход процесса выполнения задания и результат его работы:
На этой же странице справа можно вручную запустить задание еще раз:
CI/CD создан. Теперь необходимо подготовить систему к синхронизации данных.
Настройка Rsyncd
Наша синхронизация будет выполняться с помощью Rsyncd. Это удобный инструмент, с помощью которого можно поддерживать актуальное состояние двух и более каталогов. Также у нас не возникнет проблем с правами — rsync после копирования будет задавать файлам нужного владельца и нам не нужно будет выдавать права root для runner с помощью файла sudoerst. Подробнее об установке и настройке Rsyncd.
Настройки нужно выполнить как на веб-серверах, так и сервере с GitLab.
Настройка на веб-серверах
Данные действия нужно выполнить на каждом веб-сервере. Мы должны установить и настроить в качестве сервиса rsyncd. Сначала установим его. В зависимости от типа Linux, наши действия будут различаться.
GitLab Shell Runner. Конкурентный запуск тестируемых сервисов при помощи Docker Compose
Данная статья будет интересна как тестировщикам, так и разработчикам, но рассчитана в большей степени на автоматизаторов, которые столкнулись с проблемой настройки GitLab CI/CD для проведения интеграционного тестирования в условиях недостаточности инфраструктурных ресурсов и/или отсутствия платформы оркестрации контейнеров. Я расскажу, как настроить развертывание тестируемых окружений при помощи docker compose на одном единственном GitLab shell раннере и так, чтобы при развертывании нескольких окружений запускаемые сервисы друг другу не мешали.
Содержание
- Предпосылки
- GitLab Shell Runner
- Подготовка docker-compose.yml
- Подготовка Makefile
- Подготовка .gitlab-ci.yml
- Запуск интеграционных тестов
- Очистка раннера
- Результат
Предпосылки
В моей практике частенько случалось «лечить» интеграционное тестирование на проектах. И зачастую первой и самой значительной проблемой является CI pipeline, в котором интеграционное тестирование разрабатываемого сервиса(ов) проводится в dev/stage окружении. Это вызывало не мало проблем:
- Из-за дефектов в том или ином сервисе в процессе интеграционного тестирования тестовый контур может быть испорчен битыми данными. Бывали случаи, когда отправка запроса с битым JSON-форматом вешал сервис, что приводило стенд полностью в нерабочее состояние.
- Замедлением работы тестового контура с ростом тестовых данных. Думаю, описывать пример с очисткой/откатом БД не имеет смысла. В своей практике я не встречал проекта, где эта процедура проходила бы гладко.
- Риск нарушить работоспособность тестового контура при тестировании общих настроек системы. Например, user/group/password/application policy.
- Тестовые данные от автотестов мешают жить ручным тестировщикам.
Кто-то скажет, что хорошие автотесты должны чистить данные после себя. У меня есть аргументы против:
- Динамические стенды весьма удобны в использовании.
- Не каждый объект можно удалить из системы через API. Например вызов на удаление объекта не реализован, так как противоречит бизнес логике.
- При создании объекта через API может создаваться огромное количество метаданных, которые удалить проблематично.
- Если тесты имеют зависимость между собой, то процесс очистки данных после выполнения тестов превращается в головную боль.
- Дополнительные (и, на мой взгляд, не оправданные) вызовы к API.
- И главный аргумент: когда тестовые данные начинают чистить прямо из БД. Это превращается в настоящий PK/FK цирк! От разработчиков слышно: «Я только табличку добавил/удалил/переименовал, почему 100500 интеграционных тестов попадало?»
По моему мнению, самое оптимальное решение — это динамическое окружение.
У меня есть собственный GitLab раннер для своих проектов и с этими вопросами я столкнулся при разработке Java клиента для TestRail. А точнее при запуске интеграционных тестов. Вот далее и будем решать эти вопросы с примерами из данного проекта.
GitLab Shell Runner
Для раннера рекомендую линуксовую виртуалку с 4 vCPU, 4 GB RAM, 50 GB HDD.
На просторах интернета очень много информации по настройке gitlab-runner, поэтому коротко:
- Заходим на машинку по SSH
Если у вас менее 8 GB RAM, то рекомендую сделать swap 10 GB, чтобы не приходил OOM killer и не убивал нам задачи из-за нехватки RAM. Такое может случится, когда запускается одновременно более 5 задач. Задачи будут проходить помедленнее, зато стабильно.
Если в логах задачи вы увидите bash: line 82: 26474 Killed , то просто выполните на раннере sudo dmesg | grep 26474
И если картина выглядит примерно так, то или добавляйте swap, или докидывайте RAM.
Открываем на редактирование /etc/gitlab-runner/config.toml и добавляем
Это позволит запускать параллельные задачи на одном раннере. Более подробно читать тут.
Если у вас машинка помощнее, например 8 vCPU, 16 GB RAM, то эти цифры можно сделать как минимум в 2 раза больше. Но все зависит от того, что конкретно будет запускаться на данном раннере и в каком количестве.
Подготовка docker-compose.yml
Основная задача — это универсальный docker-compose.yml, который разработчики/тестировщики могут использовать как локально, так и в CI pipeline.
В первую очередь мы делаем уникальные названия сервисов для CI. Одной из уникальных переменных в GitLab CI является переменная CI_JOB_ID . Если указать container_name со значением «service-$
- если CI_JOB_ID не определена в переменных окружения,
то имя сервиса будет service-local - если CI_JOB_ID определена в переменных окружения (например 123),
то имя сервиса будет service-123
Во вторую очередь мы делаем общую сеть для запускаемых сервисов. Это дает нам изоляцию на уровне сети при запуске нескольких тестовых окружений.
Собственно, это первый шаг к успеху =)
Пример локального запуска
Но не все так просто с запуском в CI.
Подготовка Makefile
Я использую Makefile, так как это весьма удобно как для локального управления окружением, так и в CI. Далее комментарии инлайн
Подготовка .gitlab-ci.yml
Запуск интеграционных тестов
В результате запуска такой задачи в артефактах директория logs будет содержать логи сервисов и тестов. Что очень удобно в случае возникновения ошибок. У меня каждый тест в параллели пишет свой лог, но об этом я расскажу отдельно.
Очистка раннера
Задача будет запускаться только по расписанию.
Далее идем в наш GitLab проект -> CI/CD -> Schedules -> New Schedule и добавляем новое расписание
Результат
Запускаем 4 задачи в GitLab CI
В логах последней задачи с интеграционными тестами видим контейнеры от разных задач
Артефакты задачи содержат логи сервисов и тестов
Вроде все по красоте, но есть нюанс. Pipeline может быть принудительно отменен во время выполнения интеграционных тестов, и в этом случае запущенные контейнеры не будут остановлены. Время от времени нужно чистить раннер. К сожалению, задача на доработку в GitLab CE все еще в статусе Open
Но у нас добавлен запуск задачи по расписанию, и никто нам не запрещает ее запустить вручную.
Переходим в наш проект -> CI/CD -> Schedules и запускаем задачу Clean runner
- У нас один shell runner.
- Конфликтов между задачами и окружением нет.
- У нас параллельный запуск задач с интеграционными тестами.
- Можно запускать интеграционные тесты как локально, так и в контейнере.
- Логи сервисов и тестов собираются и прикрепляются к pipeline-задаче.
- Есть возможность очистки раннера от старых docker-образов.
2 часа.
Вот, собственно, и все. Буду рад фидбэку.