Як за допомогою DevOps побудувати повноцінну inhouse-розробку – досвід ВТБ

Практики DevOps працюють. Ми переконалися в цьому самі, коли скоротили час встановлення релізів у 10 разів. У системі FIS Profile, яку ми використовуємо у ВТБ, встановлення тепер займає не 90 хвилин, а 10. Час складання релізу знизився з двох тижнів до двох днів. Число постійних дефектів застосування при цьому впало майже до мінімуму. Щоб уникнути «ручної праці» та усунути залежність від вендора, нам довелося пройти через роботу з милицями та знайти несподівані рішення. Під катом — докладна історія про те, як ми збудували повноцінну внутрішню розробку.

Як за допомогою DevOps побудувати повноцінну inhouse-розробку – досвід ВТБ
 

Пролог: 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. Кумулятивну модель можна сміливо тиражувати на наступні впровадження (у тому числі позарелізні) з багатьох поставок.

Джерело: habr.com

Додати коментар або відгук