Модуль 15 / 18
Registry: публікація, authentication, mirror і retention
Зміст
1. Цілі та модель registry
Після модуля ви зможете публікувати image, перетворювати tag на digest, читати Registry API, проєктувати auth/TLS та retention.
- repository групує manifests
- tag — змінний покажчик
- manifest пов’язує config і blobs
- digest фіксує вміст
- registry зберігає OCI artifacts
2. Теорія: Distribution API
/v2/ перевіряє API; manifests endpoint приймає tag або digest; blobs адресуються digest. Push спочатку завантажує blobs, потім manifest.
Docker-Content-Digest повертає canonical digest. Manifest видаляють за digest із правильним Accept media type.
3. Теорія: TLS та authentication
Production registry потребує TLS і access control. Basic htpasswd дозволений лише поверх TLS та з bcrypt. Token auth видає scoped bearer token.
docker login має використовувати credential store. Не передавайте password аргументом і не залишайте anonymous push.
4. Теорія: storage, HA та consistency
Filesystem backend підходить одному instance; HA потребує shared object storage, однакових secrets/config та load balancer.
Registry availability не замінює digest verification; proxy/CDN мають зберігати headers, ranges та immutable blob semantics.
5. Теорія: retention та garbage collection
DELETE manifest прибирає reference, але shared blobs лишаються. Garbage collector робить mark-and-sweep.
Offline GC потребує read-only або зупинки registry; concurrent push ризикує corruption. Retention враховує signatures та attestations.
6. Теорія: pull-through cache
Docker Hub mirror зменшує downloads, але не є mirror будь-якого private registry та залежить від upstream policy.
Upstream credentials відкривають private content кешу, тому mirror потрібно захищати.
7. Методичні вказівки
- TLS і scoped least privilege
- Release за digest
- Окремі push/pull identities
- Моніторинг quota та errors
- Inventory attestations до delete
- Тест restore
- GC у безпечному вікні
- Не логувати Authorization
8. Лабораторна робота: локальний registry
Підніміть Registry 3 лише на loopback, push Alpine та дослідіть API.
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}}' | jqdocker 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Отримайте digest, pull immutable reference і видаліть manifest за digest.
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}}'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 доступні; digest pull успішний; DELETE 202; tag після delete дає 404.
9. Діагностика push/pull
Шлях: DNS → TCP → TLS → /v2/ challenge → scope → manifest → platform → blobs → storage.
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: auth
- 403: scope/policy
- 404: reference
- 429: rate limit
- 5xx: storage
- digest mismatch: integrity
- no matching manifest: platform
10. Контроль і cleanup
- Tag чи digest?
- Що повертає /v2/?
- Навіщо Accept?
- Чому Basic лише з TLS?
- Що таке scope?
- Що видаляє DELETE?
- Чому GC read-only?
- Mirror чи registry?
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 і локалізуєте failure за протоколом.