Непрерывная интеграция/внедрение приложения symfony с помощью docker-compose и gitlab ci

Введение и знакомство с проектом

В качестве «подопытного кролика» мы будем использовать чуть модифицированный шаблонный проект, созданный утилитой create-react-app.

! Теперь давайте клонируем репозиторий с кодом с которым мы будем работать.

! Перейдите в каталог локального репозитория

Должна отобразиться стандартная стартовая страница create-react-app.

! Установите npm пакеты локально, выполнив

! Попробуйте «собрать» проект

Обратите внимание, что в папке появились соответствующие файлы, включая минифицированный JavaScript и CSS. ! Затем запустите тесты

! Затем запустите тесты

! Осталось осуществить «развёртывание», но чтобы не засорять туториал инструкциями по установке веб-сервера, давайте просто запустим отладочный веб-сервер чтобы увидеть как выглядит наше веб приложение выглядит в браузере.

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

  • централизованный репозиторий с
    • управлением полномочиями членов команды;
    • code review;
  • багтрекер чтобы
    • планировать работу и
    • отслеживать прогресс;
  • среду сборки с
    • автоматическим запуском конвейера непрерывной поставки в нужные моменты;
    • визуализацией статуса сборки;
    • хранением артефактов;
    • автоматическим оповещением о ключевых событиях;
    • автоматическим развёртыванием в разные среды;
  • сбор метрик непрерывной доставки.

Всё это, а также многое другое, поддерживается GitLab. Платная версия предлагает больше возможностей, но для наших целей нам хватит и бесплатной версии доступной на GitLab.com.

Дополнительно

Про CPU

Чтобы ограничить контейнер любыми 2 процессорами:

Данная команда сработает на лету, чтобы в этом убедится посмотрим применилось ли наше ограничение

На определенных ядрах процессора, скажем, на втором и четвертом команда примет вид:

Более сложные закрепление с помощью диапазонов:

Чтобы ограничить процессорное время контейнера до 10% от общего числа, набираем вот такую команду:

Про память

Что бы ограничить выделяемую контейнеру память, необходимо набрать следующую команду:

Смотрим инфо про память:

Для отключения файла подкачки swap

Если вы хотите монтировать директорий с привилегиями пользователя хост машины, то на эту тему написана статья вот ссылка

Шаг 2 — Установка GitLab

Настроив зависимости, мы можем приступить к установке GitLab. Это простой процесс, использующий сценарий установки для настройки хранилищ GitLab в системе.

Перейдите в каталог  и загрузите установочный скрипт:

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

Когда вы будете довольны безопасностью скрипта, запустите программу установки:

Скрипт настроит ваш сервер для использования хранилищ, обслуживаемых GitLab. Это позволит вам управлять GitLab с помощью тех же средств управления пакетами, которые вы используете для других системных пакетов. Завершив эту задачу, вы можете начать установку приложения GitLab с помощью :

При этом в системе будут установлены необходимые компоненты.

Ручной импорт образа¶

Если у вас уже есть lxd-совместимый файл образа, вы можете импортировать его:

lxc image import \<file\> --alias my-alias

И запустить контейнер:

lxc launch my-alias my-container

Смотрите спецификации образов для подробной информации.

Создание и использование вашего первого контейнера

Предполагая, что вы импортировали образ Ubuntu cloud из источника «ubuntu», можете создать контейнер:

lxc launch ubuntu first

Это создаст и запустит новый контейнер ubuntu, что подтвердит:

lxc list

Ваш контейнер здесь называется «first». Вы можете предоставить LXD выбрать случайное имя
просто вызвав «lxc launch ubuntu» без имени.

Сейчас ваш контейнер запущен, вы можете получить интерактивный доступ внутрь:

lxc exec first -- /bin/bash

Или вызвать команду напрямую:

lxc exec first -- apt-get update

Для скачивания файла из контейнера, используйте:

lxc file pull first/etc/hosts .

Для загрузки:

lxc file push hosts first/tmp/

Для остановки, просто сделайте:

lxc stop first

И для полного удаления:

lxc delete first

Множество хостов

Утилита командной строки «lxc» может связываться со множеством серверов LXD.
По умолчанию она связана с локальным по локальному UNIX socket.

Удаленные операции требуют запуска двух команд на удаленном сервере:

lxc config set core.https_address ""
lxc config set core.trust_password some-password

Первая указывает LXD слушать все адреса на порту 8443.
Вторая устанавливает надежный пароль для связи с сервером.

Теперь для связи с удаленным LXD, вы можете просто добавить его:

lxc remote add host-a <ip address or DNS>

Это попросит вас подтвердить отпечаток удаленного сервера а затем спросит пароль.

И после этого, используйте те же команды, что и раньше, но предваряя из именами контейнера
и образа:

lxc exec host-a:first -- apt-get update

Работа в команде, часть 2

Опять. Это опять произошло. Стоило вам только запушить свою feature-ветку для превью, как спустя минуту Патрик сделал то же самое и тем самым перезаписал содержимое staging. #$@! Третий раз за сегодня!

Идея! Используем Slack для оповещений о развертываниях, чтобы никто не пушил новые изменения, пока старые не закончили развертываться.

Оповещения Slack

Настроить оповещения Slack несложно. Надо лишь взять из Slack URL входящего вебхука…

… и передать его в Settings > Services > Slack вместе с вашим логином Slack:

Поскольку вы хотите получать уведомления только о развертываниях, в показанных выше настройках можно убрать галочки на всех пунктах, кроме “Build”. Вот и все, теперь вы будете получать оповещения о каждом развертывании:

Шаг 1 — Установка зависимостей

Прежде чем выполнять установку GitLab, важно установить программное обеспечение, используемое при установке и на постоянной основе. К счастью, все требуемое программное обеспечение можно легко установить из заданных по умолчанию хранилищ пакетов Ubuntu

Поскольку мы впервые используем  в этом сеансе, мы можем обновить индекс локального пакета и установить зависимости с помощью следующей команды:

Вероятно, некоторые элементы этого программного обеспечения у вас уже установлены. Для установки  выберите вариант Internet Site в диалоговом окне. На следующем экране введите доменное имя вашего сервера, чтобы настроить отправку почты в системе.

Selecting the executor

The executors support different platforms and methodologies for building a
project. The table below shows the key facts for each executor which will help
you decide which executor to use.

Executor SSH Shell VirtualBox Parallels Docker Kubernetes Custom
Clean build environment for every build conditional (4)
Reuse previous clone if it exists conditional (4)
Runner file system access protected (5) conditional
Migrate runner machine partial partial
Zero-configuration support for concurrent builds ✗ (1) conditional (4)
Complicated build environments ✗ (2) ✓ (3) ✓ (3)
Debugging build problems easy easy hard hard medium medium medium
  1. It’s possible, but in most cases it is problematic if the build uses services
    installed on the build machine
  2. It requires to install all dependencies by hand
  3. For example using Vagrant
  4. Dependent on what kind of environment you are provisioning. It can be
    completely isolated or shared between each build.
  5. When a runner’s file system access is not protected, jobs can access the entire
    system including the runner’s token, and the cache and code of other jobs.
    Executors marked ✓ don’t allow the runner to access the file system by default.
    However, security flaws or certain configurations could allow jobs
    to break out of their container and access the file system hosting runner.

Shell executor

Shell is the simplest executor to configure. All required dependencies for
your builds need to be installed manually on the same machine that GitLab Runner is
installed on.

Virtual Machine executor (VirtualBox / Parallels)

This type of executor allows you to use an already created virtual machine, which
is cloned and used to run your build. We offer two full system virtualization
options: VirtualBox and Parallels. They can prove useful if you want to run
your builds on different operating systems, since it allows the creation of virtual
machines on Windows, Linux, macOS or FreeBSD, then GitLab Runner connects to the
virtual machine and runs the build on it. Its usage can also be useful for reducing
infrastructure costs.

Docker executor

A great option is to use Docker as it allows a clean build environment,
with easy dependency management (all dependencies for building the project can
be put in the Docker image). The Docker executor allows you to easily create
a build environment with dependent services,
like MySQL.

Docker Machine executor

The Docker Machine is a special version of the Docker executor
with support for auto-scaling. It works like the normal Docker executor
but with build hosts created on demand by Docker Machine.

Kubernetes executor

The Kubernetes executor allows you to use an existing Kubernetes cluster
for your builds. The executor will call the Kubernetes cluster API
and create a new Pod (with a build container and services containers) for
each GitLab CI job.

SSH executor

The SSH executor is added for completeness, but it’s the least supported
among all executors. It makes GitLab Runner connect to an external server
and runs the builds there. We have some success stories from organizations using
this executor, but usually we recommend using one of the other types.

Custom executor

The Custom executor allows you to specify your own execution
environments. When GitLab Runner does not provide an executor (for
example, LXC containers), you are able to provide your own
executables to GitLab Runner to provision and clean up any environment
you want to use.

Установка lxc-desktop

Установим систему в контейнер. Для установки выполните команду:

lxc-create -t download -n pc100 — —server mirror.calculate-linux.org —no-validate -d CCDX —arch x86_64

(потребуется ввести номер версии дистрибутива),

где pc100 — имя контейнера, участвующее в дальнейших настройках и используемое в качестве сетевого имени.

Настройка контейнера

Добавьте настройки сети для контейнера и права на запись в , дописав в конец файла:

/var/calculate/lxc/pc100/config

# Network configuration
lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.name = eth0
lxc.net.0.link = br0
lxc.net.0.hwaddr = 02:03:04:05:06:07

lxc.mount.auto = cgroup:mixed proc:mixed sys:rw
lxc.environment = LXC_DESKTOP=1

Измените MAC-адрес 02:03:04:05:06:07 на любой другой

Обратите внимание, что первое число должно быть чётным

Настройки системы в контейнере

Запустите контейнер:

lxc-start -n pc100

После запуска откроется графическое приглашение к вводу пароля. Во время первой загрузки будет создан пользователь с паролем «guest». Вернитесь в консоль при помощи комбинации клавиш .

Выполните базовые настройки: пароль root, запуск демона ssh, локализация системы. Теперь перезапустите контейнер:

lxc-attach -n pc100 passwd

lxc-attach -n pc100 — cl-setup-locale -l ru_RU —timezone Europe/Moscow

lxc-stop -r -n pc100

Используйте свои значения локализации ru_RU и временной зоны Europe/Moscow.

Добавление контейнера в автозагрузку

ln -sf /etc/init.d/lxc /etc/init.d/lxc.pc100

rc-update add lxc.pc100

Для того, чтобы система в контейнере стартовала после поднятия сети, создайте файл:

/etc/conf.d/lxc

rc_want="net.br0"

Первое автоматическое развертывание

При работе с GitLab используются все те же команды, что и при работе на локальном терминале. Вы можете настроить GitLab CI в соответствии с вашими требованиями так же, как вы настраиваете ваш локальный терминал. Все команды, которые можно выполнить на вашем компьютере, можно выполнить и в GitLab, передав их в CI. Просто добавьте ваш скрипт в файл и сделайте пуш — вот и все, CI запускает задачу (job) и выполняет ваши команды.

Добавим деталей в нашу историю: ваш веб-сайт небольшой — 20-30 посетителей в день, а в репозитории есть только одна ветка — .

Начнем с того, что добавим задачу с командой aws в :

Неудача:

Нам нужно удостовериться в наличии исполняемого файла . Для установки требуется — инструмент для установки пакетов Python. Укажем образ Docker с предустановленным Python, в котором также должен содержаться :

При пуше на GitLab код автоматически развертывается с помощью CI

Установка увеличивает время выполнения задачи, но сейчас нас это не особенно волнует. Если вы все же хотите ускорить процесс, можете поискать образ Docker с предустановленным , или же создать такой своими силами.

Также, не стоит забывать о переменных окружения, полученных из AWS Console:

Должно сработать, однако держать секретные ключи в открытом виде (даже в приватном репозитории) — не самая лучшая идея. Посмотрим, что с этим можно сделать.

Сохранение секретов

В GitLab есть специальный раздел для секретных переменных: Settings > Variables

Все данные, помещенные в этот раздел станут переменными окружения. Доступ к этому разделу есть только у администратора проекта.

Раздел можно удалить из настроек CI, но лучше давайте воспользуемся им для другой цели.

Создание и использование публичных переменных

С увеличением размера файла конфигурации становится удобнее хранить некоторые параметры в его начале в качестве переменных. Такой подход особенно актуален в случае, когда эти параметры используются в нескольких местах. Хоть в нашем случае до такого пока что не дошло, в демонстрационных целях создадим переменную для названия бакета S3:

Сборка успешна:

Тем временем посещаемость вашего сайта повысилась, и вы наняли разработчика, чтобы он вам помогал. Теперь у вас есть команда. Посмотрим как работа в команде влияет на рабочий процесс.

Преимущества контейнеров

Существует ряд преимуществ использования контейнеров:

  • Портативность
  • Эффективность
  • Изоляция
  • Лёгкость
  • Неизменность (Immutability)

Портативность

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

Также портативность состоит в том, что после того, как Docker образ собран и он работает правильно, он будет работать где угодно, если там работает Docker т.е. на серверах Windows, Linux и MacOS.

Эффективность

При работе с приложениями виртуальных машин действительно ли нужны процессы ОС, системные программы и т.п.? Как правило нет, интересен только процесс вашего приложения. Контейнеры обеспечивают именно это: в контейнере запускаются только те процессы, которые явно нужны, и ничего более. Поскольку контейнеры не требуют отдельной операционной системы, они используют меньше ресурсов. Виртуальная машина часто занимает несколько гигабайт, контейнер же может быть размером всего в несколько мегабайт, что позволяет запускать гораздо больше контейнеров, чем виртуальных машин на одном сервере.

Поскольку контейнеры имеют более высокий уровень утилизации серверов, требуется меньше аппаратного обеспечения, что приводит к сокращению затрат.

Изоляция

Контейнеры изолируют приложение от всех остальных процессов, и, хотя несколько контейнеров могут работать на одном сервере, они могут быть полностью независимы друг от друга. Любое взаимодействие между контейнерами должно быть явно объявлено. Если один контейнер выходит из строя, он не влияет на другие контейнеры и может быть быстро перезапущен. Безопасность также повышается благодаря такой изоляции. Например, использование уязвимости веб-сервера на хосте может дать злоумышленнику доступ ко всему серверу, но в случае контейнера злоумышленник получит доступ только к контейнеру веб-сервера.

Лёгкость

Поскольку для контейнеров не требуется отдельная ОС, их можно запустить, остановить или перезагрузить в считанные секунды, что ускорит все связанные процессы, в том числе и процессы Continuous Integration. Вы можете начать разрабатывать быстрее и не тратить время на настройку окружения.

Неизменность (Immutability)

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

Тесная интеграция с GitLab

GitLab Container Registry полностью интегрирован в GitLab, что позволяет разработчикам с легкостью создавать, тестировать и запускать образы Docker, используя GitLab CI или другие инструменты, совместимые с Docker.

  • Для аутентификации и разграничения доступа используются пользователи и группы из вашего инстанса GitLab.
  • Нет необходимости создавать дополнительные репозитории для работы с реестром – реестр является частью вашего проекта в GitLab.
  • В проекте появляется новая вкладка Container Registry, в которой перечислены все образы, относящиеся к данному проекту.
  • У каждого проекта может быть собственный реестр образов (опционально, может быть отключено для любого отдельного проекта).
  • Можно легко скачивать и загружать образы на GitLab CI.
  • Не нужно скачивать и устанавливать дополнительный софт.

Обновление до версии 4.0

Начиная с LXC 4.0 вместо отдельных конфигурационных файлов для различных типов контейнеров, используется единый файл настроек . При обновлении с предыдущих версий, необходимо внести изменения в настройки уже подготовленных контейнеров. Исправьте путь до общего конфигурационного файла:

/var/calculate/lxc/calculate/config

#lxc.include = /usr/share/lxc/config/gentoo.common.conf
lxc.include = /usr/share/lxc/config/common.conf

Для работы программ, использующих путь (например PostgreSQL), добавьте в конфигурационный файл контейнера монтирование tmpfs по этому пути:

/var/calculate/lxc/calculate/config

lxc.mount.entry = none dev/shm tmpfs rw,nosuid,nodev,create=dir

Установка GitLab

Будем устанавливать GitLab на нашем собственном сервере. Впрочем можно пользоваться GitLab.com. Существует много способов установки GitLab: из исходников, из пакета, в контейнере. Выберите тот способ который вам нравится и следуйте инструкции по установке.

Требования:

  • Отдельный сервер — GitLab достаточно ресурсоёмкое веб-приложение, поэтому лучше держать его на отдельном сервере (4 Gb RAM, 2 CPU).
  • ОС Linux.
  • (Опционально но рекомендуется) Домен — необходим для обеспечения безопасности и запуска pages.

Конфигурация

Прежде всего настройте почтовые уведомления.

Далее, рекомендую установить Pages. Как было сказано выше, артефакты от выполнения скриптов могут быть загружены на GitLab. Пользователи могут загрузить их, но часто бывает полезно открыть их напрямую в браузере и для этого нужно установить pages.

Зачем нужны pages:

  • Для вики или набора статичных страниц связанных с проектом.
  • Для просмотра html артефактов.
  • .

Так как в HTML может быть добавлено автоматическое перенаправление при загрузке страницы, то можно направлять пользователя на страницу с результатами юнит-тестов.

Кстати, я столкнулся с багом при использовании pages (Ошибка 502 при просмотре артефактов) — вот решение.

Подключение окружений к GitLab

Для запуска CD скриптов необходимы окружения — настроенные серверы для запуска вашего приложения. Для начала предположим, что у вас установлен Linux-сервер с платформой InterSystems (скажем, InterSystems IRIS, но всё будет работать с Caché или Ensemble). Для соединения окружения с GitLab нужно:

  1. Установить GitLab runner.
  2. Зарегистрировать GitLab runner в GitLab.
  3. Разрешить пользователю вызывать InterSystems IRIS.

Важное замечание по установке GitLab runner — НЕ клонируйте сервер после установки GitLab runner. Результаты непредсказуемы и нежелательны.
Расскажу поподробнее о шагах 2 и 3

Зарегистрировать GitLab runner в GitLab.

После запуска команды:

Будет предложено несколько опций на выбор, и хотя большинство шагов довольно просто, некоторые из них стоит прокомментировать:

Доступно несколько токенов: для всей системы (доступен в настройках администрирования) либо для одного проекта (доступен в настройках проекта).
Когда вы подключаете runner для CD конкретного проекта, нужно указать токен именно этого проекта.

В CD конфигурации можно фильтровать, какие скрипты выполняются окружениях с определёнными тегами. Поэтому в самом простом случае укажите один тег, который будет названием окружения.

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

Разрешить пользователю вызывать InterSystems IRIS.

После подключения к GitLab нужно разрешить юзеру вызывать InterSystems IRIS. Для этого:

  1. Пользователь должен иметь права для вызова либо . Для этого его нужно добавить в группу либо командой:
  2. В InterSystems IRIS создайте пользователя и предоставьте ему права для выполнения скриптов CD (запись в БД и т.д.)
  3. Включите ОС аутентификацию.

Вместо пунктов 2 и 3 можно использовать другие подходы, например передачу пользователя/пароля, но вариант с ОС аутентификацией представляется мне более предпочтительным.

