[Oracle, SQL, Администрирование баз данных, DevOps] Немного CI/CD магии: настраиваем доставку скриптов миграции базы данных с использованием GitLab и Liquibase

Автор Сообщение
news_bot ®

Стаж: 6 лет 2 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
21-Июн-2021 14:48

Главный разработчик и архитектор проектов ГК «ОТР» Дмитрий Копытов рассказал о практичном использовании CI/CD-подхода на примере доставки скриптов миграции базы данных Oracle 19. Для решения задачи он использовал GitLab Community Edition, GitLab Runner и Liquibase. Эксперт подробно описал технические аспекты настройки связи инструментов для проектов.Методология разработки CI/CD применяется уже на большинстве проектов. Она представляет собой автоматизацию тестирования и доставки новых проектов разрабатываемого проекта разработчикам, аналитикам, инженерам качества, конечным пользователям и другим заинтересованным сторонам. Метод обеспечивает оперативность вывода новой функциональности продукта и повышение качества разрабатываемого решения.В одном из проектов Дмитрий Копытов столкнулся с CI/CD и задачей настроить с нуля доставку скриптов миграции базы данных Oracle 19 в одной из проектов. Для этого он решил использовать стандартные инструменты — GitLab и Liquibase. Первый является известной средой управлениями репозиториями проекта с возможностью работы с CI/CD pipeline. А Liquibase — платформа с открытым кодом для наката миграции баз данных.Если говорить о конкретных возможностях, которые были применены для решения задачи, то использовались:
  • GitLab Commmunity Edition 13.x — как хранилище Git;
  • GitLab Runner — основной инструмент работы с CI/CD;
  • Liquibase — инструмент для описания скриптов наката и отказа БД с помощью chageset-файлов, состоящих из SQL команд или БД-независимых конструкций.
