ADG Оставить заявку
Блог DevOps 5 мин чтения

Helm 3.7 + Harbor OCI: charts и образы в одном registry

Helm 3.7 стабилизировал OCI-реестры для хранения charts. Переносим клиентский chart-репозиторий с ChartMuseum на Harbor: сканирование, pipeline и один registry на всё.

Контекст момента

Helm 3.7 переводит поддержку OCI-реестров для хранения Helm charts из экспериментальной в стабильную

Helm 3.7 вышел на этой неделе, и главная новость там - OCI-поддержка charts вышла из-за флага HELM_EXPERIMENTAL_OCI=1 и стала частью стабильного API. Для нас это был сигнал: наконец-то можно делать то, что мы откладывали уже несколько месяцев - переводить chart-репозиторий клиента с ChartMuseum на Harbor.

Расскажем, как это выглядело на практике.

Почему ChartMuseum начал раздражать

ChartMuseum - вполне рабочий инструмент, и мы не собираемся на него катить. Но у клиента уже стоял Harbor для container images, и поддерживать два отдельных сервиса - это две точки отказа, две точки обновления, две точки настройки авторизации. При этом Harbor поддерживает OCI artifacts достаточно давно, просто до Helm 3.7 это было экспериментально и включалось флагом окружения на каждой машине разработчика.

Второй аргумент - сканирование. Trivy в Harbor сканирует container images автоматически при push. Charts там не образы, но тоже содержат yaml-шаблоны с references на образы. Хотелось иметь возможность хотя бы видеть, что лежит в одном месте. После того как мы настроили сканирование container images через Trivy, концентрировать всё в Harbor выглядело логично.

Что изменилось в Helm 3.7

До 3.7 OCI-функциональность жила за экспериментальным флагом и имела несколько неприятных особенностей: отдельный логин командой helm registry login, несовместимый с обычным helm repo add, и часть команд вела себя иначе, чем с обычными репозиториями.

В 3.7 OCI-реестры интегрированы в стандартный workflow. Флаг HELM_EXPERIMENTAL_OCI больше не нужен (и фактически игнорируется). Команды helm push, helm pull, helm show работают с oci:// схемой напрямую. Авторизация через helm registry login теперь совместима с docker-credential-helpers, что упрощает работу в CI.

Важный нюанс: chart-репозитории в классическом смысле (helm repo add) и OCI-реестры - это разные модели. В OCI нет index.yaml, нет helm repo update. Каждый chart - это отдельный OCI artifact с тегом-версией. Это ломает ряд привычных вещей, о которых скажем ниже.

Настройка Harbor

Harbor мы использовали версии 2.3, которая поддерживает OCI Distribution Spec 1.0. Для charts создали отдельный project - helm-charts. Никаких специальных настроек проекта для OCI artifacts не требуется, Harbor воспринимает их автоматически.

Права доступа настраиваются теми же robot accounts, что и для образов. Это, собственно, одно из главных преимуществ: один robot account с нужными правами работает и для docker pull, и для helm pull.

# Логин - один раз, credentials кешируются в ~/.config/helm/registry/config.json
helm registry login harbor.example.com \
  --username robot$ci-account \
  --password <токен>

Pipeline: push chart в Harbor

Клиентский пайплайн в GitLab. После сборки и тестирования chart публикуется в Harbor:

publish-chart:
  stage: publish
  image: alpine/helm:3.7.1
  script:
    - helm registry login ${HARBOR_HOST}
        --username ${HARBOR_USER}
        --password ${HARBOR_PASSWORD}
    - helm package charts/${CHART_NAME}
        --version ${CI_COMMIT_TAG}
        --app-version ${CI_COMMIT_TAG}
    - helm push ${CHART_NAME}-${CI_COMMIT_TAG}.tgz
        oci://${HARBOR_HOST}/helm-charts
  rules:
    - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'

При pull в кластере:

helm pull oci://harbor.example.com/helm-charts/app-name --version 1.2.3
# или сразу install
helm install my-release \
  oci://harbor.example.com/helm-charts/app-name \
  --version 1.2.3 \
  -f values-prod.yaml

Что сломалось при переезде

helm search repo не работает с OCI. В классическом репозитории helm search repo ищет по index.yaml. Для OCI-реестра этой команды нет - нужно смотреть в Harbor UI или использовать Harbor API. Для команды разработчиков, привыкших к helm search, это неудобно. Мы написали небольшой bash-скрипт, который дёргает Harbor API и выводит список charts с версиями в похожем формате.

Helmfile и зависимости. Helmfile поддерживает OCI начиная с версии 0.141.0. Клиент использовал 0.138 - пришлось обновить. Синтаксис в helmfile.yaml меняется: вместо repository: ... + chart: repo/name нужно писать chart: oci://harbor.example.com/helm-charts/app-name.

Chart dependencies через OCI. Если в Chart.yaml указаны dependencies с repository: "oci://...", то helm dependency update работает, но требует предварительного helm registry login. В CI это решается добавлением логина в начало скрипта, но нужно помнить.

Сканирование charts в Harbor

Trivy в Harbor умеет сканировать OCI artifacts, но charts сканируются иначе, чем образы. По факту Trivy разбирает chart как архив и ищет в нём references на образы, после чего сканирует эти образы. Это не то же самое, что сканировать сам chart на предмет misconfiguration в yaml - для этого нужен отдельный инструмент вроде helm lint или Checkov/Conftest.

Для клиента настроили автоматическое сканирование при push через политики Harbor. Плюс добавили helm lint в pipeline перед публикацией - это ловит синтаксические ошибки и явные несоответствия.

Что в итоге

Переезд занял примерно день с учётом обновления всех клиентских машин разработчиков и обновления Helmfile. ChartMuseum отключён, Harbor обслуживает и образы, и charts. Robot accounts единые, логин один.

Из неочевидного: мы потеряли helm search repo и получили необходимость смотреть версии через Harbor UI или API. Это реальное неудобство, и если в команде активно пользовались поиском по репозиторию - нужно готовиться. Плюс документацию пришлось обновить в нескольких местах, где были примеры с helm repo add.

OCI-подход к charts - это стандарт дистрибуции артефактов, который уже работает для образов. Иметь один registry вместо двух выглядит разумно. Но это не бесплатный переезд, и несколько вещей, привычных по ChartMuseum, там просто отсутствуют.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.