
Тема монорепозиторія обговорювалася вже неодноразово і, зазвичай, викликає дуже активні суперечки. Створюючи як Open Source-інструмент, покликаний поліпшити процеси складання коду додатків з Git в Docker-образи (та їх подальшої доставки в Kubernetes), ми мало розмірковуємо на тему того, який вибір є кращим. Для нас первинно забезпечити все необхідне для прихильників різних думок (якщо це не суперечить здоровому глузду, звісно).
Нещодавно підтримка mono-repo в werf - хороший тому приклад. Але спочатку давайте розберемося, як ця підтримка взагалі пов'язана з використанням werf і при чому тут Docker Registry…
Проблематика
Уявімо таку ситуацію. У компанії є безліч команд розробників, які займаються незалежними проектами. Більшість програм функціонують у Kubernetes, а відповідно — контейнезуються. Для зберігання контейнерів, образів, потрібний реєстр (registry). Як такий реєстр у компанії використовується Docker Hub з єдиним акаунтом COMPANY. За аналогією з більшістю систем зберігання вихідного коду, Docker Hub не дозволяє створювати вкладену ієрархію репозиторіїв, таку як COMPANY/PROJECT/IMAGE. У такому разі… як же з цим обмеженням зберігати в реєстрі немонолітні програми, не створюючи окремий обліковий запис під кожен проект?

Можливо, описана ситуація комусь не з чуток знайома, але розглянемо питання організації зберігання додатків загалом, тобто. без прив'язки до вищеописаного прикладу та Docker Hub.
Шляхи вирішення
Якщо програма монолітно, поставляється в одному образі, то питань не виникає і ми просто зберігаємо образи в реєстрі контейнерів проекту.
Коли програма представлена у вигляді декількох компонентів, мікросервісів, то потрібно вибрати певний підхід. На прикладі типового web-програми, що складається з двох образів: frontend и backend - Можливі варіанти такі:
- Зберігати образи в окремих вкладених репозиторіях:

- Зберігати все в одному репозиторії, а ім'я образу враховувати в тезі, наприклад, так:

NB: Взагалі-то, є ще варіант зі збереженням у різних репозиторіях, PROJECT-frontend и PROJECT-backend, але його ми не розглядатимемо через складність підтримки, організації та розподілу прав між користувачами.
Підтримка у werf
Спочатку werf обмежився вкладеними репозиторіями — благо, більшість реєстрів підтримують таку можливість. Починаючи з версії , додано роботу з реєстрами, в яких не підтримується вкладеність, і Docker Hub - серед них. З цього моменту у користувача з'явився вибір, як зберігати образи програми.
Реалізація доступна в рамках опції --images-repo-mode=multirepo|monorepo (за замовчуванням multirepo, тобто. зберігання у вкладених репозиторіях). Вона визначає шаблони, якими образи зберігаються у реєстрі. Достатньо вибрати потрібний режим під час використання основних команд, а решта залишиться незмінним.
Оскільки більшість опцій werf можна задавати змінними оточення, в CI/CD-системах режим зберігання, як правило, легко поставити глобально для всього проекту. Наприклад, у випадку з GitLab достатньо додати змінну оточення в налаштуваннях проекту: Settings -> CI / CD -> Variables: WERF_IMAGES_REPO_MODE: multirepo|monorepo.
Якщо говорити про публікацію образів та викочування додатків (про ці процеси можна докладно прочитати у відповідних статтях документації: и ), то режим виключно визначає шаблон, яким можна працювати з образом.
Диявол у деталях
Відмінність і основна складність при додаванні нового способу зберігання - в процесі очищення (можливості чищення, що підтримуються в werf, див. ).
При очищенні werf враховує образи, що використовуються в кластерах Kubernetes, а також політики, що настроюються користувачем. В основі політик лежить розподіл тегів на стратегії. Стратегії, які зараз підтримуються:
- 3 стратегії, пов'язані Git-примітивами, такими як тег, гілка та коміт;
- 1 стратегія для довільних користувацьких тегів.
Інформацію про стратегію тега ми зберігаємо під час публікації образу в лейблах кінцевого образу. Саме значення - так званий метатег - Необхідний для застосування частини політик. Наприклад, при видаленні гілки або тега з Git-репозиторію логічно видаляти та пов'язані невикористовувані образи з реєстру, що покривається частиною наших політик.
При збереженні в одному репозиторії (monorepo), у тезі образу, крім метатегу також може зберігатися ім'я образу: PROJECT:frontend-META-TAG. Для їхнього поділу ми не стали вводити якийсь специфічний роздільник, а просто додали необхідне значення до лейблу кінцевого образу при публікації.
NB: Якщо цікаво подивитися на все описане у вихідному коді werf, то відправною точкою може служити .
У цій статті ми не будемо приділяти більше уваги проблематиці та обґрунтуванню нашого підходу: про стратегію тегування, зберігання даних у лейблах та процес публікації в цілому — про все це докладно розказано у нещодавній доповіді Дмитра Столярова: «».
Резюмуючи
Відсутність підтримки реєстрів без вкладеності не була блокуючим фактором для нас чи відомих нам користувачів werf — адже завжди можна підняти окремий реєстр образів (або перейти на умовний Container Registry у Google Cloud)… Однак зняття такого обмеження виглядало логічним для того, щоб інструмент був більш зручним. широкому DevOps-спільноті. Реалізуючи його, ми зіткнулися з головною складністю переробки механізму очищення реєстру контейнерів. Тепер, коли все готово, приємно усвідомлювати, що комусь полегшало, а у нас (як головних розробників проекту) помітних складнощів у подальшій підтримці цієї фічі не передбачається.
Залишайтеся з нами і незабаром ми розповімо про інші нововведення в !
P.S.
Читайте також у нашому блозі:
- «»;
- «».
Джерело: habr.com


