Стадия жизненного цикла модуля: Preview
У модуля есть требования для установки

Модуль поддерживает следующие способы аутентификации и авторизации:

Право на получение списка доступных репозиториев (catalog) доступно для всех аутентифицированных пользователей вне зависимости от способа аутентификации.

Каждый корневой каталог в хранилище образов контейнеров соответствует имени неймспейса в Kubernetes. В случае удаления этого неймспейса все образы в этом каталоге и подкаталогах будут удалены вне зависимости от способа аутентификации.

Аутентификация с использованием токенов Kubernetes

При этом способе аутентификации используются следующие параметры:

Доступ к путям репозиториев определяется правилами Kubernetes RBAC для ресурса PayloadRepositoryAccess.

RBAC и PayloadRepositoryAccess

При аутентификации с использованием токена Kubernetes доступ к путям репозиториев контролируется с использованием Kubernetes RBAC, применённого к виртуальным ресурсам PayloadRepositoryAccess:

  • API grouppayload-registry.deckhouse.io;
  • имя ресурсаpayloadrepositoryaccesses (PayloadRepositoryAccess);
  • назначение — виртуальный ресурс только для настройки доступа к хранилищу образов с использованием Kubernetes RBAC.

Объекты PayloadRepositoryAccess не создаются в Kubernetes, а используются для выдачи прав через Role или ClusterRole на этот ресурс, для проверки доступа к путям и тегам в репозитории со стороны хранилища образов и расширения Kubernetes API.

Поле resourceNames задаёт шаблоны путей репозитория.

Возможные подстановки в шаблоне:

Шаблон Описание
* Любая последовательность символов, кроме / (один сегмент пути)
/**/ Ноль или более директорий (рекурсивный обход)
? Ровно один символ (кроме /) в сегменте пути
[class] Один символ из набора или диапазона, например, [a-z0-9]
{alt1,alt2,...} Один из перечисленных вариантов через запятую

Двойная звёздочка ** должна быть отдельным сегментом пути.

Шаблон вида /path** недействителен и обрабатывается так же, как /path*, нужный эффект даёт /path*/**.

Шаблон /path/** сопоставляется со всеми каталогами и файлами внутри path, а /path/**/ — только с каталогами.

Сопоставление путей регистронезависимое: шаблон и запрашиваемый путь приводятся к нижнему регистру перед проверкой.

Если запрошенный путь совпадает с разрешёнными resourceNames (или resourceNames отсутствует) и совпадает уровень доступа (verb) — доступ разрешается.

Уровни доступа (verbs)

Verb Операция в хранилище образов
get Pull образа и получение информации теге через расширение Kubernetes API
list Получение списка тегов в репозиториях неймспейса через расширение Kubernetes API
create Push образа
delete Удаление образа, в том числе через расширение Kubernetes API

Пример конфигурации RBAC

Пример конфигурации RBAC с выдачей ServiceAccount полного доступа (включая получение и удаление тегов через расширение Kubernetes API) к репозиториям в неймспейсе project-1:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: payload-registry-full
  namespace: project-1
rules:
- apiGroups: ["payload-registry.deckhouse.io"]
  resources: ["payloadrepositoryaccesses"]
  resourceNames: 
    - "dist/*"
    - "app/**"
  verbs: ["get", "list", "create", "delete"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: payload-registry-read
  namespace: project-1
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: payload-registry-full
subjects:
- kind: ServiceAccount
  name: payload-registry-sa
  namespace: project-1

Авторизация с использованием токена и загрузка образа в хранилище

Чтобы авторизоваться в хранилище образов контейнеров с использованием токена, выполните следующие действия:

  1. Создайте неймспейс, к которому будут привязаны образы:

    d8 k create namespace project-1
  2. Авторизация в хранилище с использованием токена ServiceAccount:

    1. Создайте ресурс Role внутри неймспейса, в котором определите доступы (подробнее — в примере выше).

    2. Создайте ServiceAccount:

      d8 k -n project-1 create serviceaccount payload-registry-sa
    3. Привяжите его к Role с использованием RoleBinding (подробнее — в примере выше).

    4. Авторизуйтесь на своей рабочей машине в payload-registry:

      docker login payload-registry.${PUBLIC_DOMAIN} -u token --password $(d8 k -n project-1 create token payload-registry-sa)
  3. Авторизация в хранилище с использованием токена, полученного через интерфейс генерации kubeconfig (ID Token):

    1. Привяжите пользователя, под которым осуществляется доступ к, Role или ClusterRole с использованием RoleBinding или ClusterRoleBining соответственно (пример с использованием Role можно посмотреть выше).

    2. Скопируйте ID Token со страницы kubeconfig.

    3. Авторизуйтесь на своей рабочей машине в хранилище образов:

      docker login payload-registry.${PUBLIC_DOMAIN} -u token -p <ID Token>
  4. Создайте образ и присвойте ему тег:

    docker tag ubuntu:latest payload-registry.${PUBLIC_DOMAIN}/project-1/dist/ubuntu:latest
  5. Загрузите созданный образ в хранилище образов:

    docker push payload-registry.${PUBLIC_DOMAIN}/project-1/dist/ubuntu:latest
  6. Проверьте наличие образа в хранилище. Пример проверки с использованием команды crane:

    crane catalog payload-registry.${PUBLIC_DOMAIN}

Статическая конфигурация пользователей (устаревший способ)

Способ аутентификации устарел (deprecated). Рекомендуется использовать для аутентификации токены Kubernetes.

Статическая конфигурация может быть удалена в будущих версиях.

Этот способ позволяет настроить статическую авторизацию и управлять доступом на основе проектов. Каждый проект представляет собой корневой каталог в хранилище образов и соответствует имени неймспейса в Kubernetes. В случае удаления этого неймспейса все образы в соответствующем каталоге и подкаталогах будут удалены.

Особенности:

  • Пользователи задаются через ModuleConfig в разделе settings.users.
  • Пароль не хранится в открытом виде. В конфигурации указывается только хеш пароля (подробнее — в разделе «Генерация passwordHash»).

Проекты и уровни доступа

Проект — корневой путь в хранилище образов. Имя проекта совпадает с именем неймспейса Kubernetes.

У каждого пользователя может быть несколько записей по проектам с полями:

  • name — имя проекта (неймспейса);
  • subPath — путь или шаблон с wildcard (*, path-*, path/*, */*). Пропуск сегментов ** не поддерживается;
  • access — уровень доступа.

Поддерживаются следующие уровни доступа:

Доступ Разрешённые операции Условие
READ Только pull Всегда
FULL pull и push Только если существует неймспейс с тем же именем, что и проект. Иначе выдаётся доступ READ

Чтобы разрешить push:

  1. Настройте пользователя с access: FULL для проекта и нужного subPath.
  2. Создайте неймспейс (например d8 k create namespace <имя-проекта>).

Пример статической конфигурации пользователей

Пример статической конфигурации пользователей:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: payload-registry
spec:
  version: 1
  enabled: true
  settings:
    users:
      deploy-user:
        passwordHash: "$2y$10$..."   # Bcrypt-хеш пароля.
        projects:
          - name: my-app
            subPath: "*"
            access: FULL
      read-only-user:
        passwordHash: "$2y$10$..."
        projects:
          - name: my-app
            subPath: "*"
            access: READ

Шаблоны subPath: полный путь задаётся как projectName/subPath. Примеры: * (весь проект), path-*, path/*, */*. Шаблон не должен начинаться или заканчиваться слешем.

Генерация passwordHash

Для генерации bcrypt-хеша воспользуйтесь командой htpasswd:

echo -n '${PASSWORD}' | htpasswd -BinC 10 "" | cut -d: -f2 | tr -d '\n'; echo

Сгенерированный хеш необходимо указать в поле users.${USER_NAME}.passwordHash. Пример:

echo -n 'password123' | htpasswd -BinC 10 "" | cut -d: -f2 | tr -d '\n'; echo
$2y$10$CeP/hYvBJ05Ih2azafVyIuuMRpf60am4z6USm4jhHfUPsFDBAmn/u

Пример ModuleConfig с указанием хеша пароля в users.${USER_NAME}.passwordHash:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: payload-registry
spec:
  version: 1
  enabled: true
  settings:
    users:
      user-1:
        # Bcrypt-хеш пароля `password123`.
        passwordHash: "$2y$10$CeP/hYvBJ05Ih2azafVyIuuMRpf60am4z6USm4jhHfUPsFDBAmn/u"
        projects: []

Добавление образа в проект

Для добавления образа в проект выполните следующие действия:

  1. Настройте пользователя с доступом к проекту уровня FULL. Пример:

    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleConfig
    metadata:
      name: payload-registry
    spec:
      version: 1
      enabled: true
      settings:
        users:
          user-1:
            # bcrypt-хеш пароля `password123`
            passwordHash: "$2y$10$CeP/hYvBJ05Ih2azafVyIuuMRpf60am4z6USm4jhHfUPsFDBAmn/u"
            projects:
            - name: "project-1"
              subPath: "*"
              access: FULL
  2. Создайте неймспейс с именем проекта в кластере:

    d8 k create namespace project-1
  3. Авторизуйтесь на своей рабочей машине в хранилище образов:

    docker login payload-registry.${PUBLIC_DOMAIN} -u user-1 -p password123
  4. Создайте образ и присвойте ему тег:

    docker tag ubuntu:latest payload-registry.${PUBLIC_DOMAIN}/project-1/ubuntu:latest
  5. Загрузите созданный образ в хранилище образов:

    docker push payload-registry.${PUBLIC_DOMAIN}/project-1/ubuntu:latest
  6. Проверьте наличие образа в хранилище образов. Пример проверки с использованием команды crane:

    crane catalog payload-registry.${PUBLIC_DOMAIN}