Хабрахабр

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

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

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

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

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

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

Пути решения

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

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

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

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

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

Поддержка в werf

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

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

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

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

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

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

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

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

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

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

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

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

Резюмируя

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

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

P.S.

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

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть