MAATRIX / Блог / Zot выигрывает по памяти, Harbor — по функциям: что важнее вашему реестру

Zot выигрывает по памяти, Harbor — по функциям: что важнее вашему реестру

MAATRIX

Когда встаёт вопрос «нужен свой Docker-реестр», большинство статей и гайдов ведут прямиком к Harbor — и это оправданно, если вам нужна вся платформа целиком: веб-интерфейс, сканер уязвимостей, RBAC по проектам. Но если задача проще — хранить и раздавать образы команде без лишнего балласта, — Harbor тащит за собой PostgreSQL, Redis, Trivy и портал, даже если от него нужен только надёжный docker push/docker pull. Zot — минималистичный реестр, который умеет ровно то, что описано в OCI Distribution Spec, и почти ничего сверх этого. Разберём честно, где Zot выигрывает по простоте и памяти, а где без функций Harbor вы быстро упрётесь в стену.

Что такое Zot и почему он такой компактный

Zot — open source реестр контейнерных образов (проект в CNCF Sandbox), написанный на Go и распространяемый как один статический бинарник или один Docker-образ. Он реализует OCI Distribution Spec и OCI Image Spec — открытые стандарты, по которым работает docker push/pull независимо от того, куда вы стучитесь: в Docker Hub, GHCR или собственный сервер. Никакого проприетарного формата хранения, никакого наследия старого Docker Registry API v1 — только актуальный стандарт.

Ключевое архитектурное отличие от Harbor — Zot не требует внешней СУБД. Метаданные о репозиториях и тегах он хранит во встроенной BoltDB (файловое key-value хранилище) прямо рядом с блобами на диске, а сами блобы — на локальной файловой системе или в S3-совместимом хранилище. Один процесс, один конфиг-файл в JSON, никакой хореографии из docker-compose с полудюжиной сервисов, которые должны подняться в правильном порядке и не потерять связь друг с другом.

Практическое следствие: Zot стартует за секунды, а не за минуту-полторы, как Harbor с его цепочкой миграций БД при первом запуске. Если раньше вы поднимали приватный Docker Registry на голом registry:2, Zot — концептуальный преемник той же идеи «один простой сервис для хранения образов», но с полной поддержкой актуального стандарта OCI и рядом полезных расширений, которых у голого registry:2 нет вовсе.

Что даёт Harbor из коробки, а Zot — нет

Здесь Harbor выигрывает без оговорок, и именно за эти функции его выбирают, а не только за узнаваемое имя.

Полноценный веб-интерфейс. В Harbor вы браузером листаете проекты, репозитории, теги, видите размер каждого слоя и историю push — это ощутимо для команды, где не все привыкли жить в терминале. У Zot исторически нет встроенного богатого UI сопоставимого уровня: базовая часть функциональности доступна через API и CLI-утилиты, а полноценный веб-клиент (zui) существует как отдельный опциональный проект, а не встроенная часть основного дистрибутива.

Сканирование уязвимостей с историей и отчётами. В Harbor Trivy интегрирован так, что результаты скана каждого тега видны прямо в интерфейсе с разбивкой по severity, и это накапливается — можно посмотреть, когда именно в образе появилась критичная CVE. У Zot тоже можно подключить сканирование через расширение trivy в конфиге, но это работает скорее как фоновая проверка с результатом через API/CLI, без того же уровня наглядности и истории, что в Harbor.

RBAC на уровне проектов. Harbor строит модель прав вокруг проектов: роли admin/maintainer/developer/guest, robot-аккаунты с ограниченными правами для CI, привязка LDAP/OIDC-групп к ролям в конкретном проекте. У Zot модель прав проще — списки контроля доступа (ACL) по паттернам путей репозиториев с базовой авторизацией (htpasswd, LDAP, OIDC) и действиями read/create/update/delete на уровне пользователя. Для одной команды этого достаточно, но иерархии «проект → роль → права» как в Harbor нет.

Управляемая через UI репликация, вебхуки, квоты, retention-политики. В Harbor это настраивается кликами: указали удалённый реестр, задали правило репликации по расписанию, включили автоочистку старых тегов по политике хранения — и Harbor сам всё выполняет с логом операций. У Zot похожая функциональность есть (расширение sync умеет и зеркалировать из внешних реестров, и реплицировать между зот-инстансами), но настраивается декларативно через конфиг-файл, без UI и без встроенного журнала операций такого уровня подробности.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер под реестр

Память и ресурсы: разница не в проценты, а в разы

Это то место, где Zot отыгрывает всё назад. В отдельном разборе памяти для Harbor показано, что даже полностью бездействующий Harbor с включённым Trivy держит на борту порядка 900 МБ – 1,5 ГБ занятой памяти ещё до первого пуша образа, а официальный минимум в документации — 4 ГБ RAM, которых реально хватает только для теста «works on my machine».

Zot — один Go-процесс без отдельной СУБД и без JVM или Node.js-сателлитов. Его базовое потребление памяти в простое обычно измеряется десятками мегабайт, а не гигабайтом — это на порядок ниже, чем у Harbor. Точные цифры зависят от версии, числа репозиториев и включённых расширений, поэтому воспринимайте это как ориентир по практике эксплуатации, а не как результат контролируемого бенчмарка.

ПараметрZotHarbor
Процессов в стеке1 (сам Zot)8+ (core, registry, db, redis, jobservice, trivy, portal, nginx)
Внешняя СУБДне нужна (встроенная BoltDB)обязательна (PostgreSQL)
Память в простоедесятки МБ (ориентир)~0,9–1,5 ГБ (ориентир, из практики с Trivy)
Официальный минимум RAMне заявлен формально, комфортно от 512 МБ–1 ГБ4 ГБ по документации, реально комфортнее от 8 ГБ
Время запускасекундыдо минуты и больше на первом старте

На практике это значит, что Zot спокойно уживается на компактной VPS вместе с другими сервисами — CI-раннером, панелью управления, мониторингом, — не отъедая заметную долю памяти только на своё существование. Harbor на той же машине потребует либо отдельного сервера, либо серьёзного запаса памяти сверх того, что уже занято остальными сервисами.

Функции Zot, которые незаслуженно недооценивают

«Минималистичный» не значит «голый registry:2 с новой лейблой». У Zot есть набор расширений, включаемых в конфиге по необходимости, и часть из них закрывает задачи, которые интуитивно ждёшь только от Harbor:

  • search — полнотекстовый поиск по репозиториям и тегам через API, полезно, когда образов становится много и листать их вручную неудобно;
  • sync — репликация и зеркалирование: можно как реплицировать между несколькими инстансами Zot, так и подтягивать (mirror) образы из внешних реестров, чтобы иметь локальную копию на случай недоступности апстрима;
  • scrub — фоновая проверка целостности блобов на диске, находит повреждённые слои до того, как это всплывёт при попытке pull;
  • metrics — эндпоинт в формате Prometheus для мониторинга самого реестра — то же самое, что вы, скорее всего, уже используете для остальной инфраструктуры;
  • lint — проверка обязательных аннотаций образа перед тем, как разрешить push, удобно для соблюдения внутренних стандартов маркировки образов в команде;
  • trivy-scan — сканирование на уязвимости через тот же Trivy, что и в Harbor, только без отдельного богатого UI поверх результатов.

Отдельный плюс — Zot как честная OCI-реализация одинаково хорошо хранит не только классические Docker-образы, но и произвольные OCI-артефакты: Helm-чарты, SBOM, подписи Cosign. Для команды, которая уже смотрит в сторону хранения не только образов, но и сопутствующих артефактов supply chain, это может оказаться более прямым путём, чем настройка отдельных плагинов под каждый тип артефакта в других системах.

Установка Zot: минимальный рабочий стенд

Конфигурация Zot — один JSON-файл. Базовый вариант с локальным хранилищем, авторизацией через htpasswd и ACL по репозиториям:

{
  "distSpecVersion": "1.1.0",
  "storage": {
    "rootDirectory": "/var/lib/registry"
  },
  "http": {
    "address": "0.0.0.0",
    "port": "5000",
    "auth": {
      "htpasswd": {
        "path": "/etc/zot/htpasswd"
      }
    },
    "accessControl": {
      "repositories": {
        "**": {
          "policies": [
            {
              "users": ["deployer"],
              "actions": ["read", "create", "update"]
            }
          ],
          "defaultPolicy": ["read"]
        }
      }
    }
  },
  "log": {
    "level": "info"
  }
}

Файл пароля создаётся так же, как для registry:2:

mkdir -p /opt/zot/{data,config}
docker run --rm --entrypoint htpasswd httpd:2 -Bbn deployer 'СильныйПароль' > /opt/zot/config/htpasswd

Запуск контейнера — одна команда, без цепочки из install.sh и предварительной генерации сертификатов, как у Harbor:

docker run -d --name zot --restart unless-stopped \
  -p 127.0.0.1:5000:5000 \
  -v /opt/zot/data:/var/lib/registry \
  -v /opt/zot/config:/etc/zot \
  ghcr.io/project-zot/zot-linux-amd64:latest \
  serve /etc/zot/config.json

Уточните актуальный тег образа в документации проекта на момент установки — версии обновляются, а закреплённый тег вместо latest в проде убережёт от неожиданного апгрейда при пересоздании контейнера. Порт, как и в случае с голым registry:2, привязан к 127.0.0.1 — наружу реестр отдаётся через reverse proxy с HTTPS, Docker не работает с незашифрованным соединением, кроме localhost.

Проверка, что сервис поднялся:

curl http://127.0.0.1:5000/v2/

Пустой JSON-ответ {} означает, что реестр отвечает и готов принимать push после настройки HTTPS перед ним. Дальше docker login, docker tag, docker push работают идентично тому, что описано для базового registry:2 — Zot полностью совместим по API, разница только в том, что происходит под капотом.

Когда хватает Zot, а когда пора на Harbor

Однозначного правила по числу образов нет, но есть набор вопросов, ответы на которые обычно и определяют выбор:

  • Сколько человек пушат и забирают образы? Один-два разработчика или небольшая команда до 5-10 человек с общим доверием друг к другу — Zot с базовым ACL закрывает задачу полностью, отдельные роли и проекты избыточны.
  • Нужно ли сканирование уязвимостей как формальное требование комплаенса, с историей и отчётами для аудита? Если да — это довод в пользу Harbor: наглядный UI с историей сканов удобнее показывать при проверке, чем результат из API Zot.
  • Есть ли несколько команд/проектов, которым нужна изоляция прав друг от друга? Модель проектов Harbor с ролями создана именно под это. У Zot такое можно приблизить через ACL по паттернам путей репозиториев, но это требует более ручной дисциплины в именовании репозиториев и сложнее масштабируется на много команд.
  • Нужна ли управляемая репликация между несколькими реестрами в разных локациях с журналом операций? Zot умеет реплицировать через sync, но без UI и подробного лога это больше подходит для одного-двух статичных правил, а не для гибкого управления множеством направлений репликации.
  • Сколько памяти и CPU реально есть на сервере под реестр? На VPS с 1-2 ГБ RAM, где реестр — не единственный сервис, Zot оставляет заметно больше ресурсов остальным процессам, чем Harbor.

Грубый ориентир: соло-разработчик или команда до десятка человек с несколькими десятками-сотнями образов и без формальных требований к сканированию — Zot закрывает задачу с большим запасом и минимальными накладными расходами. Растущая команда с несколькими изолированными проектами, требованием аудита уязвимостей и репликацией между дата-центрами — здесь дополнительная память и сложность Harbor уже окупаются функциями, которые иначе пришлось бы собирать руками поверх Zot.

Совместимость и путь миграции между Zot и Harbor

Здесь у обоих реестров есть общий знаменатель, который снимает часть страха перед выбором: оба реализуют один и тот же открытый стандарт OCI Distribution Spec. Это значит, что образ, запушенный в Zot, физически ничем не отличается от того же образа в Harbor — то же манифест-дерево, те же слои, та же адресация по digest. Перенести образы между реестрами можно инструментами вроде skopeo copy или crane copy, которые просто копируют манифесты и блобы напрямую по OCI API, без пересборки.

Это открывает практичный сценарий: начать с Zot для MVP или небольшой команды, а когда компания вырастет и появятся требования к RBAC-проектам, сканированию с отчётностью или управляемой репликации — перенести накопленные образы в Harbor без переписывания CI-пайплайнов под другой формат. Изменится только URL реестра в docker login/docker push, сам механизм сборки и хранения образов остаётся прежним. Если реестр разворачивается впервые и вопрос HTTPS/авторизации ещё не решён — общие шаги (реверс-прокси, сертификат, авторизация) одинаковы что для Zot, что для registry:2, а частые грабли на этом пути (просроченный сертификат, обрыв push крупного образа, нехватка места под данные) разобраны в статье про типичные ошибки приватного Docker Registry на сервере, а для Harbor — в пошаговой установке на Ubuntu 24.04.

Для обоих сценариев важна одна и та же дисциплина эксплуатации: реестр — это не просто ещё один контейнер, а хранилище артефактов, от которых зависит деплой. Диск под данные должен резервироваться отдельно от остального, а при выборе сервера под реестр — будь то компактный Zot или полновесный Harbor — стоит закладывать запас по диску сразу, а не по памяти в первую очередь: место под образы растёт быстрее, чем растёт нагрузка на CPU. Для обоих вариантов подойдёт VPS с быстрым NVMe-диском в удобной локации с оплатой из России картой или криптой — разница только в том, сколько памяти вы заложите под сам реестр.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер под реестр

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Есть ли у Zot собственный веб-интерфейс?

Встроенного богатого UI сопоставимого с порталом Harbor в основном дистрибутиве нет — базовая работа идёт через API и CLI, полноценный веб-клиент существует как отдельный опциональный проект. Если наглядный браузер по репозиториям и тегам критичен для команды, это довод в пользу Harbor.

Можно ли получить сканирование уязвимостей в Zot без установки Harbor?

Да, через расширение trivy-scan в конфиге — используется тот же сканер, что и в Harbor, но без того же уровня наглядности отчётов и накопленной истории по каждому тегу.

Что случится с образами при переходе с Zot на Harbor?

Ничего критичного — оба реестра говорят на одном языке OCI Distribution Spec, образы переносятся инструментами вроде skopeo copy без пересборки и без изменения формата хранения.

Поддерживает ли Zot Helm-чарты и другие OCI-артефакты, а не только Docker-образы?

Да, как честная реализация OCI Distribution/Image Spec, Zot одинаково хранит Helm-чарты, SBOM и подписи Cosign — это иногда даже удобнее, чем настраивать под каждый тип артефакта отдельный плагин в других системах.

Стоит ли ставить Zot в прод, а не только для локального теста?

Да, это не игрушечный проект — Zot активно развивается, входит в CNCF Sandbox и используется как продакшен-реестр там, где не нужны функции уровня Harbor. Ограничение не в зрелости, а именно в наборе функций из коробки.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →