Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets

Рейтинг: 64.6% · 12 голосов
Практический курс по Docker: образы, контейнеры, тома, сети, Compose и продакшен. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
Marina_DevOps
Сообщения: 25
Зарегистрирован: 11 май 2026, 05:31

Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets

Сообщение Marina_DevOps »

АкадемияDocker с нуляГлава 14 из 17
Оглавление курса (17)
  1. Что такое Docker и какие задачи он решает
  2. Установка Docker и запуск первого контейнера
  3. Образы: слои, теги и реестр Docker Hub
  4. Пишем свой Dockerfile
  5. Тома и хранение данных: volumes и bind mounts
  6. Сети в Docker: связываем контейнеры между собой
  7. Переменные окружения и конфигурация контейнеров
  8. Docker Compose: поднимаем многоконтейнерное приложение
  9. Оптимизация образов: multi-stage сборка, размер и кэш слоёв
  10. Логи, отладка и мониторинг контейнеров
  11. Базовая безопасность контейнеров
  12. Подготовка к продакшену: что важно учесть
  13. Dockerfile глубже: ENTRYPOINT и CMD, HEALTHCHECK, .dockerignore, запуск не от root
  14. Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets (вы здесь)
  15. BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша
  16. Docker в CI/CD: автосборка, сканирование образов (Trivy, Docker Scout), публикация
  17. Итоговый проект и куда расти: от Dockerfile до прода, обзор оркестрации (Kubernetes, Podman, OCI)
В предыдущих главах образы жили в основном локально, а пушили мы их разве что в Docker Hub. На реальных проектах все иначе: образы лежат в приватных реестрах, CI заливает их туда автоматически, а кластер забирает по учетке с ограниченными правами. В этой главе: анатомия имени образа, push и pull в чужой реестр, свой registry за вечер, разница между тегом и digest и как подружить Kubernetes с закрытым реестром.

Анатомия имени образа:

Полное имя выглядит так: адрес-реестра[:порт]/пространство/репозиторий:тег. Когда вы пишете docker pull nginx, движок молча разворачивает это в docker.io/library/nginx:latest. Реестр зашит прямо в имя, отдельного параметра "куда пушить" у docker push нет. Отсюда практический вывод: чтобы залить образ в свой реестр, его сначала нужно перетегировать.

Код: Выделить всё

docker tag myapp:1.4.2 cr.yandex/crp1abc2def3/myapp:1.4.2
echo "$CR_TOKEN" | docker login cr.yandex -u oauth --password-stdin
docker push cr.yandex/crp1abc2def3/myapp:1.4.2
docker pull cr.yandex/crp1abc2def3/myapp:1.4.2
Логин только через --password-stdin, а не через -p, иначе пароль осядет в истории шелла. И помните: docker login по умолчанию складывает учетку в ~/.docker/config.json в base64, то есть фактически открытым текстом. На рабочей машине настройте credential helper (credsStore: osxkeychain, wincred, pass), а в CI используйте короткоживущие токены.

Варианты приватных реестров на 2026 год: GitLab Container Registry и ghcr.io идут бесплатным довеском к репозиториям, Harbor ставят как корпоративный реестр со сканированием и RBAC, в облаках СНГ есть Yandex Container Registry, реестры Selectel и VK Cloud.

Свой registry за вечер:

Для внутренних нужд хватает образа registry:3 (проект CNCF Distribution). Поднимем его с базовой аутентификацией:

Код: Выделить всё

mkdir -p auth
docker run --rm httpd:2.4 htpasswd -Bbn builder 'S3cret-2026' > auth/htpasswd

docker run -d --name registry --restart=always -p 5000:5000 \
  -v registry-data:/var/lib/registry \
  -v "$PWD/auth:/auth:ro" \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM=Registry \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  registry:3
Демон Docker по умолчанию требует HTTPS и откажется работать с таким реестром по голому HTTP. Для стенда в изолированной сети можно прописать адрес в insecure-registries в /etc/docker/daemon.json и перезапустить демон, но наружу так выставляться нельзя: логин и слои поедут в открытую. Нормальный путь: TLS-сертификат (хоть от Let's Encrypt) на реверс-прокси перед реестром.

Нюанс этого реестра: удаление образа через API не освобождает диск. Слои чистит отдельная команда garbage-collect внутри контейнера, и гонять ее нужно периодически, иначе том распухнет.

Теги против digest:

Тег подвижен. Сегодня myapp:1.4.2 указывает на один образ, завтра кто-то пересоберет и перезальет под тем же тегом другой. Digest, наоборот, неизменен: это sha256 от манифеста образа, и pull по digest всегда вернет байт в байт то же самое.

Код: Выделить всё

docker buildx imagetools inspect cr.yandex/crp1abc2def3/myapp:1.4.2
docker pull cr.yandex/crp1abc2def3/myapp@sha256:9f2c4e1a...
Правило для продакшена простое: деплоим по digest или хотя бы по уникальному тегу вида 1.4.2-a1b9f30 (версия плюс короткий хэш коммита), который никогда не перезаписывается. Тег latest в проде не используем вообще, он годится только для локальных экспериментов.

imagePullSecrets:

Kubernetes тянет образы сам, силами kubelet на каждой ноде, и ваш docker login ему ничего не говорит. Учетку для реестра кладут в секрет типа docker-registry:

Код: Выделить всё

kubectl create secret docker-registry cr-creds \
  --docker-server=cr.yandex \
  --docker-username=oauth \
  --docker-password="$CR_TOKEN" \
  -n staging
И ссылаются на него в манифесте пода:

Код: Выделить всё

spec:
  imagePullSecrets:
    - name: cr-creds
  containers:
    - name: app
      image: cr.yandex/crp1abc2def3/myapp@sha256:9f2c4e1a...
Секрет живет в конкретном namespace. Чтобы не прописывать его в каждом деплойменте, секрет добавляют в ServiceAccount, тогда все поды этого аккаунта получат его автоматически. В managed-кластерах часто еще проще: нодам выдают права на родной реестр облака, и секреты не нужны вовсе.

Типичные грабли:

Ошибка denied: requested access to the resource is denied при push почти всегда означает, что вы забыли docker tag с адресом реестра и докер ломится в Docker Hub под чужим именем. Права тут ни при чем.

Перезаливка существующего тега плюс кэш на нодах. Политика imagePullPolicy по умолчанию IfNotPresent (Always она только для latest и образов без тега). Нода, у которой образ уже есть, обновление просто не заметит, и вы получите кластер, где половина подов на старой версии. Лечится уникальными тегами или digest, а не перезаписью.

Лимиты Docker Hub на анонимные pull регулярно кладут CI: десятки джоб с одного NAT-адреса быстро упираются в потолок. Решение: аутентифицироваться в CI или поднять pull-through кэш, тот же registry:3 умеет работать прокси-зеркалом.

И не храните долгоживущие пароли реестра в переменных CI, если платформа умеет выдавать токен на время джобы: в GitLab это CI_JOB_TOKEN, у облаков IAM-токены с коротким сроком жизни.

Итог:

Реестр зашит в имя образа, тег подвижен, digest вечен. В прод деплоим по digest или неперезаписываемым тегам, Kubernetes ходит в приватный реестр через imagePullSecrets, а свой registry поднимается за вечер, но требует TLS и уборки мусора. В следующей главе берем BuildKit и buildx: multi-arch сборки, секреты сборки и экспорт кэша лягут как раз поверх того, что настроили сегодня.
👍4 ❤️2 🔥4 😄 🤔1
✔ Лучший ответ сформирован автоматически — basedstack
Marina_DevOps писал(а):Нода, у которой образ уже есть, обновление просто не заметит вот это мы прочувствовали на проде. перезаливали staging тег поверх, три пода из пяти крутили старую версию, два новую, и попробуй догадайся. с тех пор только тег с хэшем коммита и никаких latest
Перейти к ответу →
Аватара пользователя
mark327
Сообщения: 1
Зарегистрирован: 05 июн 2026, 03:31

Re: Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets

Сообщение mark327 »

Про denied: requested access to the resource is denied прям в точку. Неделю назад дергал админа, мол выдай мне права на реестр, а оказалось я запушил myapp:1.4.2 без префикса и докер ломился в Docker Hub. Полчаса жизни в никуда. Пусть тут полежит, может кому сэкономит время.
👍4 ❤️ 🔥 😄 🤔
Аватара пользователя
basedstack
Сообщения: 1
Зарегистрирован: 03 июн 2026, 06:54

Re: Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets

Сообщение basedstack »

✔ Лучший ответ — сформирован автоматически
Marina_DevOps писал(а):Нода, у которой образ уже есть, обновление просто не заметит
вот это мы прочувствовали на проде. перезаливали staging тег поверх, три пода из пяти крутили старую версию, два новую, и попробуй догадайся. с тех пор только тег с хэшем коммита и никаких latest
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
DockerAdmin
Сообщения: 2
Зарегистрирован: 04 июн 2026, 06:17

Re: Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets

Сообщение DockerAdmin »

А что посоветуете на команду из 5 человек, голый registry:3 за nginx с летсенкриптом или сразу Harbor? Харбор выглядит жирновато, там под капотом полдесятка контейнеров, жалко на это 4 гига оперативы на нашей виртуалке.
👍3 ❤️ 🔥 😄 🤔1
Аватара пользователя
levis
Сообщения: 4
Зарегистрирован: 02 июн 2026, 19:23

Re: Реестры образов: приватные registry, push и pull, теги и digest, imagePullSecrets

Сообщение levis »

по опыту: если нужен только push/pull, registry:3 хватает за глаза, бэкапить один том и не париться. Harbor берите когда захочется UI, retention-политики и сканер уязвимостей из коробки. ну или просто живите в gitlab registry, он у вас скорее всего уже есть
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Dockerfile глубже: ENTRYPOINT и CMD, HEALTHCHECK, .dockerignore, запуск не от root
Следующая глава →
BuildKit и buildx: multi-arch сборки, секреты сборки, экспорт кэша

Все главы курса «Docker с нуля»

Поделиться темой: ✈ Telegram VK

Вернуться в «Docker с нуля»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость