company_banner

Полная поддержка популярных реализаций Docker Registry в werf

    image


    Все популярные реализации реестров для образов контейнеров поддерживают Docker Registry HTTP API и позволяют использовать одни и те же инструменты для работы с ними. Тем не менее, часть реализаций имеет свои особенности и ограничения, а значит — если вам нужно их поддерживать в своем инструментарии для CI/CD, — с этой спецификой необходимо считаться. Так у нас и случилось в процессе работы над GitOps-утилитой werf, когда мы захотели улучшить в ней то, как обеспечивается жизненный цикл образов.


    В статье рассказывается об основных особенностях поддерживаемых имплементаций Docker Registry, а также о соответствующих нововведениях в werf.


    Хранение образов


    Для хранения Docker-контейнеров, их образов, необходим реестр (registry). Строго говоря, registry — сервис для хранения репозиториев (AWS ECR, Azure CR, Docker Hub и так далее). В репозитории хранятся образы, сгруппированные по имени.


    При использовании werf для сборки приложений и/или их деплоя в Kubernetes доступны опции --images-repo и --images-repo-mode, которые позволяют определить, где и как (в одном или нескольких репозиториях*) будут храниться образы приложения в registry.


    * Проблематика и история внедрения этой опции описывалась в статье «Поддержка monorepo и multirepo в werf и при чём здесь Docker Registry».


    Параметр --images-repo может быть как адресом registry, так и repository. По сути это значение является основой для построения имени образа, а вовсе не обязательно репозиторием, в котором будут храниться образы (шаблоны, описанные ниже, проясняют этот момент).


    Для параметра --images-repo-mode поддерживаются два значения, которые определяют шаблон, по которому строится конечное имя образа:


    • IMAGES_REPO:IMAGE_NAME-TAG — шаблон для режима monorepo;
    • IMAGES_REPO/IMAGE_NAME:TAG — шаблон для режима multirepo.

    Примечание: при использовании единственного и безымянного образа (image: ~) значение параметра опции --images-repo-mode не имеет никакого смысла, т.к. конечный образ будет всегда использовать значение --images-repo в качестве репозитория (IMAGES_REPO:TAG).


    Так как образы не могут храниться в registry, использование режима monorepo совместно с registry не имеет никакого смысла. По этой же причине нельзя использовать безымянный образ (image: ~) и registry, независимо от значения --images-repo-mode.


    Поддержка возможных опций


    Таким образом, пользователю доступны 3 возможные комбинации значений этих параметров. В таблице ниже представлен список реализаций Docker Registry и поддержка в них этих комбинаций:


    реализация registry + multirepo repository + monorepo repository + multirepo
    AWS ECR* + + +
    Azure CR + + +
    Default (DTR) + + +
    Docker Hub + + -
    GCR + + +
    GitHub Packages + + -
    GitLab Registry + + +
    Harbor + + +
    Quay + + -

    * В AWS ECR репозитории не создаются автоматически при публикации образа. Требуется создать их вручную (через UI или API) перед использованием.


    Как видно по таблице, единственное ограничение распространяется на Docker Hub, GitHub Packages и Quay: в них не поддерживаются многоуровневые имена репозиториев (REGISTRY/REPO/SUBREPO).


    Тип реализации, равно как и значение --images-repo-mode, определяется автоматически. Для реализаций, которые поддерживают всё без исключения, multirepo — всегда значения по умолчанию. Значение для остальных имплементаций определяется автоматически по переданному значению --images-repo.


    Для того, чтобы задать имя имплементации вручную, можно воспользоваться опцией --implementation. Это может понадобиться, например, если в качестве адреса используется алиас из hosts или необходимо вручную запустить очистку GitLab Registry с помощью werf (при использовании в pipeline ci-env проставит необходимое значение при необходимости).


    Иллюстрация


    А теперь небольшой пример, который прояснит всё вышесказанное.


    Рассмотрим следующий werf.yaml:


    project: flant
    configVersion: 1
    ---
    image: backend
    dockerfile: Dockerfile
    target: backend
    ---
    image: frontend
    dockerfile: Dockerfile
    target: frontend

    … и аккаунт на Docker Hub под названием flant.


    Параметр --images-repo=flant приведёт к следующим тегам:


    • flant/frontend:tag
    • flant/backend:tag

    werf build-and-publish -s=:local -i=flant --tag-custom=tag

    Параметр --images-repo=flant/project приведёт к следующим тегам:


    • flant/project:frontend-tag
    • flant/project:backend-tag

    werf build-and-publish -s=:local -i=flant/project --tag-custom=tag

    Пояснение к werf build-and-publish


    Это команда для сборки образов, описанных в werf.yaml, и их последующей публикации в реестре. Используемые параметры:


    • -s — краткая запись опции --stages-storage, которая определяет хранилище стадий (подробнее про зависимость образов от стадий — см. в документации);
    • -i — краткая запись опции --images-repo;
    • --tag-custom — одна из возможных опций тегирования (подробнее про именования и доступные схемы тегирования — в документации).

    Очистка образов


    Еще одна задача, требующей внимания в контексте реестров образов, — это очистка. Ниже представлена таблица, в которой сопоставлены имплементации и необходимый API для удаления тегов:


    Реализация API
    AWS ECR Amazon ECR API
    Azure CR Azure CR API
    Default (DTR) Docker Registry API
    Docker Hub Docker Hub API
    GCR Docker Registry API
    GitHub Packages GitHub GraphQL API (только в приватных git-репозиториях)
    GitLab Registry Docker Registry API
    Harbor Docker Registry API
    Quay Docker Registry API

    Для реализаций, поддерживающих удаление тегов с Docker Registry API, достаточно выполнить docker login с токеном, наделенным достаточными полномочиями. А у остальных имплементаций: AWS ECR, Azure CR, Docker Hub и GitHub Packages — неполная поддержка Docker Registry API, поэтому потребуется использовать их API для удаления тегов. При их очистке могут потребоваться дополнительные пользовательские данные.


    Особенности


    Каковы же особенности использования этих имплементаций при очистке с werf?


    • Для Azure необходимо установить CLI (az) и выполнить авторизацию пользователя с одной из следующих ролей: Owner, Contributor или AcrDelete. Подробности доступны в документации: Azure CR roles and permissions.
    • При удалении тегов из AWS ECR используется AWS SDK. Пользователь может установить AWS CLI и выполнить конфигурацию (aws configure) или просто задать переменные окружения AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY перед выполнением очистки.
    • Для чистки тегов в репозитории Docker Hub werf использует Docker Hub API и для работы требуется token. Пользователь может задать токен* (--images-repo-docker-hub-token) или пользователя с паролем (--images-repo-docker-hub-username + --images-repo-docker-hub-password).

    Обратите внимание, что в качестве токена для Docker Hub нельзя использовать personal access token, т.к. удаление ресурсов возможно только при использовании основных учётных данных.


    * Используя следующий скрипт, пользователь может получить token самостоятельно:


    HUB_USERNAME=USERNAME
    HUB_PASSWORD=PASSWORD
    HUB_TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${HUB_USERNAME}'", "password": "'${HUB_PASSWORD}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)


    Резюмируя


    Мы решили поддерживать следующий набор реализаций Docker Registry в werf:


    • AWS ECR;
    • Azure CR;
    • Docker Hub;
    • Default (DTR);
    • GCR;
    • GitHub Packages;
    • GitLab Registry;
    • Harbor;
    • Quay.

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


    Описанные в статье фичи доступны в релизах werf с версии v1.1.9+fix2.


    Актуальные изменения и особенности, связанные с поддерживаемыми реализациями Docker Registry, доступны в документации проекта.


    P.S.


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


    Флант
    Специалисты по DevOps и Kubernetes

    Комментарии 6

      0
      не заметил упоминания nexus, не поясните за него?
        +1

        Работаем по законам спроса и предложения: проверить все имплементации нет возможности, поэтому наращиваем набор только при должной потребности.


        В ближайших планах есть поддержка JFrog Artifactory.
        До nexus тоже доберёмся. Спасибо за обратную связь.


        P.S. Для многих имплементаций никаких дополнительных обвязок не требуется и всё будет работать по умолчанию (Docker Registry API)

          0
          спасибо за ответ, попробую, я так понимаю api v2 везде одинаков, хоть я и не вдавался в подробности.
            0

            Основных момента два:


            • поддерживаются ли многоуровневые имена репозиториев.
            • поддерживается ли стандартное, с Docker Registry API, удаление тегов.

            Первое можно отрегулировать с помощью опции --images-repo-mode, а вот со вторым или самостоятельно организовывать очистку или добавлять поддержку в werf.

              0
              а второе не проще политиками делать на стороне реджистри? аля, не качали образ неделю — удаляй, прод образы удаляй только через полгода. Я даже слабо представить могу, как это можно организовать на стороне приложения, которое собирает образы, а не занимается хранением. Хотя, когда пользовался обычным реджистри, штука бы пригодилась, если бы умела делать GC за собой.
              Спасибо за ваш труд.
                +1

                Наш опыт показывает, что регистри не имеет достаточно данных для того, чтобы делать очистку правильно, поэтому необходимо делать это извне и брать в расчёт Git, Kubernetes и ...


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


                Пока можно почитать про текущие политики и логику работы в документации.

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

      Самое читаемое