Compatibility chart

Supported features by different executors:

Executor SSH Shell VirtualBox Parallels Docker Kubernetes Custom
Secure Variables
GitLab Runner Exec command
: image ✓ (via
: services
: cache
: artifacts
Passing artifacts between stages
Use GitLab Container Registry private images n/a n/a n/a n/a n/a
Interactive Web terminal ✓ (UNIX) ✓ (1)
  1. Interactive web terminals are not yet supported by
    Helm chart,
    but support is planned.

Supported systems by different shells:

Shells Bash PowerShell Desktop PowerShell Core Windows Batch (deprecated)
Windows ✗ (4) ✓ (3) ✓ (2)
Linux ✓ (1)
macOS ✓ (1)
FreeBSD ✓ (1)
  1. Default shell.
  2. Deprecated. Default shell if no

    is specified.

  3. Default shell when a new runner is registered.
  4. Bash shell is currently not working on Windows out of the box due to
    this issue but is intended
    to be supported again soon. See the issue for a workaround.

Supported systems for interactive web terminals by different shells:

Shells Bash PowerShell Desktop PowerShell Core Windows Batch (deprecated)
Windows
Linux
macOS
FreeBSD

Создание сервисов на основе контейнеров Docker

docker-composedocker-compose.yml

  • блок services включает в себя описание всех создаваемых сервисов;
  • в каждом сервисе есть раздел image, который определяет используемый образ для создания контейнеров на его основе. Подобный формат записи позволяет получать образы с хранилища, доступного по адресу gitlab.example.ru:4567. Последний аргумент ${CI_COMMIT_SHA} — переменная окружения, связанная с значением хеша текущего коммита, которую мы используем для различия сборок друг от друга в данном руководстве;
  • блок deploy используется только при использовании команды docker stack deploy. Мы используем три ключевых слова внутри данного блока:
    • replicas — количество копий контейнера;
    • placement — расположение контейнеров относительно рабочих нодов;
    • restart_policy — условия перезапуска контейнеров;
  • открытие портов для общения между сервисами и внешней средой осуществляется в разделе ports;
  • для выполнения дополнительных команд при старте сервиса используется блок command.

docker-composeNginx

Nginxbuild GitLab CI

example.ru

DOCKER_HOSTURLRegistry$CI_COMMIT_SHARedislatest

  • вначале файла указывается блок image, который определяет на основе какого образа будет осуществляться сборка проекта;
  • в блоке services мы дополнительно подключаем образ с настроенным Docker, для запуска контейнеров Docker внутри Docker;
  • раздел before_script содержит команды, выполняемые перед запуском каждой стадии сборки проекта;
  • блок stages перечисляет в каком порядке будут исполняться различные стадии выполнения работ;
  • выполнение каждого раздела происходит в именованном блоке, например, unittests, который в свою очередь состоит из нескольких разделов:
    • поле stage указывает в какой стадии выполняется блок;
    • поле variables может содержать дополнительные переменные окружения, необходимые для выполнения операций;
    • поле script содержит список команд, которые будут выполнены в этом блоке;
    • поле tags определяет на каких GitLab Runners может выполняться даный блок.

Тонкая настройка iptables

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

Готовый листинг , решающий две задачи сразу, представлен ниже:

Создание бэкапов

Данный метод создает бэкапы контейнеров как LXD образы, готовые к импорту. В идеале нужно создавать снимки и отправлять их в приватный репозиторий LXD. Но иногда, этого сделать нельзя. Например, у небольшой компании нет возможности покупать еще один сервер. В этом случае можно обойтись простым решением tar + Amazon S3.

Скачайте готовые скрипты для создания и восстановления бэкапов:

Установите флаг выполнения для скриптов:

Перед созданием и восстановлением бэкапов нужно остановить работающий контейнер. Можно, в принципе, делать бэкап на работающем контейнере, но при создании бэкапа возможна потеря некоторых данных (зависит от установленных программ в контейнере).

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Техноарена
Добавить комментарий

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