Привет всем! В данной статье мы осветим наш опыт внедрения реестра Docker-образов Harbor в CI/CD платформу Gitorion. Расскажем, как настроить внешнюю аутентификацию Harbor в Keycloak по протоколу OIDC. Разграничим права доступа пользователей к реестру на основе ролей RBAC. Настроим дисковые квоты и автоматизируем очистку Harbor от устаревших Docker-образов, используя API Harbor в пайплайне Jenkins.

Назначение реестра Docker-образов

Кратко напомним, какую функцию выполняет реестр Docker-образов в цикле CI/CD. Во время непрерывной интеграции разработчик вносит изменения в код и делает commit в Git-репозиторий Forgejo. Forgejo посылает Web-хук в Jenkins. Jenkins автоматически вытягивает код из Git-репозитория, компилирует и упаковывает в Docker-образ. Для хранения всех собираемых на платформе Docker-образов используется реестр Docker-образов. Во время непрерывной доставки pipeline Jenkins устанавливает Helm-чарт приложения в кластер Kubernertes. Helm-чарт создает Deployment или StatefulSet, которые извлекают Docker-образ с приложением из приватного реестра Docker-образов и используют его для запуска Docker-контейнера в кластере Kubernetes.

Обоснование внедрения Harbor

В статье CI/CD Kubernetes платформа Gitorion. Приватный реестр Docker-образов с аутентификацией в Keycloak и Web-интерфейсом мы рассмотрели простейший вариант приватного реестра Docker-образов на базе связки Docker-registry с Web-интерфейсом Joxit и аутентификацией в Keycloak. Однако, это решение подойдет команде разработчиков, которой просто нужно делать push/pull Docker-образов в реестр, иметь простой Web-интерфейс, закрытый логином и паролем, и одинаковые права доступа для всех членов команды. В качестве альтернативы мы интегрировали в платформу реестр Harbor, обладающий более широким набором функций.

Краткий обзор Harbor

Harbor - это бесплатный Open-source инструмент, предоставляющий пользователям следующие возможности:

  • закачивать push и скачивать pull Docker-образы;

  • хранить Docker-образы и Helm-чарты на внешнем накопителе;

  • создавать публичные или приватные репозитории сразу для нескольких проектов;

  • предоставлять пользователю удобный Web-интерфейс;

  • выполнять аутентификацию пользователей. Harbor может самостоятельно выполнять аутентификацию и хранить логины и пароли пользователей в собственной базе данных. Также к Harbor можно подключить внешний источник аутентификации по одному из протоколов LDAP, UAA, OIDC;

  • разграничивать права доступа к реестру на основе ролей RBAC;

  • задавать дисковые квоты;

  • удалять устаревшие Docker-образы;

  • сканировать Docker-образы на уязвимости;

  • подключать к Harbor другие реестры Docker-образов в качестве бэкенда.

Подключаем Harbor к Keycloak

Поскольку бесшовную аутентификацию во все сервисы платформы выполняет Keycloak, настроим аутентификацию пользователей в Harbor, используя Keycloak как внешний источник аутентификации.

На странице администратора Keycloak создайте клиента для Harbor. В верхнем правом углу выберите область Realm и нажмите "Create client" в меню "Clients".

Список клиентов  в Keycloak
Список клиентов в Keycloak

В следующем окне задайте тип клиента "OpenID Connect" в поле "Clietn type". Задайте ClientID, имя клиента, описание клиента и нажмите кнопку "Next".

Параметры клиента Harbor
Параметры клиента Harbor

Включите "Client authentication" и галочки "Standart flow" и "Direct access grants". Нажмите кнопку "Next".

Параметры клиента Harbor
Параметры клиента Harbor

В следующем окне задайте URL вашего реестра Docker-образов в поле "Root URL" и нажмите кнопку "Next".

Параметры клиента Harbor
Параметры клиента Harbor

В результате будет создан клиент Harbor в Keycloak. Теперь войдите администратором в Web-интерфейс Harbor.

Окно аутентификации Harbor
Окно аутентификации Harbor

Перейдите в меню "Configuration -> Authentication".

Настройка аутентификации Harbor
Настройка аутентификации Harbor

Выберите тип аутентификации "OIDC" в выпадающем списке "Auth Mode" и задайте следующие параметры:

  • "OIDC Provider Name" - надпись на кнопке внешней аутентификации, которая появится на странице аутентификации Harbor;

  • "OIDC Endpoint" - адрес конечной точки внешней аутентификации, состоящий из URL к Keycloak и пути к области, в которой был создан клиент Harbor в предыдущем пункте;

  • "OIDC Client" - имя клиента Harbor в Keycloak, заданное в поле "Client ID" в Keycloak;

  • "OIDC Client Secret" - ключ доступа Harbor к Keycloak. Cкопируйте из поля "Client Secret" на вкладке "Credentials" настроек клиента Harbor в Keycloak;

  • "OIDC Group Filter" - при успешной аутентификации пользователя Keycloak выдаст Harbor токен, содержащий имя группы, в которой состоит пользователь. В данном поле можно отфильтровать возвращаемые группы с помощью регулярного выражения;

  • "Group Clime Name" - имя заявки из Harbor в Keycloak на получение группы пользователя;

  • "OIDC Admin Group" - группа с административными правами;

  • "OIDC Scope" - список scope с информацией о пользователе, который Keycloak должен передать Harbor в токене после успешной аутентификации пользователя;

  • "Veryfi Sertificate" - установить защищенное SSL-соединение между Harbor и Keycloak;

  • "Automatic Onboarding" - при первой аутентификации пользователя с помощью Keycloak Harbor выдает запрос на создание локального пользователя и предлагает связать с ним пользователя из Keycloak. Установите данную галочку, чтобы автоматизировать создание и привязку пользователя. Например, для пользователя developer из Keycloak Harbor автоматически создаст локального пользователя developer_developer и свяжет с пользователем из Keycloak.

Задайте "Redirect URI", расположенный в строке над кнопкой "SAVE" в поле "Valid Redirect URIs" в настройках клиента Harbor в Keycloak. Нажмите кнопку "SAVE", и в Harbor будет создан внешний источник аутентификации в Keycloak.

Аутентификация пользователей Harbor в Keycloak

После добавления внешнего источника аутентификации на странице аутентификации Harbor появится кнопка, по которой можно пройти аутентификацию в Keycloak.

Окно аутентификации Harbor
Окно аутентификации Harbor

Нажмите кнопку "LOGIN WITH keycloak", и вас перенаправит на окно аутентификации Keycloak.

Окно аутентификации Keycloak
Окно аутентификации Keycloak

Введите логин и пароль, и в случае удачной аутентификации Keycloak перекинет вас обратно на Web-интерфейс Harbor.

Web-интерфейс Harbor
Web-интерфейс Harbor

Разграничение прав доступа с помощью ролей RBAC

Harbor поддерживает разграничение прав пользователей в соответствии с их ролью в проекте. Всего Harbor поддерживает 5 ролей для пользователей: Limited Guest, Guest, Developer, Maintainer и ProjectAdmin. Список разрешенных действий для каждой роли можно посмотреть тут. В статье CI/CD Kubernetes платформа Gitorion. Единый вход Single Sign-On (SSO) во все сервисы платформы при помощи Keycloak мы создали две группы пользователей: "devs" - пользователям которой даны права только на чтение и "admins" - пользователем которой даны административные права во всех сервисах платформы. Ниже мы покажем, как связать группу "devs" из Keycloak c ролью "Developer" в Harbor, а группу "admins" c ролью "ProjectAdmin".

Настроим Keycloak передавать в Harbor группу пользователя в токене после успешной аутентификации пользователя. В настройках клиента Harbor в Keycloak перейдите на вкладку "Client Scopes".

Настройка Client scopes клиента Harbor
Настройка Client scopes клиента Harbor

Выберите "harbor-dedicated", перейдите на вкладку "Mappers", нажмите кнопку "Configure a new mapper" и выберите в списке "Group Membership".

Создаем mapper "Group Membership"
Создаем mapper "Group Membership"

Задайте имя mapper-а в поле "Name". В поле "Token Claim Name" укажите имя заявки, которое задали в поле "Group Clime Name" при настройке источника аутентификации OIDC в Harbor выше. Нажмите кнопку "Save".

Параметры mapper-а "Group Membership"
Параметры mapper-а "Group Membership"

Теперь залогиньтесь в Harbor через Keycloak любым пользователем из группы "admins", а затем любым пользователем из группы "devs", чтобы пользователи и группы из Keycloak появились в Harbor.

Группы из Keycloak в Harbor
Группы из Keycloak в Harbor
Пользователи из Keycloak в Harbor
Пользователи из Keycloak в Harbor

Осталось только связать группы пользователей из Keycloak с ролями Harbor. Для этого выберите ваш проект с репозиториями в Harbor.

Список проектов в Harbor
Список проектов в Harbor

Перейдите на вкладку "Members" и нажмите кнопку "+GROUPS".

Список членов группы проекта
Список членов группы проекта

Свяжите роль "Project Admin" из Harbor с группой "admins" из Keycloak и аналогично группу "devs" свяжите с ролью "Developers".

