вторник, 11 августа 2020 г.

Aptly. Как организовать контроль пакетов из внешних репозиториев и делегировать управление в продуктовые команды

Всем привет! Решил отрепостить и сюда тоже нашу совместную с коллегами из Positive Technologies Сашей Паздниковым и Никитой Драчёвым статью про Aptly: будет полезной тех-лидам от разработки. Оригинал размещён на Хабре по ссылке.

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

Возможны ситуации, когда в состав разрабатываемого продукта могут попадать нежелательные изменения, которые содержатся во внешних зависимостях. Это особенно актуально во время сертификации продукта. Как следствие — затягивание сертификаций, сбои ночных тестов и интеграционного тестирования, поломки on-premise production (производственной среды, расположенной на собственных ресурсах организации) при накатывании хотфикса и прочее. В новой статье мы описали подход, который позволит избежать таких проблем.

Чего мы хотели добиться


Прежде чем приступать к описанию подхода, пара слов о задачах, которые мы хотели решить:

  • Получить полный контроль над составом внешних пакетов в релизе (предсказуемость).
  • Зафиксировать составы внешних репозиториев для быстрой выкатки хотфиксов с минимальным дополнительным тестированием (скорость).
  • Обеспечить продуктовые стенды QA повторяемым предсказуемым фиксированным окружением (повторяемость).
  • Независимость от наличия внешнего канала связи (автономность).
  • Моментальное переключение на официальные репозитории при аварии (отказоустойчивость).
  • Гарантированная проверка ключей внешних репозиториев в сборочных конвейерах (доверие).
  • И самое главное, передать управление и контроль над составом внешних пакетов в руки продуктовых команд и релиз-менеджеров (самоуправление).

Анализ жизненного цикла feature-сборок


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

Для примера возьмем условный репозиторий Debian Stretch. Данный подход применим и для репозиториев Docker, SaltStack и т. п. На временной шкале зафиксировали три среза на даты T1, T2 и T3.


T1T2T3
stretch202003052020042020200615
Feature1202003042020030420200501
Feature2202003042020030420200601
Feature3202003012020040620200406

Мы свели в таблицу состав внешнего репозитория Debian Stretch для сборки дистрибутивов Feature1, Feature2 и Feature3. Из таблицы видно, что состав внешнего репозитория контролируется каждой веткой независимо. Мы приняли соглашение для себя фиксировать ветку master для Debian Stretch ежедневно и давать метки каждому срезу в формате YYYYMMDD, например 2020304 для среза на 4 марта 2020 года. Итого в таблице приведены используемые для дистрибутива в каждой ветке срезы внешнего репозитория в трех разных моментах времени и состав в мастере для Debian Stretch. Команда для каждой фичи или для каждого релиза обновляет состав внешних репозиториев по своему усмотрению и согласно своему циклу разработки.

На примере Feature1: продуктовая команда приступает к разработке новой фичи и фиксирует в конфигурационных файлах состав внешнего репозитория на дату 20200228 (см. на схеме выше).

Переключаем на 20200228
deb http://repository.co/debian-stretch-20200228 stretch main contrib non-free

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

Переключаем на 20200304
deb http://repository.co/debian-stretch-20200304 stretch main contrib non-free

Далее происходит еще одно переключение пакетной базы на дату 20200501.

Переключаем на 20200501
deb http://repository.co/debian-stretch-20200501 stretch main contrib non-free

Если теперь мы проведем временные срезы, то увидим, что в моменты времени T1 и Т2 разработка Feature1 идет на пакетной базе, «замороженной» 4 марта 2020 года. А в срезе T3 разработка идет уже на новой пакетной базе за 1 мая 2020 года.

Продуктовое мультирелизное управление зависимостями


Теперь рассмотрим управление зависимостями нескольких активных релизов продукта. На поддержке представлены три релиза 2.5, 2.6 и 2.7.

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


РелизСостав
2.5.128, 2.5.135, 2.5.20720200301
2.6.201, 2.6.215, 2.6.31520200301
2.7.210, 2.7.217, 2.7.30520200404

Вместо именования срезов по датам YYYYMMDD мы также используем именование тегами в формате <ProjectName.ReleaseVersion> (название_релиза.версия_релиза продукта, например name.2.2) или <ProjectName-FeatureNumber> (добавляем номер фичи, например 3).

Снапшот для 2.5 по состоянию на 20200301
deb http://repository.co/debian-stretch-projectname-2.5 stretch main contrib non-free # 20200301

Таким образом в процессе разработки релиза 2.5 команда фиксирует состав зависимых репозиториев на дату 20200301. Где-то в апреле команда начинает новый релиз 2.6 и решает использовать состав пакетов внешнего репозитория от 2.5. Создаем новый снапшот для 2.6 из снапшота для 2.5. В будущем составы репозиториев для релизов 2.5 и 2.6 могут легко разойтись. Мы сделали для 2.6 свой тег debian-stretch-projectname-2.6.

Снапшот для 2.6 по состоянию на 20200301
deb http://repository.co/debian-stretch-projectname-2.6 stretch main contrib non-free # 20200301

В случае релиза 2.7 команда может начать разработку с ветки master — ежедневного снапшота оригинального репозитория.

Снапшот для 2.7 по состоянию на 20200404
deb http://repository.co/debian-stretch-projectname-2.7 stretch main contrib non-free # 20200404

Мультипродуктовое управление зависимостями


Рассмотрим мультипродуктовое управление зависимостями на примере двух продуктов с разными релизными циклами и своими продуктовыми командами: Stealth и Infiniti.



Прокомментируем таблицу, что и когда происходит.
ПродуктРелизСостав
stealth2.2r2.2.12420200301
stealth2.2r2.2.131, r2.2.16220200305
infiniti4.0r4.0.235, r4.0.24120200303
infiniti4.0r4.0.25020200308

1. Пусть с 1 марта 2020 года стартовала разработка версии 2.2 проекта Stealth, для этого был создан снапшот состава пакетной базы на текущую дату. Выпуск релиза 2.2.124 выполнен с пакетной базой внешнего репозитория от 20200301.

Stealth 2.2
deb http://repository.co/debian-stretch-stealth-2.2 stretch main contrib non-free # 20200301

2. Пятого числа производится обновление пакетной базы. Рабочий репозиторий debian-stretch-stealth-2.2 одномоментно переключается на нужную дату, выпуск релизов 2.2.131 и 2.2.162 выполнен с составом пакетов внешнего репозитория от 20200305. Без дополнительных манипуляций в окружении все 100500 микросервисов продукта одномоментно получили в сборочном конвейере новое окружение 20200305.

Stealth 2.2
deb http://repository.co/debian-stretch-stealth-2.2 stretch main contrib non-free # 20200305

3. Параллельно третьего числа стартует разработка проекта Infiniti версии 4.0 и для нее создается срез состава репозитория на дату 20200303. Версии 4.0.235 и 4.0.241 выпускаются с составом пакетов внешнего репозитория на 20200303.

Infiniti 4.0
deb http://repository.co/debian-stretch-infiniti-4.0 stretch main contrib non-free # 20200303

4. После выпуска версии 4.0.241 команда решает обновить состав репозитория до 20200308 и выпустить новый релиз с новым составом внешних пакетов. Версия 4.0.250 выходит с составом пакетов на 20200308.

Infiniti 4.0
deb http://repository.co/debian-stretch-infiniti-4.0 stretch main contrib non-free # 20200308

Два варианта переключения между состояниями репозиториев позволяют выбрать удобный для процесса разработки подход. В первом случае мы переключаемся в нужное состояние путем указания снапшота репозиториев на конкретную дату. Во втором случае для многокомпонентных продуктов используем именованный срез и двигаем его на нужную дату. Такой механизм обеспечивает единовременное переключение среза во всех 100500 компонентах продукта.

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

Скачать список всех репозиториев

# For example
curl repository.co/info/sources.list | grep $(lsb_release -cs) > /etc/apt/sources.list

Автоматическое создание срезов внешних репозиториев


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



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

Итоги


  1. Подготовка новой версии дистрибутива к сертификации больше не является головной болью. На период сертификации мы фиксируем состав дистрибутива, и если нужно что-то пофиксить оперативно, то с большой вероятностью в выпущенном хотфиксе не будет ошибок из-за изменения окружения.
  2. Все feature-сборки получают управляемое состояние внешних репозиториев.
  3. Ускоряются выкатка хотфиксов и проверка через QA с предсказуемым, быстрым и успешным результатом.
  4. Feature-стенды получают после развертывания заранее определенную, неизменяемую среду выполнения.
  5. Продуктовые команды получили полностью самостоятельный контроль над составом внешних репозиториев для любых задач.

Отметим, что у Debian есть официальный ресурс snapshot.debian.org с ежедневными срезами и большой глубиной хранения. Для определенных задач этого достаточно.

Благодарим Сергея Смирнова и сообщество за прекрасный инструмент для управления составом внешних репозиториев Aptly. От нас — небольшой вклад в лучшие практики использования этого полезного инструмента в производственных конвейерах.

В следующих статьях расскажем про связку Aptly + Simple-CDD для подготовки ISO-образов дистрибутивов, делегирование управления внешними зависимостями в продуктовые команды и проблемы применения Aptly в процессе управления внешними зависимостями.

АвторыНикита ДрачёвАлександр ПаздниковТимур Гильмуллин