Как стать автором
Обновить
150.33

Как с помощью DevOps построить полноценную inhouse-разработку — опыт ВТБ

Время на прочтение9 мин
Количество просмотров9.3K
Практики DevOps работают. Мы убедились в этом сами, когда сократили время установки релизов в 10 раз. В системе FIS Profile, которую мы используем в ВТБ, установка теперь занимает не 90 минут, а 10. Время сборки релиза снизилось с двух недель до двух дней. Число постоянных дефектов внедрения при этом упало почти до минимума. Чтобы уйти от «ручного труда» и устранить зависимость от вендора, нам пришлось пройти через работу с костылями и найти неожиданные решения. Под катом — подробная история о том, как мы построили полноценную внутреннюю разработку.


 

Пролог: DevOps — это философия


За минувший год с небольшим мы провели немалую работу по организации внутренней разработки и внедрения практик DevOps в ВТБ:

  • Выстроили процессы внутренней разработки по 12 системам;
  • Запустили 15 pipeline, четыре из которых довели до продуктива;
  • Автоматизировали 1445 сценариев тестирования;
  • Успешно внедрили ряд релизов, подготовленных инхаус-командами.

Одной из самых сложных для организации inhouse-разработки и внедрения практик DevSecOps оказалась система FIS Profile — розничный продуктовый процессор на нереляционной СУБД. Тем не менее мы смогли построить разработку, запустить pipeline, выполнить установку на продуктив отдельных внерелизных пакетов и научились собирать релизы. Задача была непростая, но зато интересная и без явных ограничений в реализации: вот система — нужно построить inhouse-разработку. Единственное условие — использовать CD до продуктивной среды.

Поначалу алгоритм реализации казался простым и понятным:

  • Нарабатываем начальную экспертизу разработки и добиваемся от команды кода приемлемого уровня качества без грубых дефектов;
  • Максимально встраиваемся в существующие процессы;
  • Для передачи кода между очевидными этапами пилим pipeline и упираем его одним из концов в прод.

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

Казалось бы, вполне себе энергоэффективный путь к требуемому результату: вот DevOps, вот метрики производительности команды, вот набранная экспертиза… Но на практике мы получили очередное подтверждение того, что DevOps — это все-таки про философию, а не «прикрутить к процессу gitlab, ansible, nexus и далее по списку».

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

С чего начинается inhouse-разработка 


Работать предстояло с далеко не самой дружелюбной системой. Архитектурно она представляла собой одну большую нереляционную СУБД, состояла из множества отдельных исполняемых объектов (скриптов, процедур, батчей и т. д.), которые вызывались по необходимости, и работала по принципу черного ящика: получает запрос — выдает ответ. Среди других сложностей стоит отметить:

  • Экзотический язык (MUMPS);
  • Консольный интерфейс;
  • Отсутствие интеграции с популярными средствами автоматизации и фреймворками;
  • Объем данных в десятки терабайт;
  • Нагрузку свыше 2 млн операций в час;
  • Значимость — Business-Critical.

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

  • Изучили документацию и основы кодогенерации;
  • Проштудировали полученный от вендора краткий курс по разработке;
  • Освоили начальные скилы разработки;
  • Составили методичку для новых участников команды;
  • Договорились о включении команды в работу в «боевом» режиме;
  • Решили вопрос с контролем качества кода;
  • Организовали стенд для разработки.

На наработку экспертизы и погружение в систему мы потратили три месяца, а уже с начала 2019 года inhouse-разработка начала свое движение навстречу светлому будущему, иногда со скрипом, но уверенно и целенаправленно.

Миграция репозитория и автотесты


Первая задача DevOps — репозиторий. О предоставлении доступа договорились быстро, но нужно было выполнить миграцию из текущего SVN с одной trunk-ветвью в целевой для нас Git с переходом на модель из нескольких ветвей и проработкой Git Flow. А еще у нас 2 команды со своей инфраструктурой плюс часть команды вендора за границей. Пришлось жить с двумя Git’ами и обеспечить синхронизацию. В такой ситуации это было меньшее из зол.

Миграция репозитория неоднократно откладывалась, выполнили ее только к апрелю не без помощи коллег из фронт-линии. С Git Flow решили для начала не мудрить, остановились на классической схеме с hotfix, develop и release. От master (он же prod-like) решили отказаться. Ниже мы объясним, почему такой вариант оказался для нас оптимальным. В качестве рабочего использовали внешний репозиторий, принадлежащий вендору, единый для двух команд. Он синхронизировался с внутренним репозиторием по расписанию. Теперь с Git и Gitlab можно было заниматься автоматизацией процессов.