Связываем роль с группой
Связываем роль с группой

Теперь залогиньтесь в Harbor через Keycloak любым пользователем из группы "admins", и вы увидите напротив названия проекта роль пользователя "System Admin", а в меню слева появится оснастка администратора Harbor.

Web-интерфейс администратора Harbor
Web-интерфейс администратора Harbor

Залогиньтесь любым пользователем из группы "devs", и вы увидите роль пользователя "Developer", а оснастка администратора в меню отсутствует.

Web-интерфейс разработчика в Harbor
Web-интерфейс разработчика в Harbor

Дисковые квоты

По умолчанию место на жестком диске, занимаемое Docker-образами проектов, не ограничено. Harbor позволяет установить дисковые квоты как для всех проектов разом, так и для каждого проекта в отдельности. Войдите администратором в Web-интерфейс Harbor и перейдите в меню "Project Quotas" в оснастке администратора.

Страница настройки дисковых квот
Страница настройки дисковых квот

Для примера зададим квоту 10Gb для проекта "gitorion".

Задаем размер дисковой квоты
Задаем размер дисковой квоты

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

Страница с информацией о проекте
Страница с информацией о проекте

При исчерпании квоты попытка выполнить push Docker-образа в реестр приведет к ошибке, показанной на картинке ниже.

Исчерпание дисковой квоты
Исчерпание дисковой квоты

API Harbor. Автоматизируем очистку реестра

Harbor имеет собственный API, позволяющий взаимодействовать с реестром из скриптов и пайплайнов. В нашем случае мы использовали API Harbor для автоматизации очистки реестра от устаревших Docker-образов. Удалять Docker-образы можно в Web-интерфейсе Harbor, пометив галочкой и нажав кнопку, но это неудобно, когда Docker-образов много. Ознакомиться с API Harbor можно по ссылке "Harbor API v2.0" в левом нижнем углу Web-интерфейса Harbor. В появившемся окне пройдите аутентификацию в Harbor по кнопке "Authorize" и получите возможность запускать и отлаживать команды API прямо на странице API Harbor.

API Harbor
API Harbor

Тут же можно получить команды API и далее использовать в скриптах или пайплайнах. Для автоматизации очистки реестра нам потребовались три команды API Harbor:

//получить список репозиториев
curl -u $HARBOR_LOGIN:$HARBOR_PASSWORD -X GET https://registry.gitorion.kvm/api/v2.0/repositories

//получить список Docker-образов в репозитории
curl -u $HARBOR_LOGIN:$HARBOR_PASSWORD -X GET https://registry.gitorion.kvm/api/v2.0/projects/${project_name}/repositories/${repository_name}/artifacts

//Удалить Docker-образ
curl -u $HARBOR_LOGIN:$HARBOR_PASSWORD -X DELETE https://registry.gitorion.kvm/api/v2.0/projects/${project_name}/repositories/${repository_name}/artifacts/${reference}

Далее мы создали параметризированный пайплайн в Jenkins, который подключается к API Harbor и извлекает список репозиториев.

Список репозиториев
Список репозиториев

Полученный список репозиториев Jenkins подгружает в параметр ChoiceParameter.

Пайплайн Jenkins для очистки репозитория
Пайплайн Jenkins для очистки репозитория

Пользователь выбирает репозиторий, задает дату и нажимает кнопку "Собрать". Jenkins запускает пайплайн "registry-cleaning", который удаляет все Docker-образы в выбранном репозитории, созданные раньше указанной даты.

Для примера мы удалили из репозитория "owneruser/backend/dev1" проекта "gitorion" все Docker-образы старше 2024-10-31.

Список Docker-образов в репозитории
Список Docker-образов в репозитории

Журнал работы пайплайна очистки реестра "registry-cleaning" приведем на картинке ниже.

:Журнал работы пайплайна очистки реестра
:Журнал работы пайплайна очистки реестра

После очистки, Harbor отобразит в Web-интерфейсе, что репозиторий стал занимать меньше места, но фактически не удалит файлы с жесткого диска. Чтобы удалить файлы с жесткого диска нужно запустить сборщик мусора "Garbage Collection" в меню "Clean Up" оснастки администратора кнопкой "GC NOW".

Сборщик мусора "Garbage Collection"
Сборщик мусора "Garbage Collection"

Тут же можно настроить запуск сборщика мусора по расписанию, нажав кнопку "EDIT" в пункте "Shedule to GC".

Заключение

В данной статье мы рассмотрели ключевые функции реестра Docker-образов Harbor, которые позволили сделать его частью CI/CD цикла платформы Gitorion. Спасибо за внимание!

Комментарии (0)