доставка кода на сервер
Что такое деплой?
Деплой — процесс «разворачивания» веб-сервиса, например, сайта, в рабочем окружении. Рабочее окружение — место, где сайт запускается и доступен для запросов. Это может быть как готовый хостинг, так и своя собственная серверная инфраструктура.
Деплоятся не только веб-сервисы, но любые сервисы, доступные по сети. Даже если эта сеть внутренняя и не доступна для запросов через интернет.
Как это происходит. Разработчики добавляют код в репозиторий. В какой-то момент они решают, что пора доставить его до продакшена. Это может происходить как по регулярному расписанию, например раз в две недели, так и просто по необходимости, вплоть до выкатки после каждого изменения. Во многом количество деплоев зависит от уровня его автоматизации — того, насколько процесс легкий в проведении и откате в случае проблем. На Хекслете деплои выполняются практически после каждого изменения, около 3 деплоев в день.
Каждый раз, когда разработчики решили что все, пора, они создают релиз. Под релизом обычно понимают тег в Git, который фиксирует, что уйдет в деплой. То есть изменения, добавленные в мастер после создания тега, не повлияют на сам тег, а значит мы точно уверены в том, что деплоим.
Для статических сайтов или отдельного фронтенда (только HTML, CSS и статические файлы) деплой сводится к обновлению кода на сервере. В ситуации деплоя бэкенда, как минимум, подключается база данных. В общем случае деплой может быть сложной процедурой, занимающей приличное время. В распределенных системах, состоящих из множества независимых веб-сервисов, вообще не бывает общего деплоя — каждая часть приложения деплоится (выкатывается) независимо.
Стоит сказать, что PaaS-платформы, такие как Heroku, берут деплой полностью на себя. Там достаточно выполнить коммит, и дальше все произойдет само. Цена за это — стоимость самой платформы
Шаги деплоя
Доставка кода на сервер
Возможны разные варианты доставки кода на сервер в зависимости от способа его упаковки. Иногда код просто копируют на сервер как набор файлов, но такое встречается редко, чаще он обновляется через Git. Раньше был популярен способ деплоя через стандартные пакетные менеджеры Linux-дистрибутивов. Сейчас он тоже встречается, и для определенных ситуаций подходит лучше всего.
Обновление базы данных
Новая версия приложения, как правило, требует изменений в базе данных. Для этого во время (или до) деплоя запускают миграции — специальные скрипты, содержащие правила обновления базы данных. Например sql-скрипты:
Запуск и остановка
Где-то в этом процессе происходит остановка старой версии и запуск новой. Если сначала остановить старую версию, а потом выполнить миграции и запустить новую, то мы получим простой (downtime) в работе сервиса. Так действительно работают многие, но это может быть болезненно для бизнеса и частых деплоев. Поэтому самые продвинутые проекты не останавливаются во время деплоя. О том, как это делать — ниже.
Автоматизация
Деплой нужно максимально автоматизировать, от этого зависит Time To Market, ключевая характеристика бизнес-ориентированных приложений. Чем быстрее и чаще мы доставляем изменения пользователю, тем лучше. Быстрее проверяем гипотезы, быстрее вносим исправления, быстрее оправдываем деньги, вложенные в разработку. Без автоматизации разработчики боятся выполнять деплой, он становится обузой, что приводит к снижению числа деплоев и регулярному стрессу для всей команды, с засиживанием на работе до позднего вечера.
Основных способа автоматизации три:
Но даже если автоматизация выполнена, все равно остается задача «запустить деплой». Запуск тоже автоматизируется. Существует целый подход, который называется Непрерывная доставка(continuous delivery). Его сложно внедрить и он не везде подходит, но если получилось, то про деплой забывают. Он выполняется полностью сам без участия людей. Главное в таком варианте — хороший мониторинг и система оповещения (алертинг) для реакции на ошибки.
Zero Downtime Deployment
Если не предпринимать специальных шагов, то каждый деплой будет приводить к остановке (возможно частичной) сервиса. В это время пользователи либо увидят ошибку, либо сообщение о происходящем обновлении. Но такого не происходит на большинстве крупных сервисов в интернете. Почему? Из-за реализации подхода «деплой без даунтайма» (downtime — простои в работе сервиса).
Zero Downtime Deployment выглядит так, как будто сервис никогда не останавливается, но при этом обновляется. Достигается это за счет одновременного запуска старой версии и новой кода. То есть когда деплоится приложение, то сначала поднимается новая версия рядом со старой. И только когда автоматика убеждается, что новая версия запустилась и работает, происходит остановка старой версии. Для выполнения этой процедуры понадобится следующее:
GitLab для Continuous Delivery проекта на технологиях InterSystems
В данной статье хотелось бы рассказать про организацию процессов Continuous Integration / Continuous Delivery, автоматизирующих сборку, тестирование и доставку приложений на платформах InterSystems.
Рассмотрим такие темы как:
Git 101
Несмотря на то, что основная тема это CD, Git, а точнее ряд фундаментальных принципов лежащих в его основе оказали большое влияние на процессы разработки программного обеспечения, поэтому начнём с краткого описания основных терминов Git.
Git — система контроля и управления версиями, в основе которой такие идеи, как:
Git не был первой системой контроля версий в которой данные идеи были реализованы, однако Git популяризовал данные идеи и существенно упростил их практическое применение.
Репозиторий (Repository)
Место, где хранятся и поддерживаются какие-либо данные.
Локальный репозиторий — репозиторий, расположенный на локальном компьютере
Удалённый репозиторий — репозиторий, находящийся на удалённом сервере
Коммит (Commit)
Зафиксированное состояние репозитория.
Хранит отличие (Diff) от какого-либо другого коммита который называется родительским.
Ветка (Branch)
Указатель на коммит.
Всегда можно посмотреть на его историю до первого коммита. Например, ветка master :
Дерево коммитов
Коммиты образуют деревья — графическое представление репозитория. Рассмотрим самый простой линейный вариант, когда к двум существующим коммитам с картинки выше добавили ещё три коммита:
Теперь пример дерева посложнее: два разработчика работают одновременно и, чтобы не мешать друг другу каждый из них работает в своей ветке. Это выглядит так:
После чего разработка продолжается:
Выводы — Git 101
Методологии разработки (Git flows)
Методология разработки на основе Git это серия подходов к разработке программного обеспечения использующих Git в качестве основы разработки. Существует множество методологий разработки, рассмотрим две из них:
GitHub flow
GitHub flow является, наверное, одной из самых простых методологий разработки на основе Git. Вот она:
Кроме того существует ряд правил:
Окружение это сконфигурированный ресурс где исполняется код вашего приложения. Это может быть сервер, виртуальная машина или даже контейнер.
Вот как это выглядит:
Подробно про GitHub flow на Хабре уже писали и не раз.
GitLab flow
Выглядит процесс разработки так:
Подробно про GitLab flow на Хабре тоже писали.
Выводы — Методологии разработки (Git flows)
Существует ряд методологий разработки основанных на Git — от простых до сложных. Выберите ту методологию которая с одной стороны не переусложнена, с другой обеспечивает надлежащий уровень контроля за состоянием вашего проекта.
GitLab Workflow
GitLab Workflow — методология разработки программного обеспечения, которая затрагивает не только этапы разработки но весь жизненный цикл продукта от идеи до отзывов пользователей. Вот как он выглядит:
Подробно каждый этап описан на сайте GitLab, я ограничусь описанием нескольких этапов.
Задачи и планирование
Начальные этапы GitLab Workflow сосредоточены на задаче — новой функциональности, ошибке или каком-либо другом отдельном объёме работ. Задача имеет несколько целей, таких как:
Этап планирования позволяет группировать задачи по их приоритету, этапу, статусу.
Разработку мы обсудили выше, следуйте любой методологии разработки git. После того, как мы разработали нашу новую функциональность и слили её в ветку master — что дальше?
Continuous Delivery (непрерывная доставка)
Непрерывная доставка — это подход к разработке программного обеспечения, в котором команды разрабатывают программное обеспечение в коротких спринтах, гарантируя, что новая версия приложения может быть выпущена в любое время. Данный подход автоматизирует сборку, тестирование и доставку программного обеспечения. Этот подход помогает снизить затраты и риски внесения изменений, позволяя получать быстрые инкрементные обновления для приложений в промышленной эксплуатации. Для непрерывной доставки важно настроить простой и воспроизводимый процесс доставки.
Непрерывная доставка в GitLab
В GitLab конфигурации непрерывной доставки определяется отдельно для каждого репозитория и хранится в файле конфигурации YAML в корне репозитория.
Скрипт
Определяет одно действие и какие условия должны выполняться для его запуска:
Окружение — это настроенный сервер или контейнер, в котором вы можете запускать скрипты.
Runner — служба, выполняет скрипты в определенном окружении. Подключен к GitLab и выполняют скрипты по мере необходимости.
Runner может быть развернут на сервере, в контейнере или даже на локальном компьютере разработчика.
Как происходит непрерывная доставка?
Вот пример запуска:
Он состоит из четырех этапов, выполняемых последовательно
Как мы видим, каждый скрипт выполнился успешно, если бы один из скриптов завершился неудачно, следующие скрипты не будут выполняться:
Если открыть скрипт, можно увидеть почему он закончился с ошибкой:
Ошибка компиляции стала причиной неудачного выполнения скрипта.
Перейдём от теории к практике.
Установка GitLab
Будем устанавливать GitLab на нашем собственном сервере. Впрочем можно пользоваться GitLab.com. Существует много способов установки GitLab: из исходников, из пакета, в контейнере. Выберите тот способ который вам нравится и следуйте инструкции по установке.
Конфигурация
Далее, рекомендую установить Pages. Как было сказано выше, артефакты от выполнения скриптов могут быть загружены на GitLab. Пользователи могут загрузить их, но часто бывает полезно открыть их напрямую в браузере и для этого нужно установить pages.
Так как в HTML может быть добавлено автоматическое перенаправление при загрузке страницы, то можно направлять пользователя на страницу с результатами юнит-тестов.
Кстати, я столкнулся с багом при использовании pages (Ошибка 502 при просмотре артефактов) — вот решение.
Подключение окружений к GitLab
Для запуска CD скриптов необходимы окружения — настроенные серверы для запуска вашего приложения. Для начала предположим, что у вас установлен Linux-сервер с платформой InterSystems (скажем, InterSystems IRIS, но всё будет работать с Caché или Ensemble). Для соединения окружения с GitLab нужно:
Важное замечание по установке GitLab runner — НЕ клонируйте сервер после установки GitLab runner. Результаты непредсказуемы и нежелательны.
Расскажу поподробнее о шагах 2 и 3.
Зарегистрировать GitLab runner в GitLab.
После запуска команды: sudo gitlab-runner register
Будет предложено несколько опций на выбор, и хотя большинство шагов довольно просто, некоторые из них стоит прокомментировать:
Доступно несколько токенов: для всей системы (доступен в настройках администрирования) либо для одного проекта (доступен в настройках проекта).
Когда вы подключаете runner для CD конкретного проекта, нужно указать токен именно этого проекта.
В CD конфигурации можно фильтровать, какие скрипты выполняются окружениях с определёнными тегами. Поэтому в самом простом случае укажите один тег, который будет названием окружения.
Вне зависимости от того используете ли вы docker, выбирайте shell для запуска скриптов.
Разрешить пользователю gitlab-runner вызывать InterSystems IRIS.
После подключения к GitLab нужно разрешить юзеру gitlab-runner вызывать InterSystems IRIS. Для этого:
Вместо пунктов 2 и 3 можно использовать другие подходы, например передачу пользователя/пароля, но вариант с ОС аутентификацией представляется мне более предпочтительным.
Конфигурация CD
Итак, приступим к написанию конфигурации непрерывной доставки. Для начала опишем окружения и план.
Окружения
У нас есть несколько окружений и соответствующих им веток:
Окружени | Ветка | Доставка | Кто может коммитить | Кто может сливать |
---|---|---|---|---|
Тестовое | master | Автоматическая | Разработчики, Владельцы | Разработчики, Владельцы |
Опытное | preprod | Автоматическая | Никто | Владельцы |
Промышленное | prod | По нажатию кнопки | Никто | Владельцы |
План работ
Тоже самое в графическом виде:
Приложение
Наше тестовое приложение состоит из двух частей:
Этапы (Stages)
Из приведенного выше плана мы можем выделить этапы, которые нам необходимо определить в нашей конфигурации непрерывной доставки:
Скрипты
Следующая часть конфигурации — скрипты. Документация.
Начнём со скрипта load server который загружает серверный код.
Что здесь происходит?
Такой метод может завершится только двумя способами
Этот метод вызывает два других метода:
Но как мы можем получить директорию с репозиторием?
Когда GitLab выполняет скрипт, он определяет ряд переменных окружения. Одна из них CI_PROJECT_DIR — полный путь до корня репозитория. Так его можно получить в методе getDir :
Вот скрипт запуска тестов:
Обратите внимание на схожесть скриптов тестирования и загрузки. Части скриптов, такие как окружения, одинаковые во всех скриптах могут быть выделены в отдельные блоки. Определим тестовое окружение:
Теперь наш скрипт tests выглядит так:
Теперь напишем соответствующий серверный код, вызывающий юнит тесты (статья на хабре):
Настройка tests — путь относительно корня репозитория до папки с тестами. Если он не задан, то пропускаем юнит тесты.
Метод writeTestHTML (приведён выше) используется для генерации страницы-ссылки на результаты юнит-тестов.
Package
Весь клиент это одна веб-страница, обращающаяся к REST API:
Deploy
Наконец, развернём клиент переместив index.html в корень веб-сервера.
Несколько окружений
Что делать если нужно выполнить один и тот же скрипт в нескольких окружениях? Части скриптов также могут быть именованы, поэтому их тоже можно выделять в отдельные блоки. Вот пример конфигурации загружающей код в тестовое и опытное окружения:
Так мы можем избавиться от дублирования кода.
Полная конфигурация CD доступна здесь и она соответствует первоначальному плану перемещения кода между тестовым, опытным и промышленным окружениями.
Выводы
Непрерывная доставка — это подход к разработке программного обеспечения, в котором команды разрабатывают программное обеспечение в коротких спринтах, гарантируя, что новая версия приложения может быть выпущена в любое время. Данный подход автоматизирует сборку, тестирование и доставку программного обеспечения. Этот подход помогает снизить затраты и риски внесения изменений, позволяя получать быстрые инкрементные обновления для приложений в промышленной эксплуатации.
Ваши приложения на платформах InterSytems, к примеру InterSystems IRIS Data Platform (но всё будет работать и с Caché или Ensemble), легко могут быть адаптированы к процессам непрерывной доставки, увеличивая скорость разработки, улучшая качество кода и устраняя ошибки вызванные ручным управлением процессами сборки, тестирования и доставки.
DevOps: задачи и инструменты
Development Operations (от англ. development – разработка и operations — эксплуатация) — методология, сочетающая принципы продуктивной разработки IT-решений. Этот подход, описанный в 2009 году, известен многим разработчикам, но на российском рынке еще не получил всеобщего признания. Рассмотрим на примере практики SimbirSoft, в чем роль DevOps-инженера и с какими технологиями он работает.
DevOps-инженер — кто это?
DevOps охватывает три этапа жизненного цикла IT-продукта: непосредственно разработку, тестирование и сопровождение. Профессия DevOps-инженера предполагает, что он погружен во все перечисленные области и за счет этого может выбрать такое техническое решение, которое снизит риски конфликтов в IT-системе.
Одна из особенностей роли DevOps — необходимость выстроить взаимодействие между командами разработчиков, тестировщиков и системных администраторов. При этом сам DevOps-инженер должен обладать навыками системного администрирования, отчасти программирования, администрирования в облаках, автоматизировать инфраструктуру и рутинные процессы.
— минимально необходимые права, чтобы сократить влияние человеческого фактора и риски в области безопасности;
— минимально необходимая инфраструктура для оптимизации расходов.
Также специалист должен заложить гибкую архитектуру, чтобы проект было легко масштабировать в случае его дальнейших изменений. В этом случае добавление новых компонентов потребует относительно небольших трудозатрат.
Процессы CI/CD включают в себя:
— постоянное слияние рабочей копии в общую основную версию разработки;
— выполнение автоматизированных сборок проекта для скорейшего выявления потенциальных дефектов;
— решение интеграционных проблем.
Таким образом, мы программируем процесс деплоя — перемещения кода на сервер.
Преимущества
DevOps — достаточно молодая методология, и о ее пользе в отрасли информационных технологий спорят до сих пор. В нашей практике мы видим следующие преимущества DevOps:
автоматизация рутинных процессов и минимизация человеческого фактора;
снижение частоты отказов новых релизов.
Наши выводы подтверждает статистика. Так, согласно исследованию Gitlab, DevOps вносит положительные изменения во все процессы создания продукта, например:
Разработка. Почти 83% разработчиков говорят, что после внедрения DevOps релизы происходят быстрее, чем раньше, а 25% отметили 10-кратное увеличение скорости;
Тестирование. 35% участников исследования, использующих DevOps, автоматизировали задачи в значительной степени.
Ключевые подходы в DevOps
1) Новая парадигма администрирования
Многие компании постепенно уходят от старой парадигмы администрирования серверов — ручного деплоя, который, как правило, применяли в работе с монолитными приложениями. При этом системные администраторы вручную устанавливали приложения на сервера: настраивали «железо», самостоятельно отправляли в продакшн готовые проекты и т.д. Такой подход называют Pet, проводя аналогию с обслуживанием домашних питомцев: если их немного, то владелец обычно сам отвозит их в ветеринарную клинику для всех процедур.
DevOps зачастую следует другой парадигме — Cattle, или большое поголовье животных, подобранных для решения определенных задач. Рассмотрим на примере участия лошадей в состязании, в котором нужна высокая скорость. Используя подход «домашнее животное», мы купим новый корм или подковы, чтобы «улучшить» питомца. Однако, используя другой подход, мы будем рассматривать коня как рабочую единицу, которая не отвечает заявленным характеристикам и требует замены. Если применить этот пример к администрированию, в некоторых ситуациях вам выгоднее развернуть новый сервер, а не тратить время на модернизацию старого.
Такой подход стал возможен во многом благодаря тому, что инфраструктура теперь описывается в виде кода (Infrastructure as Code) и позволяет минимизировать рутинные операции.
Пример: вам нужно заменить путь до того или иного файла сразу на 100 серверах. Для того чтобы сделать это вручную, системному администратору пришлось бы создавать bash-скрипт — файл, в котором прописывают алгоритм команд и программу, выполняющую его. Однако, сейчас мы просто зайдем в репозиторий для хранения данных, изменим там код и развернем его всего в несколько кликов.
2) Logging & Monitoring
С помощью логирования и мониторинга DevOps решает задачу по выявлению любых сбоев в системе до того, как с ними столкнутся пользователи.
Логирование — это регистрация изменений, происходящих внутри действующей программы. Полученная информация дает представление о состоянии сервиса во время взаимодействия с пользователем, в частности, о возникающих проблемах. Эти данные помогают разработчикам оперативно устранять неполадки.
Мониторинг — сбор показателей производительности, в том числе из логов — наглядно предоставляет агрегированную информацию о состоянии сервиса. Необходим как для оценки работоспособности продукта, так и для выявления тенденций в регистрируемых результатах. Например, если зафиксирована повышающаяся нагрузка на приложение, можно спрогнозировать, когда будет необходим дополнительный сервер.
Говоря простыми словами, если бы программа была тюрьмой, тогда мониторинг стал бы сигнализацией, а логирование — системой видеонаблюдения. Первая помогает вовремя отреагировать, а вторая — восстановить ход событий, найти причины и внести необходимые изменения.
В числе популярных инструментов для логирования — ELK stack, Graylog, Splunk. Мы в качестве централизованной системы сбора логов используем ELK stack: Elasticsearch, Logstash и Kibana — для визуализации собранных данных и упрощения их анализа. Также этот стек позволяет настроить алерты (уведомления), которые будут срабатывать при определенном триггере (событии). Например, если сайт недоступен в течение 1 минуты, то система направляет алерт специалисту в заранее выбранный мессенджер.
Для мониторинга используют такие сервисы, как Zabbix, Cacti, Prometheus. Мы в своей работе чаще используем Prometheus — это экосистема, которая включает в себя и другие вспомогательные инструменты, в том числе Alertmanager. Приложение может отправлять уведомления на различные платформы, в частности, в мессенджеры. Таким образом, при выходе собранных метрик за заданные рамки мы оперативно получаем сообщение.
Для визуализации данных мониторинга, на наш взгляд, отлично подходит Grafana. Дашборды можно настраивать под конкретный проект, и для этого можно использовать графики, таблицы, тепловые карты и др.
Перечисленные сервисы помогают минимизировать время простоя в случае сбоев в работе того или иного продукта.
3) Clouds, Terraform
Использование облачных серверов позволяет быстро развернуть инфраструктуру проекта, а также обеспечить отказоустойчивость. Так, мы можем заказать серверы в дата-центрах Москвы, Санкт-Петербурга, Новосибирска и других городов. В случае поломки нам не нужно будет срочно искать ее причину, поскольку ответственность за оказание услуги несут специалисты дата-центра: они сами подключат другой сервер или устранят неполадки.
В числе провайдеров можно отметить как мировых гигантов: Google, Amazon и др., так и российские компании: Yandex.Cloud, Selectel Cloud Platform и т.д.
Мы используем Terraform для управления облачной инфраструктурой. Этот инструмент позволяет работать в парадигме Infrastructure as Code. При этом необходимо описать конечный результат, к которому мы хотим привести наш виртуальный сервер, в виде привычного для специалистов языка — кода. Далее Terraform обращается к API облачного провайдера и совершает заданные действия. В итоге инфраструктура разворачивается в короткие сроки, всего за 15-20 минут. Когда нам нужно будет внести изменения, достаточно будет исправить только необходимые фрагменты кода, при этом результат увидит вся команда.
Описанный подход упрощает администрирование: даже если проект был запущен давно, вам не нужно запоминать все настройки — их в любой момент можно проверить и поправить в репозитории. Важно помнить, что высокая скорость изменений тоже может быть риском, поэтому Terraform требует от специалистов ответственного подхода.