Вопрос автотестов решился на удивление легко — нам предоставили готовый фреймворк. С учетом особенностей системы вызов отдельной операции представлял собой понятную часть бизнес-процесса и параллельно являлся unit-тестом. Оставалось подготовить тестовые данные и задать нужный порядок вызова сценариев с оценкой результатов. По мере наполнения перечня сценариев, сформированного на основе статистики выполнения операций, критичности процессов и существующей методики регресса, начали появляться автотесты. Теперь можно было начинать заниматься построением pipeline.

Как было: модель до автоматизации


Сложившаяся модель процесса внедрения — отдельная история. Каждая доработка вручную передавалась в виде самостоятельного инкрементального установочного пакета. Далее шла ручная регистрация в Jira и ручная установка на среды. Для отдельных пакетов все выглядело понятно, но с подготовкой релиза дела обстояли сложнее.

Сборка выполнялась на уровне отдельных поставок, которые являлись самостоятельными объектами. Любое изменение — новая поставка. Помимо прочего, к 60–70 пакетам основного состава релиза добавлялось 10–15 технических — версий, полученных при добавлении или исключении чего-либо из релиза и отражении изменений прода внерелизами.

Объекты внутри поставок пересекались между собой, особенно в части исполняемого кода, который был уникален менее чем наполовину. Было множество зависимостей как от уже поставленного кода, так и от того, установка которого только планировалась. 

Для получения нужной версии кода требовалось строго соблюдать порядок установки, в ходе которой объекты многократно перезаписывались физически, некоторые по 10–12 раз.

После установки партии пакетов приходилось вручную выполнять инструкции по инициализации настроечных параметров. Релиз собирал и устанавливал вендор. Состав релиза уточнялся практически до момента внедрения, что влекло за собой создание «развязочных» пакетов. В результате заметная часть поставок переезжала из релиза в релиз со своим хвостом «развязок».

Теперь понятно, что при таком подходе — сборке релизного пазла на уровне пакетов — единая master-ветвь не имела практического смысла. Установка на прод занимала от полутора до двух часов ручного труда. Хорошо, что хотя бы на уровне установщика задавался порядок обработки объектов: поля и структуры заезжали раньше, чем данные для них и процедуры. Впрочем, это работало только в рамках отдельного пакета.

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

Первые обновления: сборка по коммиту и доставка


Автоматизацию начали с передачи кода через трубу по такому маршруту:

  • Забрать готовую поставку из хранилища;
  • Установить ее на выделенную среду;
  • Прогнать автотесты;
  • Оценить результат установки;
  • Вызвать следующий pipeline на стороне команды тестирования.

Следующий pipeline должен зарегистрировать задачу в Jira и ожидать команды для разливки на выбранные контуры тестирования, которые зависят от сроков внедрения задачи. Триггер — письмо о готовности поставки на заданный адрес. Это, конечно, был явный костыль, но с чего-то нужно было начать. С мая 2019 началась передача кода с проверками на наших средах. Процесс пошел, осталось привести его в приличный вид:

  • Каждая доработка выполняется в отдельной ветви, которая соответствует установочному пакету и вливается в целевую мастер-ветвь;
  • Триггер запуска pipeline — появление нового коммита в мастер-ветви через merge request, который закрывают мейнтейнеры из команды инхаус;
  • Синхронизация репозиториев происходит раз в пять минут;
  • Запускается сборка установочного пакета — при помощи сборщика, полученного от вендора.

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

Данный вариант запустили в июле. Трудности перехода повлекли за собой некоторое недовольство вендора и фронт-линии, но за следующий месяц нам удалось убрать все шероховатости и наладить процесс в командах. У нас появилась сборка по коммиту и доставка.
В августе удалось выполнить первую установку отдельного пакета на прод средствами нашего pipeline, а с сентября все без исключения установки отдельных внерелизных пакетов выполнялись через наше средство CD. Кроме того, нам удалось достичь доли inhouse задач в 40% состава релиза при меньшей по численности, чем у вендора, команде — это определенный успех. Оставалась самая серьезная задача — собрать и установить релиз.

