Как удалить изображения из частного реестра docker?
Я запускаю частный реестр докеров, и я хочу удалить все изображения, но latest
из репозитория. Я не хочу удалять весь репозиторий, только некоторые изображения внутри него. Элемент API docs не упоминайте способ сделать это, но, конечно, это возможно?
8 ответов:
в настоящее время вы не можете использовать API реестра для этой задачи. Он позволяет удалить только репозиторий или определенный тег.
в общем случае удаление репозитория означает, что все теги, связанные с этим РЕПО, удаляются.
удаление тега означает, что связь между изображением и тегом удаляется.
ни одно из вышеперечисленных не удалит ни одного изображения. Они остаются на вашем диск.
решение
для этого обходного пути вам нужно, чтобы ваши изображения докеров хранились локально.
обходным путем для вашего решения было бы удалить все, кроме последних тегов, и тем самым потенциально удалить ссылку на связанные изображения. Тогда вы можете запустить этот скрипт чтобы удалить все изображения, на которые не ссылается ни один тег или родословная любого используемого изображение.
терминология (изображения и теги)
рассмотрим графическое изображение, как это, где заглавные буквы (
A
,B
, ...) представляют собой короткие идентификаторы изображений и<-
означает, что изображение основано на другом изображении:A <- B <- C <- D
теперь мы добавляем теги к картинке:
A <- B <- C <- D | | | <version2> <version1>
, тег
<version1>
ссылки на изображенияC
и тег<version2>
ссылки на изображенияD
.уточнение вопрос
в своем вопросе вы сказали, что хотите удалить
все изображения, кроме
latest
. Сейчас эта терминология не совсем корректна. Вы смешали изображения и теги. Глядя на график, я думаю, вы согласитесь, что тег
<version2>
представляет последнюю версию. На самом деле, согласно этот вопрос вы можете иметь тег, который представляет последняя версия:A <- B <- C <- D | | | <version2> | <latest> <version1>
С
<latest>
тег ссылки на изображениеD
я спрашиваю вас: вы действительно хотите удалить все, кроме изображенияD
? Наверное, нет!что произойдет, если вы удалите тег?
если вы удалите тег
<version1>
С помощью Docker REST API вы получите следующее:A <- B <- C <- D | <version2> <latest>
помните: Docker никогда не удалит изображение! Даже если это так, в этом случае он не может удалить изображение, так как изображение
C
является частью родословной для изображенияD
что меченый.даже если вы используете этот скрипт, изображение не будет удалено.
когда изображение может быть удалено
при условии, что вы можете контролировать, когда кто-то может потянуть или нажать на ваш реестр (например, отключив интерфейс REST). Вы можете удалить изображение из графа изображений, если на нем нет другого изображения и на него не ссылается тег.
обратите внимание, что на следующем графике изображение
D
is не на основеC
но наB
. Таким образом,D
не зависит отC
. Если вы удалите тег<version1>
на этом графике, изображениеC
не будет использоваться ни одним изображением и этот скрипт можете удалить его.A <- B <--------- D \ | \ <version2> \ <latest> \ <- C | <version1>
после очистки ваш график изображения выглядит так:
A <- B <- D | <version2> <latest>
это то, что вы хотите?
я столкнулся с той же проблемой с моим реестром, то я попробовал решение, указанное ниже со страницы блога. Это работает.
Шаг 1: перечисление каталогов
вы можете перечислить свои каталоги, вызвав этот url:
http://YourPrivateRegistyIP:5000/v2/_catalog
ответ будет в следующем формате:
{ "repositories": [ <name>, ... ] }
Шаг 2: перечисление тегов для связанного каталога
вы можете перечислить теги вашего каталога, вызвав этот url:
http://YourPrivateRegistyIP:5000/v2/<name>/tags/list
ответ будет в следующий формат:
{ "name": <name>, "tags": [ <tag>, ... ]
}
Шаг 3: перечислите значение манифеста для связанного тега
вы можете запустить эту команду в контейнере реестра docker:
curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET http://localhost:5000/v2/<name>/manifests/<tag> 2>&1 | grep Docker-Content-Digest | awk '{print ()}'
ответ будет в следующем формате:
sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073
выполните приведенную ниже команду со значением манифеста:
curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X DELETE http://127.0.0.1:5000/v2/<name>/manifests/sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073
Шаг 4: Удалить отмеченные манифесты
выполните эту команду в контейнере реестра docker:
bin/registry garbage-collect /etc/docker/registry/config.yml
здесь мой конфиг.в формате YML
root@c695814325f4:/etc# cat /etc/docker/registry/config.yml version: 0.1 log: fields: service: registry storage: cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/lib/registry delete: enabled: true http: addr: :5000 headers: X-Content-Type-Options: [nosniff] health: storagedriver: enabled: true interval: 10s threshold: 3
текущего
v2
реестр теперь поддерживает удаление черезDELETE /v2/<name>/manifests/<reference>
см.: https://github.com/docker/distribution/blob/master/docs/spec/api.md#deleting-an-image
работа использование: https://github.com/byrnedo/docker-reg-tool
изменить: Манифест
<reference>
выше можно получить от запроса к
GET /v2/<name>/manifests/<tag>
и проверке
Docker-Content-Digest
заголовок в ответе.
1
Вы упомянули, что это был ваш личный реестр докеров, поэтому вам, вероятно, нужно проверить API реестра вместо Hub registry API doc, который является ссылкой, которую вы предоставили.
2
docker registry API-это протокол клиент / сервер, он зависит от реализации сервера о том, следует ли удалять изображения в фоновом режиме. (Я предположение)
DELETE /v1/repositories/(namespace)/(repository)/tags/(tag*)
подробное объяснение
ниже я демо как это работает сейчас из вашего описания как я понимаю на ваши вопросы.
вы запускаете частный реестр докеров, я использую по умолчанию и слушаю
5000
портdocker run -d -p 5000:5000 registry
затем я помечаю локальное изображение и нажимаю на него.
$ docker tag ubuntu localhost:5000/ubuntu $ docker push localhost:5000/ubuntu The push refers to a repository [localhost:5000/ubuntu] (len: 1) Sending image list Pushing repository localhost:5000/ubuntu (1 tags) 511136ea3c5a: Image successfully pushed d7ac5e4f1812: Image successfully pushed 2f4b4d6a4a06: Image successfully pushed 83ff768040a0: Image successfully pushed 6c37f792ddac: Image successfully pushed e54ca5efa2e9: Image successfully pushed Pushing tag for rev [e54ca5efa2e9] on {http://localhost:5000/v1/repositories/ubuntu/tags/latest}
после этого вы можете использовать Registry API чтобы проверить, что он существует в вашем частном докере реестр
$ curl -X GET localhost:5000/v1/repositories/ubuntu/tags {"latest": "e54ca5efa2e962582a223ca9810f7f1b62ea9b5c3975d14a5da79d3bf6020f37"}
теперь я могу удалить тег с помощью этого API !!
$ curl -X DELETE localhost:5000/v1/repositories/ubuntu/tags/latest true
проверьте еще раз, тег не существует в вашем частном сервере реестра
$ curl -X GET localhost:5000/v1/repositories/ubuntu/tags/latest {"error": "Tag not found"}
это действительно некрасиво, но это работает, Текст проверяется на реестре:2.5.1. Мне не удалось получить удаление работает гладко даже после обновления конфигурации, чтобы включить удаление. Идентификатор было очень трудно получить, пришлось войти в систему, чтобы получить его, возможно, какое-то недоразумение. Во всяком случае, работает следующее:
войдите в контейнер
docker exec -it registry sh
определите переменные, соответствующие вашему контейнеру и контейнеру версия:
export NAME="google/cadvisor" export VERSION="v0.24.1"
перейти в каталог реестра:
cd /var/lib/registry/docker/registry/v2
удалить файлы, связанные с вашим хэш:
find . | grep `ls ./repositories/$NAME/_manifests/tags/$VERSION/index/sha256`| xargs rm -rf
удалить манифесты:
rm -rf ./repositories/$NAME/_manifests/tags/$VERSION
выход
exit
запустите GC:
docker exec -it registry bin/registry garbage-collect /etc/docker/registry/config.yml
если все было сделано правильно, отображается некоторая информация об удаленных больших двоичных объектах.
есть некоторые клиенты (в Python, Ruby и т. д.), которые делают именно это. На мой вкус, это не устойчиво, чтобы установить время выполнения (например, Python)на моем сервере реестра, просто для ведения моего реестра!
так
deckschrubber
мое решение:go get github.com/fraunhoferfokus/deckschrubber $GOPATH/bin/deckschrubber
изображения старше заданного возраста автоматически удаляются. Возраст можно указать с помощью
-year
,-month
,-day
, или сочетание они:$GOPATH/bin/deckschrubber -month 2 -day 13 -registry http://registry:5000
обновление:вот краткое введение на deckschrubber.
этот образ docker включает в себя сценарий bash, который можно использовать для удаления изображений из удаленного реестра v2 : https://hub.docker.com/r/vidarl/remove_image_from_registry/
ниже Bash Script удаляет все теги, расположенные в реестре, кроме последнего.
for D in /registry-data/docker/registry/v2/repositories/*; do if [ -d "${D}" ]; then if [ -z "$(ls -A ${D}/_manifests/tags/)" ]; then echo '' else for R in $(ls -t ${D}/_manifests/tags/ | tail -n +2); do digest=$(curl -k -I -s -H -X GET http://xx.xx.xx.xx:5000/v2/$(basename ${D})/manifests/${R} -H 'accept: application/vnd.docker.distribution.manifest.v2+json' | grep Docker-Content-Digest | awk '{print }' ) url="http://xx.xx.xx.xx:5000/v2/$(basename ${D})/manifests/$digest" url=${url%$'\r'} curl -X DELETE -k -I -s $url -H 'accept: application/vnd.docker.distribution.manifest.v2+json' done fi fi done
после этого запустить
docker exec $(docker ps | grep registry | awk '{print }') /bin/registry garbage-collect /etc/docker/registry/config.yml