Подтвердить что ты не робот

Docker Registry 2.0 - как удалить неиспользуемые изображения?

Мы обновили наш частный реестр докеров в официальном реестре 2.0. Эта версия теперь может удалять изображения докеров, идентифицированные хэштагом (см. https://docs.docker.com/registry/spec/api/#deleting-an-image), но я до сих пор не вижу способа очистки старых изображений.

Поскольку наш сервер CI непрерывно создает новые изображения, мне нужен метод для удаления всех изображений из частного реестра, которые больше не идентифицируются с помощью именованного тега.

Если для этого не существует встроенного способа, я думаю, что пользовательский script мог бы работать, но я не вижу метода API v2 для перечисления всех сохраненных хэштегов изображения.

Как я могу сохранить свой частный реестр в чистоте? Любые подсказки?

4b9b3361

Ответ 1

Удаление изображений (вы можете сохранить 10 последних версий, как это делается в моем CI) выполняется в три этапа:

  • Включить удаление изображения, установив переменную окружения REGISTRY_STORAGE_DELETE_ENABLED: "true" и передав ее в docker-registry

  • Запустите ниже script (он удалит все изображения и теги, но сохранит последние 10 версий)

    registry.py -l user: pass -r https://example.com:5000 --delete --num 10

  • Запустите сборку мусора (вы можете поместить его в свою ежедневную задачу cron)

    docker-compose -f [path_to_your_docker_compose_file] запустите реестр bin/registry garbage-collect/etc/docker/registry/config.yml

registry.py можно загрузить по приведенной ниже ссылке, он также позволяет перечислять изображения, теги и слои, а также удалять определенный образ и/или тег.

https://github.com/andrey-pohilko/registry-cli

До сбора мусора моя папка реестра была 7 Гб, после того, как я выполнил вышеуказанные шаги, она спустилась до 1 ГБ.

Ответ 2

Это выполнимо, хотя и некрасиво. Вам нужно запустить (я думаю) реестр 2.3 или выше и разрешить удаление (REGISTRY_STORAGE_DELETE_ENABLED=True env var или эквивалентный). Приведенные ниже примеры команд предполагают наличие локального хранилища файлов в /srv/docker-registry, но я был бы удивлен, если бы не удалось подготовить что-то эквивалентное для других бэкэндов хранилища.

Для каждого репозитория, который вы хотите привести в порядок, вам нужно перечислить ссылки дайджеста, которые больше не требуются. Самый простой способ сделать это - для каждого тега, используя в качестве примера в этом случае latest вариант, вы бы сделали что-то вроде:

ls -1tr /srv/docker-registry/v2/repositories/<repo>/_manifests/tags/latest/index/sha256 \
| tail -n +3

Это будет список всех, кроме трех последних дайджесты толкнул к latest метке. С другой стороны, если вы не очень заботитесь о тегах, но просто хотите сохранить последние несколько ссылок, вы можете сделать следующее:

ls -1t /srv/docker-registry/v2/repositories/<repo>/_manifests/revisions/sha256 \
| tail -n +3

Затем вы просто удаляете ненужные ссылки:

for hash in $(ls -1t /srv/docker-registry/v2/repositories/<repo>/_manifests/tags/latest/index/sha256 | tail -n +3); do
  curl -X DELETE https://registry:5000/v2/<repo>/manifests/sha256:$hash
done

Наконец, вам нужно выполнить GC, потому что в реестре реализовано "мягкое удаление", которое фактически ничего не удаляет, а просто делает его недоступным:

docker exec docker-registry /bin/registry \
  garbage-collect /path/to/config.yml

Да, все это чертовски беспорядочно, тратится на внутреннее хранилище, потому что не существует метода API для перечисления всех дайджестов, связанных с данным тегом, но способ, которым cookie рушится.

Ответ 3

По вашему вопросу:

Мне нужен метод, чтобы удалить все изображения из частного реестра, которые больше не идентифицируются по имени тега

Новая версия реестра Docker в distribution/registry:master имеет эту приятную особенность! Однако вы не сможете запустить его из API.

В любом случае вы сможете очистить все непомеченные манифесты в своем реестре, что означает, что каждый перезаписанный тег не будет оставлять старые манифесты и капли в реестре. Каждый "неиспользованный" слой будет очищен утилитой реестра мусора.

Вы просто должны запустить docker exec:

docker exec ${container_id} registry garbage-collect \ 
  /path/to/your/registry/config.yml \
  --delete-untagged=true

Глядя на эту бинарную справку по сбору мусора:

Usage: 
  registry garbage-collect <config> [flags]
Flags:
  -m, --delete-untagged=false: delete manifests that are not currently referenced via tag
  -d, --dry-run=false: do everything except remove the blobs
  -h, --help=false: help for garbage-collect

Вы можете взглянуть на GitHub PR. Он был объединен и использован с distribution/registry, master тегов по состоянию на 2018-02-23. Он заменяет проект docker/docker-registry новым API-интерфейсом, ориентированным на безопасность и производительность...

Я использовал эту функцию сегодня и восстановил 89% пространства реестра (5,7 ГБ против 55 ГБ). Затем я снова переключился на стабильный registry.

Ответ 5

Я собрал различные части этого потока и создал простую в использовании утилиту script в bash Вы можете проверить это в этом gist cleanup.sh

Ответ 6

Я искал одну и ту же функциональность в реестре v2 api, но только нашел мягкое удаление, чего я не искал. Во время исследования я нашел проект Github delete-docker-registry-image, который удаляет фактические файлы с установленного тома с помощью bash script. Не проверено это, возможно, полезно...

Ответ 7

Я размещаю регестрирование в Docker-контейнере с именем docker-registry_registry_1 из image: registry:2

Я просто запускаю -m garbage-collect с -m

docker exec docker-registry_registry_1 bin/registry garbage-collect /etc/docker/registry/config.yml -m