Финальное решение: кумулятивные установочные пакеты 


Мы прекрасно понимали, что скриптовать инструкцию вендора — так себе автоматизация, нужно было переосмыслить сам процесс. Решение лежало на поверхности — собирать кумулятивную поставку из релизной ветви со всеми объектами нужных версий.

Начали с proof of concept: собрали руками релизную поставку по составу прошедшего внедрения и выполнили ее установку на наших средах. Все получилось, концепция оказалась жизнеспособна. Далее решили вопрос со скриптованием инициализирующих настроек и включением их в коммит. Подготовили новый пакет и проверили его уже на средах тестирования в рамках обновления контура. Установка была успешной, хоть и с обширным рядом замечаний от команды внедрения. Но главное, что нам дали добро на выход в продуктив в ноябрьском релизе с нашей сборкой.

Оставалось чуть больше месяца, собранные вручную поставки прозрачно намекали, что времени в обрез. Сборку решили делать из релизной ветви, но от чего ее отбранчевать? Prod-like у нас нет, а существующие ветви не годятся — много лишнего кода. Надо срочно пилить prod-like, а это свыше трех тысяч коммитов. Собирать руками — вообще не вариант. Набросали скрипт, который бежит по логу установки продуктива и набирает коммиты в ветвь. Раза с третьего он сработал корректно, и после «доработки напильником» ветвь была готова. 

Сборщик установочного пакета написали свой, справились за неделю. Потом пришлось дорабатывать установщик из core-функциональности системы, благо она open-source. После ряда проверок и доработок результат признали успешным. Тем временем оформился состав релиза, для корректной установки которого пришлось выравнивать тестовый контур с продуктивом, написали для этого отдельный скрипт.

Естественно, к первой установке было много замечаний, но в целом код «заехал». А уже примерно с третьей установки все стало неплохо смотреться. Контроль состава и версионность объектов отслеживали отдельно в ручном режиме, что на данном этапе было вполне оправданно.

Дополнительная сложность заключалась в большом количестве внерелизов, которые приходилось учитывать. Но с Prod-like ветвью и Rebase задача стала прозрачной.

С первого раза, быстро и без ошибок


К моменту релиза мы подошли с оптимистичным настроем и более чем десятком успешных установок на разные контуры. Но буквально за сутки до срока оказалось, что вендор не выполнил работы по подготовке релиза к установке принятым способом. Если по каким-то причинам наша сборка не зайдет, то релиз будет сорван. Причем нашими стараниями, что особенно неприятно. Путей для отступления у нас не было. Поэтому мы продумали альтернативные варианты, подготовили планы действий и начали установку.

Удивительно, но весь релиз, состоящий из 800 с лишним объектов, заехал корректно, с первого раза и всего за 10 минут. Целый час мы выверяли логи в поисках ошибок, но не нашли ни одной.

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

Дополнительным эффектом от кумулятива оказалось повышение качества сборки и тестирования. За счет многократных установок полного релиза своевременно выявлялись дефекты сборки и ошибки развертывания. Тестирование в полных релизных конфигурациях позволило дополнительно выявлять дефекты взаимовлияния объектов, которые не проявлялись при инкрементальных установках. Это определенно был успех, особенно на фоне нашего вклада в релиз на уровне 57%.

Итоги и выводы


Менее чем за год нам удалось:

  • Построить полноценную внутреннюю разработку по экзотической системе;
  • Устранить критическую зависимость от вендора;
  • Запустить CI/CD для весьма недружелюбного legacy;
  • Поднять на новый технический уровень процессы внедрения;
  • Заметно сократить длительность развертывания;
  • Значительно уменьшить количество ошибок внедрения;
  • Уверенно заявить о себе как о ведущей экспертизе разработки.

Разумеется, многое из описанного выглядит как откровенная костылизация, но таковы особенности системы и существующие в ней процессные ограничения. На данный момент изменения коснулись продуктов и сервисов ИС Profile (мастер-счета, пластиковые карты, накопительные счета, эскроу, кредит наличными), но потенциально подход можно применить к любой ИС, для которой поставлена задача внедрения практик DevOps. Кумулятивную модель можно смело тиражировать на последующие внедрения (в том числе внерелизные) из множества поставок.
Теги:
Хабы:
Всего голосов 8: ↑6 и ↓2+8
Комментарии12

Публикации

Информация

Сайт
www.vtb.ru
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия