← К программе курса

Модуль 15 / 18

Registry: публикация, authentication, mirror и retention

DOCKER

Содержание
01

1. Цели и модель registry

После модуля вы сможете публиковать image, разрешать tag в digest, читать Registry API, проектировать authentication/TLS и управлять retention.

  • repository группирует manifests
  • tag является изменяемым указателем
  • manifest связывает config и blobs
  • digest фиксирует содержимое
  • registry хранит OCI artifacts
02

2. Теория: Distribution API

/v2/ проверяет API; manifests endpoint принимает tag или digest; blobs адресуются digest. Push сначала загружает недостающие blobs, затем manifest.

Docker-Content-Digest возвращает canonical digest ответа. При удалении manifest используйте digest и правильный Accept media type.

03

3. Теория: TLS и authentication

Production registry обязан использовать TLS и access control. Basic htpasswd допустим только поверх TLS и требует bcrypt. Token auth выдаёт scoped bearer token для repository actions.

docker login хранит credential через configured credential store. Не передавайте password аргументом и не публикуйте registry анонимно.

04

4. Теория: storage, HA и consistency

Filesystem backend подходит одному экземпляру; HA требует совместимого shared object storage, одинакового secret/config и load balancer. Backup должен включать storage и конфигурацию identity/policy.

Registry availability не заменяет digest verification; proxy cache и CDN обязаны сохранять headers, ranges и immutable blob semantics.

05

5. Теория: retention и garbage collection

Удаление manifest убирает reference, но blobs могут остаться, пока на них ссылаются другие manifests. Garbage collector выполняет mark-and-sweep.

Для offline GC registry переводят read-only или останавливают: concurrent push может привести к удалению ещё не отмеченного blob. Retention учитывает tags, signatures и attestations.

06

6. Теория: pull-through cache

Registry mirror Docker Hub уменьшает повторные загрузки, но не является универсальным mirror любого private registry и остаётся subject to upstream policy.

Credentials upstream дают cache доступ к private content, поэтому сам mirror обязательно защищают. Cache не заменяет curated internal registry.

07

7. Методические указания

  • Используйте TLS и scoped least privilege
  • Продвигайте release по digest
  • Разделяйте push и pull identities
  • Проверяйте quota, latency и error rate
  • Не удаляйте tags без inventory attestations
  • Тестируйте restore registry
  • Запускайте GC в безопасном окне
  • Не логируйте Authorization headers
08

8. Лабораторная работа: локальный registry

Поднимите временный Registry 3 только на loopback, опубликуйте Alpine и исследуйте API.

terminal
docker run --detach --name docker-m15-registry --publish 127.0.0.1:15000:5000 --env REGISTRY_STORAGE_DELETE_ENABLED=true --volume docker-m15-registry:/var/lib/registry registry:3
for attempt in 1 2 3 4 5; do curl --fail --silent http://127.0.0.1:15000/v2/ && break; sleep 1; done
docker logs --tail 20 docker-m15-registry
docker inspect docker-m15-registry --format '{{json .Mounts}}' | jq
terminal
docker pull alpine:3.21
docker tag alpine:3.21 127.0.0.1:15000/course/alpine:3.21
docker push 127.0.0.1:15000/course/alpine:3.21
curl --fail --silent http://127.0.0.1:15000/v2/_catalog | jq
curl --fail --silent http://127.0.0.1:15000/v2/course/alpine/tags/list | jq

Получите canonical digest, pull по immutable reference, затем удалите manifest по digest.

terminal
manifest_digest=$(curl --fail --silent --head -H 'Accept: application/vnd.oci.image.manifest.v1+json' http://127.0.0.1:15000/v2/course/alpine/manifests/3.21 | tr -d '\r' | awk -F': ' 'tolower($1)=="docker-content-digest"{print $2}')
printf 'manifest_digest=%s\n' "$manifest_digest"
docker pull "127.0.0.1:15000/course/alpine@$manifest_digest"
docker image inspect "127.0.0.1:15000/course/alpine@$manifest_digest" --format '{{json .RepoDigests}}'
terminal
curl --fail --silent --request DELETE --output /dev/null --write-out 'delete_status=%{http_code}\n' "http://127.0.0.1:15000/v2/course/alpine/manifests/$manifest_digest"
curl --silent --output /dev/null --write-out 'manifest_after_delete=%{http_code}\n' -H 'Accept: application/vnd.oci.image.manifest.v1+json' http://127.0.0.1:15000/v2/course/alpine/manifests/3.21
docker pull 127.0.0.1:15000/course/alpine:3.21 || true

Критерий: catalog и tags видны; pull по digest успешен; DELETE возвращает 202; tag после удаления даёт 404.

09

9. Диагностика push/pull

Проверяйте путь DNS → TCP → TLS → /v2/ challenge → token scope → manifest → platform → blobs → storage.

terminal
curl -sS -D - -o /dev/null http://127.0.0.1:15000/v2/
docker logs --timestamps --tail 100 docker-m15-registry
docker inspect docker-m15-registry --format '{{json .State}}' | jq
docker system df
docker volume inspect docker-m15-registry
df -h /var/lib/docker
  • 401: authentication challenge/credentials
  • 403: scope или policy
  • 404: repository/tag/digest
  • 429: rate limit
  • 5xx: registry/storage
  • digest mismatch: integrity/proxy/storage
  • no matching manifest: platform
10

10. Контроль и cleanup

  • Tag или digest?
  • Что возвращает /v2/?
  • Зачем Accept при manifest?
  • Почему Basic требует TLS?
  • Что такое token scope?
  • Что удаляет DELETE manifest?
  • Почему GC требует read-only?
  • Чем mirror отличается от registry?
terminal
docker rm --force docker-m15-registry
docker volume rm docker-m15-registry
docker image rm 127.0.0.1:15000/course/alpine:3.21 2>/dev/null || true
docker ps -a --filter name=docker-m15

Модуль освоен, если вы публикуете immutable artifact и локализуете registry failure по протоколу.