- PVSM.RU - https://www.pvsm.ru -

Поддержка monorepo и multirepo в werf и при чём здесь Docker Registry

Поддержка monorepo и multirepo в werf и при чём здесь Docker Registry - 1

Тема монорепозитория обсуждалась уже не раз и, как правило, вызывает весьма активные споры. Создавая werf [1] как Open Source-инструмент, призванный улучшить процессы сборки кода приложений из Git в Docker-образы (и их последующей доставки в Kubernetes), мы мало размышляем на тему того, какой выбор лучше. Для нас первично обеспечить всё необходимое для сторонников разных мнений (если это не противоречит здравому смыслу, конечно).

Появившаяся недавно поддержка mono-repo в werf — хороший тому пример. Но для начала давайте разберёмся, как эта поддержка вообще связана с использованием werf и при чём здесь Docker Registry…

Проблематика

Представим такую ситуацию. В компании имеется множество команд разработчиков, занимающихся независимыми проектами. Большинство приложений функционируют в Kubernetes, а соответственно — контейнезируются. Для хранения контейнеров, образов, необходим реестр (registry). В качестве такого реестра в компании используется Docker Hub с единственным аккаунтом COMPANY. По аналогии с большинством систем хранения исходного кода, Docker Hub не позволяет создавать вложенную иерархию репозиториев, такую как COMPANY/PROJECT/IMAGE. В таком случае… как же с этим ограничением хранить в реестре немонолитные приложения, не создавая отдельный аккаунт под каждый проект?

Поддержка monorepo и multirepo в werf и при чём здесь Docker Registry - 2

Возможно, описанная ситуация кому-то не понаслышке знакома, но давайте рассмотрим вопрос организации хранения приложений в общем, т.е. без привязки к вышеописанному примеру и Docker Hub.

Пути решения

Если приложение монолитно, поставляется в одном образе, то вопросов не возникает и мы просто сохраняем образы в реестр контейнеров проекта.

Когда приложение представлено в виде нескольких компонентов, микросервисов, то требуется выбрать определённый подход. На примере типового web-приложения, состоящего из двух образов: frontend и backend — возможные варианты таковы:

  1. Хранить образы в отдельных вложенных репозиториях:

    Поддержка monorepo и multirepo в werf и при чём здесь Docker Registry - 3

  2. Хранить всё в одном репозитории, а имя образа учитывать в теге, к примеру, следующим образом:

    Поддержка monorepo и multirepo в werf и при чём здесь Docker Registry - 4

NB: Вообще-то, есть ещё вариант с сохранением в различных репозиториях, PROJECT-frontend и PROJECT-backend, но его мы не будем рассматривать из-за сложности поддержки, организации и распределения прав между пользователями.

Поддержка в werf

Изначально werf ограничился вложенными репозиториями — благо, большинство реестров поддерживают такую возможность. Начиная с версии v1.0.4-alpha.3 [2], добавлена работа с реестрами, в которых не поддерживается вложенность, и Docker Hub — в их числе. С этого момента у пользователя появился выбор, как хранить образы приложения.

Реализация доступна в рамках опции --images-repo-mode=multirepo|monorepo (по умолчанию multirepo, т.е. хранение во вложенных репозиториях). Она определяет шаблоны, по которым образы хранятся в реестре. Достаточно выбрать нужный режим при использовании основных команд, а всё остальное останется неизменным.

Поскольку большинство опций werf можно задавать переменными окружения, в CI/CD-системах режим хранения, как правило, легко задать глобально для всего проекта. Например, в случае с GitLab достаточно добавить переменную окружения в настройках проекта: Settings -> CI / CD -> Variables: WERF_IMAGES_REPO_MODE: multirepo|monorepo.

Если говорить о публикации образов и выкате приложений (об этих процессах можно подробно прочитать в соответствующих статьях документации: Publish process [3] и Deploy process [4]), то режим исключительно определяет шаблон, по которому можно работать с образом.

Дьявол в деталях

Отличие и основная сложность при добавлении нового способа хранения — в процессе очистки registry (возможности чистки, поддерживаемые в werf, см. в Cleaning process [5]).

При очистке werf учитывает используемые в кластерах Kubernetes образы, а также политики, настраиваемые пользователем. В основе политик лежит разделение тегов на стратегии. Стратегии, поддерживаемые в настоящий момент:

  1. 3 стратегии, связанные Git-примитивами, такими как тег, ветка и коммит;
  2. 1 стратегия для произвольных пользовательских тегов.

Информацию о стратегии тега мы сохраняем при публикации образа в лейблах конечного образа. Само значение — так называемый метатег — необходим для применения части политик. Например, при удалении ветки или тега из Git-репозитория логично удалять и связанные неиспользуемые образы из реестра, что и покрывается частью наших политик.

При сохранении в одном репозитории (monorepo), в теге образа, помимо метатега также может храниться имя образа: PROJECT:frontend-META-TAG. Для их разделения мы не стали вводить какой-то специфичный разделитель, а просто добавили необходимое значение в лейбл конечного образа при публикации.

NB: Если интересно посмотреть на всё описанное в исходном коде werf, то отправной точкой может служить PR 1684 [6].

В этой статье мы не будем уделять больше внимания проблематике и обоснованию нашего подхода: про стратегии тегирования, хранения данных в лейблах и процесс публикации в целом —обо всём этом подробно рассказано в недавнем докладе Дмитрия Столярова: «werf — наш инструмент для CI/CD в Kubernetes [7]».

Резюмируя

Отсутствие поддержки реестров без вложенности не являлось блокирующим фактором для нас или известных нам пользователей werf — ведь всегда можно поднять отдельный реестр образов (или перейти на условный Container Registry в Google Cloud)… Однако снятие такого ограничения выглядело логичным для того, чтобы инструмент был удобен более широкому DevOps-сообществу. Реализуя его, мы столкнулись с главной сложностью в переработке механизма очистки реестра контейнеров. Теперь, когда всё готово, приятно осознавать, что кому-то стало легче, а у нас (как главных разработчиков проекта) заметных сложностей в дальнейшей поддержке этой фичи не предвидится.

Оставайтесь с нами и совсем скоро мы расскажем о других нововведениях в werf [1]!

P.S.

Читайте также в нашем блоге:

Автор: Алексей Игрычев

Источник [9]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/open-source/328589

Ссылки в тексте:

[1] werf: https://github.com/flant/werf

[2] v1.0.4-alpha.3: https://github.com/flant/werf/releases/tag/v1.0.4-alpha.3

[3] Publish process: https://werf.io/documentation/reference/publish_process.html

[4] Deploy process: https://werf.io/documentation/reference/deploy_process/deploy_into_kubernetes.html

[5] Cleaning process: https://werf.io/documentation/reference/cleaning_process.html

[6] PR 1684: https://github.com/flant/werf/pull/1684/files

[7] werf — наш инструмент для CI/CD в Kubernetes: https://habr.com/ru/company/flant/blog/460351/

[8] Собирать Docker-образы в werf теперь можно и по обычному Dockerfile: https://habr.com/ru/company/flant/blog/463613/

[9] Источник: https://habr.com/ru/post/465131/?utm_source=habrahabr&utm_medium=rss&utm_campaign=465131