План действийПеред началом разработки необходимо составить план того, как будет работать будущий скрипт миграции. В теории когда разработчик делает коммит или мерж реквест, то запускается конвейер CI/CD — тот самый pipeline. Пайплайн включат в себя этапы, состоящие из джобов.В разрабатываемом скрипте будет одни этап — deploy. По сути, это просто применение скрипта наката. А количество джобов будет равняться количество стендов. Например, у нас есть дев и прод. Это два стенда и тогда джобов будет тоже два — deploy-dev и deploy-prod. Оба джоба будут обращаться к разным базам данных. Кроме того, deploy-dev будет выполняться автоматически при каждом мерж реквесте или коммите, а deploy-prod — вручную. Деплой на прод выполняется вручную, чтобы иметь возможность выбирать подходящее время. Оно, как правило, заранее согласованное. Например, мы деплоим прод вечером, чтобы не мешать пользователям работать.Оба джоба обрабатываются GitLab Runner. Это программа, которая занимается загрузкой исходников проектов и выполнением скриптов на сервере деплоя. Runner гибко настраивается с помощью переменных окружения, в которые могут быть вписаны адрес, логин и пароль для доступа к БД, название ветки, автор, текст коммита и так далее.Помните, что GitLab Runner сам обращается к хранилищу через http-протокол. Поэтому рабочая станция с запущенным Runner должна иметь доступ к GitLab. Иначе ничего работать не будет. Если deploy-dev и deploy-prod находятся на одной машине, то достаточно одного Runner. Но чаще всего прод размещают в другой сети. Поэтому настраиваем отдельный Runner для deploy-prod.Для разрабатываемого скрипта Runner будет вызывать через командную строку Liquibase. В параметрах вызова будет указана информация о целевой БД и используемом драйвере. Скрипты наката Liquibase сформирует автоматически из описаний миграций.Если всё пройдёт по плану, то пайплайн будет считаться завершённым и мерж реквест будет добавлен в ветку. В этом случае разработчик увидит такой статус:
Если скрипты отработали с ошибками, то пайплайн сообщит об ошибках:
В этом случае придётся изучать логи джоба, чтобы найти ошибку. Если проблема была в сетевом доступе, то достаточно перезапустить пайплайн.Настраиваем сервер деплояВ ГК «ОТР» используются виртуальные машины на основе Centos 7. Для деплоя необязательно создавать выделенный сервер, можно использовать существующий. Но для безопасности изолируем сервер от прочих ресурсов и создадим рабочую среду.Установка JavaДля работы с Liquibase рекомендуется использовать Java 11+. Процесс установки OpenJRE 11 на Centos 7 выглядит так:
sudo yum install java-11-openjdk
java --version
Установка LiquibaseФактически установка Liquibase не требуется, потому что это приложение на Java. Нужно лишь зайти на официальный сайт проекта и скачать архив. Далее распаковываем в удобную папку — в нашем случае /usr/share/liquibase/4.3.4. Создаём папку driver и копируем в неё нужный драйвер под используемую БД. Для нашей задачи это ojdc10.jar.Для проверки корректности установки выполняем простую команду:
cd /usr/share/liquibase/4.3.4
liquibase --version
Установка GitТут у внимательного читателя может возникнуть вопрос: «Зачем мы ставит отдельно Git, если он идёт зависимостью к GitLab Runner и будет установлен автоматически?». Всё верно, дорогой читатель, только по неизвестной причине сейчас GitLab Runner тянет за собой забагованную сборку Git 1.8, которая не позволяет использовать все преимущества CI/CD.На рабочей машине проверяем версию Git и, если она 1.8, устанавливаем более свежую:
# проверяем текущую версию гита
git --version
# удаляем гит, если он версии 1.8
sudo yum remove git*
# устанавливаем последнюю версию гита на момент написания статьи (2.30)
sudo yum -y install https://packages.endpoint.com/rhel/7/os/x86_64/endpoint-repo-1.7-1.x86_64.rpm
sudo yum install git
Установка GitLab RunnerДля установки GitLab Runner необходимо будет указать конкретный репозиторий:
# добавляем репу
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash
# устанавливаем
export GITLAB_RUNNER_DISABLE_SKEL=true; sudo -E yum install gitlab-runner
На этом наша рабочая среда собрана. Осталось перейти к её настройке.Настройка рабочей средыИзначально задумывалось, что GitLab Runner будет вызывать Liquibase для передачи скрипта миграции базы данных. Поэтому приступаем к настройке этих двух инструментов.Настройка GitLab RunnerПервоначально нужно дать GitLab Runner права на исполнение. Делается это простой командой:
# определяем место установки
which gitlab-runner # /usr/bin/gitlab-runner
# выдаём права на исполнение
sudo chmod +x /usr/bin/gitlab-runner
Если в процессе установке не был создан пользователь для GitLab Runner и не установлен демон, то делаем это следующими командами:
# создаём пользователя
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
# запускаем демона
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
Процесс работы с GitLab Runner очень напоминает systemctl. По крайней мере, команды для работы будут аналогичные:
sudo gitlab-runner status
# запуск сервиса
sudo gitlab-runner start
# останов сервиса
sudo gitlab-runner stop
# получения списка зарегистрированных раннеров
sudo gitlab-runner list
Получаем токен для проекта в GitLab. В интерфейсе хранилища находим раздел Setting, переходим на CI/CD и кликаем по Runners. Если ранее уже работали с GitLab Runners, то в списке будут отображены раннеры для группы проектов или конкретному проекту. У меня этот список выглядит так:
У каждого раннера также есть теги — синие метки. Для запуска GitLab Runners важно, чтобы теги раннера содержали теги джоба.Регистрируем раннер с помощью команды:
sudo gitlab-runner register
Далее выполняем пошаговую инструкцию:
Enter the GitLab instance URL
#Вводим адрес вашего GitLab
Enter the registration token
#Вводим токен
Enter a description for the runner
#Вводим имя раннера, например, dev-runner
Enter tags for the runner
#Вводим теги раннера через запятую. Пример: liquibase,dev
Enter an executor
#Вводим shell
Завершив регистрацию раннера, проверяем наличиеки через команду:
sudo gitlab-runner list
Кстати, проверить корректность и изменить некоторые параметры можно через Git, по уже знакомой схеме Settings ⇨ CI/CD ⇨ Runners.
Всё, на этом работа по настройке GitLab Runner закончена и можно приступать к следующему шагу.Настройка CI/CDИнструкции о том, что делать в процессе CI/CD хранится в файлах проекта. Для работы с CI/CD в GitLab используется главный файл .gitlab-ci.yml. Мы будем использовать дополнительные скрипты на bash, которые разместим в отдельной папке /ci.Перед настройкой .gitlab-ci.yml стоит познакомиться с примером, который можно найти по адресу https://gitlab.example.com/gitlab-org/my-project/-/ci/lint Он поможет понять, какая секция настроек за что отвечает.В нашем случае конфинг получил следующий вид:
variables:
LIQUIBASE_VERSION: "4.3.4"
stages:
- deploy
deploy-dev:
stage: deploy
tags:
- liquibase
- dev
script:
- 'bash ./ci/deploy-db.sh $DEV_DB $DEV_DB_USER $DEV_DB_PASS'
environment:
name: dev
only:
- dev
deploy-prod:
stage: deploy
tags:
- liquibase
- prod
script:
- 'bash ./ci/deploy-db.sh $DEV_DB $DEV_DB_USER $DEV_DB_PASS'
environment:
name: prod
when: manual
only:
- prod
Давайте разберём по порядку, что означает каждая секция.Секция variablesЭта секция используется для описания переменных окружения. С помощью LIQUIBASE_VERSION: "4.3.4" мы указали на версию Liquibase, которую планируем использовать. При установке новой версии Liquibase достаточно будет изменить в этой секции указание на версию, чтобы скрипт вновь заработал.
variables:
    LIQUIBASE_VERSION: "4.3.4"
Описать эту переменную можно и в самом проекте — это будет даже более правильным путём. Для этого в интерфейсе хранилища находим раздел Setting, переходим на CI/CD и кликаем по Variables. На проекте переменные могут выглядеть так:
Секция stageЗдесь мы указываем этапы деплоя. Как вы помните из начала статьи, он у нас один.
stages:
    - deploy
