Настройка CI/CD для Gitlab-репозитория: схемы и гайд по шагам
Рассказываем, как работать с CI/CD. Сравнение инструментов и подробный гайд по сборке и развертыванию через Docker на удаленный сервер с помощью Gitlab CI/CD на примере Spring Boot-приложения.
Привет! Меня зовут Николай, я Backend-разработчик в РЕЛЭКС. В статье ты найдешь полезный теоретический материал и сравнение инструментов CI/CD. Покажу, как настроить сервер и поделюсь полезными командами, которые помогут в работе.
-
Начнём с теории: коротко о CI/CD — это база.
-
Инструменты работы с CI/CD: выбираем свой.
-
Как устроен процесс CI/CD: схема работы.
-
Переходим к практике: настройка виртуального сервера.
-
Настройка конфига .gitlab-ci.yml.
Начнём с теории: коротко о CI/CD — это база
CI/CD (Continuous Integration / Continuous Deployment) —ÂÂÂÂ это непрерывная интеграция и развертывание, предназначенные для повышения удобства, частоты и надежности публикации изменений программного обеспечения или продукта, где:
CI — это практика разработки ПО, при которой изменения в коде автоматически собираются, тестируются и интегрируются в целевую ветку репозитория. Основная идея — минимизация разрыва между компонентами проекта и быстрая обратная связь о качестве кода, благодаря автоматической сборке и тестированию.
CD — это продолжение CI, которое позволяет автоматически разворачивать успешно собранный и протестированный код на сервере или другой среде реального применения. Цель — автоматизация процесса разработки и развертывания приложения или программного продукта после всех этапов проверки и тестирования. Развертывание в продакшн должно выполняться после ручного подтверждения деплоя, чтобы предоставить дополнительный уровень контроля и безопасности.
Инструментов работы с CI/CD огромное множество — самыми популярными считаются:
Gitlab CI/CD — полностью интегрированная в GitLab система для автоматизации сборки, тестирования и развертывания программного кода. GitLab CI/CD использует файл конфигурации YAML в репозитории проекта для определения правил работы на каждом этапе в пайплайне. Поддерживает использование Docker-образов для определения окружения сборки — отсюда большая гибкость и повторное использование кода.
Jenkins — система с открытым исходным кодом для внедрения CI/CD для автоматизации процесса разработки. Jenkins — самостоятельное приложение, которое требует настройки на сервере, зато предлагает обширный набор плагинов. Это расширяет его функциональность и интеграцию с другими системами и сервисами.
Azure DevOps — отдельное комплексное решение от Microsoft с набором инструментов разработки. Оно позволяет командам планировать работу, совместно создавать код и доставлять приложения. Для автоматизации сборки, тестирования и развертывания приложений используется инструмент Azure Pipelines.
TeamCity — сервер непрерывной интеграции от JetBrains. У TeamCity открытая архитектура, которая позволяет разработчикам создавать плагины для расширения функционала. Некоторые функции бесплатны, но для больших команд и проектов может потребоваться покупка коммерческой лицензии, с чем сейчас возникают сложности.
Выбор инструмента зависит от ваших целей, задач и сложности реализации.
Задача — развернуть Spring Boot-приложение, расположенное в Gitlab-репозитории на продакшн стенде. Сделать это надо с помощью удобного и простого инструмента, чтобы начать использовать его функционал сразу, «из коробки» — Gitlab CI/CD отлично подходит. Он полностью интегрирован со средой Gitlab. Не требует дополнительной установки, а также имеет поддержку и подробную документацию.
С выбором инструмента разобрались. Перейдем к главному: как устроен процесс CI/CD. Ниже — схема его работы.
Как устроен процесс CI/CD: схема работы
Алгоритм схемы следующий:
Разработчик пишет код и заливает его в GitLab-репозиторий проекта.ÂÂÂÂ
GitLab ищет в корне репозитория конфиг .gitlab-ci.yml и, когда находит, запускает пайплайн согласно описанной в конфиге логике.
Пайплайн (pipeline) представляет собой целиковый процесс из этапов или стадий (stage), которые состоят из задач (job). Каждая задача выполняется в изолированном процессе (используется GitLab Runner).
Что за термины мы описали выше?
Раннер — приложение, в рамках которого выполняются задачи и которое можно развернуть на разных типах систем: Linux, macOS, Windows, Docker, Kubernetes и так далее.
Задачи — «кирпичики», из которых строится процесс CI/CD. Это может быть сборка проекта (компиляция, подтягивание зависимостей) или прогон автотестов, или публикация собранного кода в Docker-репозиторий. По умолчанию задачи выполняются изолированно, но их можно связать между собой при помощи артефактов.ÂÂÂÂ
Артефакты — исполняемые файлы или пакеты для передачи результатов выполнения одной задачи на вход другой. Это позволяет управлять жизненным циклом программного продукта. Пример артефактов — скомпилированные бинарные файлы, архивы, образы контейнеров.
Этапы — служат для группировки задач и определения порядка их выполнения. Задачи, принадлежащие одному этапу, выполняются параллельно, если доступно достаточное количество раннеров. Этапы будут выполняться в порядке, указанном в конфиге.
Пайплайн — верхнеуровневый элемент процесса CI/CD, включающий в себя этапы и задачи.
Переходим от теории к практике. Теперь только пайплайны! Только хардкор!
Переходим к практике: настройка виртуального сервера
Переходим к настройке сервера. Процесс займет не одно действие, поэтому пойдем последовательно, шаг за шагом:
Шаг 1: Установка Docker
Официальный сайт руководства по Docker предоставляет удобный скрипт для неинтерактивной установки Docker. Такой вариант, скорее, подходит для рабочего окружения, а не для продакшена.ÂÂÂÂ
С помощью curl-команды скачаем sh-файл для запуска и настройки докера.
curl -fsSL https://get.docker.com -o get-docker.sh
Затем запустим его для установки необходимых зависимостей.
sudo sh ./get-docker.sh
Шаг 2: Скачивание и запуск контейнера GitLab Runner в Docker
В официальном руководстве Gitlab есть описание нескольких вариантов GitLab Runner. В этой статье рассмотрим установку через Docker — более простую для развертывания и версионирования. Также меньше нагружает сервер скачиванием дополнительных пакетов. Для наших целей будем использовать облегченный образ GitLab Runner последней версии:
docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:alpine
После установки можно выполнить команду docker-ps и посмотреть, что появился контейнер с GitLab Runner.ÂÂÂÂ
Помимо создания собственных раннеров, которые привязаны к конкретному проекту или группе, в GitLab есть так называемые “Shared runners”, которые доступны для всех проектов в пределах организации или всего инстанса GitLab. Такие раннеры обычно настраиваются администраторами и имеют общую конфигурацию, которую нельзя изменить на уровне отдельного проекта.
Облачная версия gitlab.com предоставляет несколько таких раннеров, которые можно использовать для ваших проектов. Они располагаются в блоке “Shared runners”. Проверьте, чтобы был активен чекбокс “Enable shared runners for this project”.
Шаг 3: Регистрация нового GitLab RunnerÂÂÂÂ
Команда с официального руководства Gitlab, где:
—
—
Если вы используете свою установку GitLab, то в качестве параметра Runner registration URL, указываете ее URL-адрес. Если используется облачная версия, то https://gitlab.com/.
Чтобы узнать параметр Registration token перейдите в репозиторий проекта, в левой панели откройте меню Settings > CI/CD и разверните секцию Runners. В этой секции, в разделе Project runners, нажмите на троеточие справа от кнопки New project runner, где находится токен.
docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner:alpine register \
--non-interactive \
--url \
--registration-token \
--executor docker \
--description "Brief description for the project" \
--tag-list "docker" \
--docker-image alpine:latest \
--docker-privileged \
--docker-volumes "/certs/client"
Выполнили команду — переходим во вкладку Runners в настройках CI/CD проекта. Там появится зарегистрированный раннер проекта, готовый к работе.
Шаг 4: Использование Container Registry для сохранения образа приложения
У gitlab есть интегрированный реестр докер-контейнеров. Так, у проекта появляется собственное пространство для хранения докер-образов, которые получили на этапе сборки. Перед использованием реестра контейнеров проверьте, что эта функция включена для вашего проекта. Для это откройте вкладку Visibility, project features, permissions в общих настройках проекта и сделаете чекбокс активным.
Чтобы сохранять и отправлять изображения, нужно пройти аутентификацию в реестре контейнеров. Для аутентификации нужно использовать один из представленных типов:
— Личный токен доступа.
— Токен доступа для деплоя.
В примере использовали личный токен доступа. Перейдём в настройки профиля, во вкладку Access token, где нужно выбрать Add new token.
Для всех типов токенов требуется минимальные правила:
read_registry — доступ на чтение (pull).
write_registry — доступ на запись (push).
Сохраните в буфер обмена получившийся токен и вставьте его в Docker команду для аутентификации в реестре контейнеров, где:
—
—
Команда выполняется на сервере, где ранее установили Docker, чтобы там взаимодействовать с реестром контейнера
docker login registry.example.com -u -p
Шаг 5: Настройка SSH-ключа
SSH-ключ используется GitLab CI/CD для входа на сервер и выполнения процедуры развертывания. Сгенерируем 4096-разрядный SSH-ключ алгоритмом RSA (пара из открытого и закрытого ключей).
Флаг -C добавляет комментарий для идентификации ключа. В качестве комментария можно указать, например, имя пользователя. подтвердите оба вопроса с помощью Enter.
ssh-keygen -t rsa -b 4096 -C
Чтобы авторизовать публичную часть SSH-ключа, осуществляющего развертывание, добавим её к authorized_keys файлу.
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Затем сохраним приватный ключ в GitLab как CI/CD переменную, чтобы сделать его доступным в процессе работы раннера. Для этого выведем содержимое приватного ключа.
cat ~/.ssh/id_rsa
Копируем содержимое ключа в буфер обмена, переходим в настройки CI/CD проекта во вкладку Variable и нажимаем Add variable.
Шаг 6: Определяем оставшиеся переменные окружения CI/CD
Добавим оставшиеся переменные для развертывания приложения на сервере:
SERVER_USER — имя пользователя для подключения к удаленному серверу через SSH. Можете использовать действующего пользователя или создать отдельного в системе.
SERVER_HOST — IP-адрес удаленного сервера для подключения через SSH. Для переменной сделать активной опцию Mask variableÂÂÂÂ
ENV_FILE — путь к файлу с переменными окружения, который будет использован при выполнении команд Docker Compose. Для этого поля поменяете тип с variable на file. В поле для ввода переменные указываются через знак равенства с новой строки.
Таким образом в списке должны отображаться четыре переменные окружения.
На этом все подготовка закончилась. Переходим к настройке конфига .gitlab-ci.yml.
Настройка конфига .gitlab-ci.yml
Файл .gitlab-ci.yml располагается в корне репозитория и определяет структуру пайплайна и логику его работы. Gitlab при каждом поддерживаемом событии (например, push-изменений или создание merge request разработчиком) ищет его и проверяет, есть ли в нем описание для обработки наступившего события.
Ниже — файл .gitlab-ci.yml для сборки и развертывания Spring Boot-приложения в docker-контейнере.ÂÂÂÂ
stages:
- build
- deploy
build-only-MR:
stage: build
tags:
- docker
image:
name: gcr.io/kaniko-project/executor:v1.9.2-debug
entrypoint: [ "" ]
script:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--no-push
only:
- merge_requests
build:
stage: build
tags:
- docker
image:
name: gcr.io/kaniko-project/executor:v1.9.2-debug
entrypoint: [ "" ]
script:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}:latest"
only:
- main
deploy:
stage: deploy
image: docker:20.10-git
tags:
- gitlab-org-docker
variables:
DOCKER_HOST: "ssh://${SERVER_USER}@${SERVER_HOST}"
before_script:
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- eval $(ssh-agent -s)
- echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add -
- '[[ -f /.dockerenv || -d /run/secrets/kubernetes.io/serviceaccount ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker compose --env-file $ENV_FILE pull
- docker compose --env-file $ENV_FILE down --timeout=60 --remove-orphans
- docker compose --env-file $ENV_FILE up --build --detach
- docker image prune -f || true
only:
- main
when: manual
Пайплайн состоит из двух этапов: сборка и развертывание.
Для этапа сборки написаны две задачи: build-only-MR и build. Обе выполняются на gitlab-runner с тегом Docker, который ранее мы зарегистрировали.
Первая — для сборки проекта только при создании merge request-а. При этом получившийся Docker-образ не сохраняется в реестре контейнеров GitLab.ÂÂÂÂ
Вторая задача для сборки проекта при вливании кода в ветку main. Получившийся Docker-образ пушится в реестр контейнеров GitLab с тегом latest.ÂÂÂÂ
Для сборки Docker-образов из Dockerfile в директории проекта используется образ Kaniko. Это мощный инструмент для сборки образов Docker, который не требует наличия Docker-демона. Например, внутри своего контейнера или кластера Kubernetes. Использование Kaniko считается более быстрым и безопасным подходом, чем Docker-in-Docker.
Этап развертывания включает в себя одну задачу, которая выполняется на общем раннере с тэгом gitlab-org-docker. Это один из Shared runner, которые предоставляет облачная версия gitlab.com.ÂÂÂÂ
Задача использует стандартный Docker-образ версии 20.10-git. В переменных задан путь для подключения к Docker на удаленном сервере через SSH. Переменные окружения SERVER_USER и SERVER_HOST определили ранее, как переменные CI/CD.
В блоке before_script выполняется настройка SSH для безопасного взаимодействия со стендом: создание директории, установка прав доступа для хранения SSH-ключа, инициализация SSH-агента, к которому добавляется приватный ключ из переменной окружения. После чего производится настройка параметров SSH. Затем авторизация в реестре контейнеров с использованием логина и пароля, хранящихся в переменных CI_REGISTRY_USER и CI_REGISTRY_PASSWORD — для получения доступа к собранным Docker-образам.
В блоке scripts подтягиваются обновления для образов с реестра. Затем останавливаются и удаляются текущие контейнеры — начинается запуск контейнеров в фоновом режиме с новыми скачанными образами из реестра. Крайняя команда удаляет все неиспользуемые образы.
Эта задача также выполняется только при вливании кода в ветку main и требует ручного подтверждения для запуска (опция when: manual).
Разворачивать будем REST-приложение на Java. Напишем контроллер, в котором будет один GET-запрос для теста, что приложение развернуто на удаленном сервере, и мы можем к нему обратиться.
Ниже — ключевые файлы, которые мы написали.ÂÂÂÂ
Тестовый GET-запрос:
@CrossOrigin
@RequestMapping("/test")
@RestController
public
class TestController {
@GetMapping("/hello")
public ResponseEntity getTest() {
return ResponseEntity.ok("Hello world");
}
}
Dockerfile
FROM maven:3.8-openjdk-17-slim
RUN mkdir -p /home/app
WORKDIR /home/app
ADD pom.xml /home/app
ADD src /home/app/src
RUN mvn clean package
CMD ["java", "-jar", "/home/app/target/test-0.0.1-SNAPSHOT.jar"]
docker-compose.yml
version: '3.9'
services:
core:
container_name: spring-application
image: registry.gitlab.com/my-test-project6/test-cicd-project:latest
environment:
TEST_SERVICE_PORT: ${TEST_SERVICE_PORT}
OPEN_API_TITLE: ${OPEN_API_TITLE}
ports:
- "8081:${TEST_SERVICE_PORT}"
logging:
driver: 'json-file'
options:
max-size: '100m'
max-file: '3'
Такой момент: мы используем переменные TEST_SERVICE_PORT - порт, на котором будет запущено приложение в Docker-контейнере и OPEN_API_TITLE — заголовок swagger-а. Прописав переменные в docker-compose-файле, мы указали нашему Java-приложению, что ее можно использовать как значение переменной в конфигурационном файле application.yml.
application.yml
server:
port: ${TEST_SERVICE_PORT}
servlet:
context-path: /api
api:
title: ${OPEN_API_TITLE}
springdoc:
api-docs:
path: /doc/api-docs
swagger-ui:
path: /doc/swagger-ui.html
Когда изменения кода зальются в main-ветку, начнется выполнение задачи build. Как только сборка успешно завершилась, можно деплоить на прод, нажав на значок запуска.
Через пару минут увидим, что приложение успешно прошло сборку и развертывание в Docker-контейнере на удаленном сервере.
Приложение доступно на порту 8081. Мы можем обратиться по API /api/test/hello и увидеть заветную надпись «Hello world». Готово!
Краткие выводы
CI/CD — важная практика разработки программного обеспечения для автоматизации процесса интеграции, тестирования и развертывания кода. Благодаря CI/CD команды разработчиков могут улучшать качество ПО и доставлять новые функции эффективнее и в более короткие сроки.
Приятных «разворачиваний»! Не бойтесь сложностей — это только начало!
Источник: https://habr.com/ru/articles/764568/
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-11-26 » Капитан грузового судна, или Как начать использовать Docker в своих проектах
- 2024-11-26 » Обеспечение безопасности ваших веб-приложений с помощью PHP OOP и PDO
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-15 » Перенос сайта на WordPress с одного домена на другой
- 2024-11-08 » OSPanel 6: быстрый старт
- 2024-11-08 » Как установить PhpMyAdmin в Open Server Panel
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
- 2024-08-01 » WebSocket
- 2024-07-26 » Интеграция с Яндекс Еда
- 2024-07-26 » Интеграция с Эквайринг
- 2024-07-26 » Интеграция с СДЕК
- 2024-07-26 » Интеграция с Битрикс-24
- 2024-07-26 » Интеграция с Travelline
- 2024-07-26 » Интеграция с Iiko
- 2024-07-26 » Интеграция с Delivery Club
- 2024-07-26 » Интеграция с CRM
- 2024-07-26 » Интеграция с 1C-Бухгалтерия
- 2024-07-24 » Что такое сторителлинг: техники и примеры
- 2024-07-17 » Ошибка 404: что это такое и как ее использовать для бизнеса
- 2024-07-03 » Размещайте прайс-листы на FarPost.ru и продавайте товары быстро и выгодно
- 2024-07-01 » Профилирование кода в PHP
- 2024-06-28 » Изучаем ABC/XYZ-анализ: что это такое и какие решения с помощью него принимают
- 2024-06-17 » Зачем вам знать потребности клиента
- 2024-06-11 » Что нового в работе Яндекс Метрики: полный обзор обновления
- 2024-06-11 » Поведенческие факторы ранжирования в Яндексе
- 2024-06-11 » Скорость загрузки сайта: почему это важно и как влияет на ранжирование
Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей Индийская пословица |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.