Секция jobsСекция обозначается названием джобов. В нашем случае это deploy-dev и deploy-prod. Как видите, они также разделены на блоки.
deploy-dev:
    stage: deploy
    tags:
        - liquibase
        - dev
    script:
        - 'bash ./ci/deploy-db.sh $DEV_DB $DEV_DB_USER $DEV_DB_PASS'
    environment:
        name: dev
    only:
        - dev
deploy-prod:
    stage: deploy
    tags:
        - liquibase
        - prod
    script:
        - 'bash ./ci/deploy-db.sh $DEV_DB $DEV_DB_USER $DEV_DB_PASS'
    environment:
        name: prod
    when: manual
    only:
        - prod
Блок stageУказывает на этап, к которому относится конкретный jobs.
stage: deploy
Блок tagsПеречисление тегов. Они указываются обычным массивом. Помните, что при создании раннера мы также указали теги? Здесь мы будем использовать аналогичные, чтобы GitLab Runners понимал, с каким джобом работает.Помните, что мы разделили раннеры для прода и дева. Если в деве тег dev, то у прода будет — prod.
tags:
        - liquibase
        - dev
Блок scriptУказываем список скриптов, которые будут выполняться раннером.
script:
        - 'bash ./ci/deploy-db.sh $DEV_DB $DEV_DB_USER $DEV_DB_PASS'
Блок environmentЗдесь указывается окружение. 
environment:
        name: dev
Окружение может быть настроено в разделе Operations при выборе пункта Environments. Это, по сути, дашборд стендов, где можно увидеть их статус, настроить переменные для окружения, вручную запустить деплой и так далее. Страница Environments может выглядеть так:
Блок whenЭто опциональный блок, которые указывают на необходимость запуск джоба в ручном режиме. Как видите, для deploy-dev он не используется, так как мы вначале определили, что здесь всё будет срабатывать автоматически. А для deploy-prod является обязательной опцией, чтобы запуск произошёл только в ручном режиме.
when: manual
Блок only/exceptБлок only указывает применение джоба к конкретным веткам. Если нужно исключить применение джоба к веткам, то используется блок except.
only:
        - dev
Скрипт вызова LiquibaseСкрипты для вызова Liquibase будем писать на bash. Переменные для скрипта будут передаваться автоматически с помощью ранее настроенных переменных окружения. Однако у нас два стенда с двумя разными базами данных. Оптимальный выход тут — передавать переменные непосредственно при вызове скрипта.Для выполнения задачи был создан такой скрипт ./ci/deploy-db.sh:
#!/bin/bash
echo "Environment: $CI_ENVIRONMENT_NAME"
cd db/changelog
/usr/share/liquibase/$LIQUIBASE_VERSION/liquibase \
--classpath=/usr/share/liquibase/$LIQUIBASE_VERSION/drivers/ojdbc10.jar \
--driver=oracle.jdbc.OracleDriver \
--changeLogFile=master.xml \
--contexts="$CI_ENVIRONMENT_NAME" \
--defaultSchemaName=STROY \
--url=jdbc:oracle:thin:@$1 \
--username=$2 \
--password=$3 \
--logLevel=info \
update
Разберём подробнее параметры вызова:
  • classpath — путь до драйвера;
  • driver — тип драйвера БД;
  • changeLogFile — путь к мастер-файлу чейнжлога;
  • contexts — контекст БД для фильтров чейнжсетов по контексту;
  • defaultSchemaName — имя схемы по умолчанию;
  • url — адрес БД. В скрипте он используется в виде переменной DEV_DB через $1;
  • username — логин пользователя в БД. В скрипте используется переменная DEV_DB_USER через $2;
  • password — пароль пользователя в БД. В скрипте используется переменная DEV_DB_PASS через $3.
При правильной настройке в логе пайплайна для Liquibase мы увидим следующее:
Работа с ошибочными мержамиДоработаем процесс CI/CD, отключив мержи, если процесс деплоя пойдёт с ошибками. Для запрета подобных мержей нужно в разделе General хранилища найти пункт Merge checks и установить соответствующую галочку. Но делать это нужно после настройки CI/CD.Искать галочку нужно здесь:
Что получилось?После всех настроек наш процесс работает следующим образом:1. Разработчик делает мерж реквест или коммит в ветку.2. Запускается пайплайн.3. Запускается ассоциированный с веткой джоб.4. С помощью джоба запускается раннер.5. Раннер скачивает исходники и вызывает с помощью скрипта Liquibase.6. Liquibase генерирует и исполняет скрипты наката или отката.Именно то, что нам нужно было изначально.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_oracle, #_sql, #_administrirovanie_baz_dannyh (Администрирование баз данных), #_devops, #_bash, #_liquibase, #_gitlab, #_cicd, #_gitlabrunner, #_avtomatizatsija (автоматизация), #_bazy_dannyh (базы данных), #_oracle, #_sql, #_administrirovanie_baz_dannyh (
Администрирование баз данных
)
, #_devops
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 25-Апр 21:15
Часовой пояс: UTC + 5