Как удалить изображения из частного реестра докеров?

Я запускаю приватный реестр докеров, и я хочу удалить все изображения, кроме latest из репозитория. Я не хочу удалять весь репозиторий, а только некоторые изображения внутри него. API docs не упоминают способ сделать это, но, возможно, это возможно?

Ответы

Ответ 1

В настоящее время вы не можете использовать Registry API для этой задачи. Это позволяет удалить репозиторий или определенный тег.

Как правило, удаление репозитория означает, что все теги, связанные с этим репо, удаляются.

Удаление тега означает, что связь между изображением и тегом удаляется.

Ни одно из указанных выше не удалит одно изображение. Они оставлены на вашем диске.


Обход

Для этого временного решения вам необходимо сохранить ваши файлы докеров.

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

Терминология (изображения и теги)

Рассмотрим граф изображений, подобный этому, где заглавные буквы (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, которое помечено.

Даже если вы используете этот script, изображение не будет удалено.

Когда изображение можно удалить

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

Обратите внимание, что на следующем графике изображение D не на основе C, а на B. Поэтому D не зависит от C. Если вы удалите тег <version1> в этом графике, изображение C не будет использоваться никаким изображением и this script может удалить его.

 A <- B <--------- D
      \            |
       \           <version2>
        \          <latest>
         \ <- C
              |
              <version1>

После очистки ваш графический граф выглядит следующим образом:

 A <- B <- D
           |
           <version2>
           <latest>

Это то, что вы хотите?

Ответ 3

Проблема 1

Вы упомянули, что это ваш приватный реестр докеров, поэтому вам, вероятно, нужно проверить "API-интерфейс реестра" вместо Док-станция API-интерфейса концентратора, которая является ссылкой, которую вы предоставили.

Проблема 2

docker registry API - это протокол клиент/сервер, до реализации сервера выполняется ли удаление изображений в фоновом режиме. (Я думаю)

DELETE /v1/repositories/(namespace)/(repository)/tags/(tag*)

Подробное описание

Ниже я расскажу, как это работает теперь из вашего описания в качестве моего понимания ваших вопросов.

Вы запускаете личный приватный реестр docker, я использую по умолчанию и слушаю в 5000 port

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"}

Ответ 4

У меня возникла такая же проблема с моим реестром, и я попробовал решение, перечисленное ниже, со страницы блога. Оно работает.

Шаг 1: Список каталогов

Вы можете перечислить свои каталоги, позвонив по этому URL:

http://YourPrivateRegistyIP:5000/v2/_catalog

Ответ будет в следующем формате:

{
  "repositories": [
    <name>,
    ...
  ]
}

Шаг 2: Идентификация тегов для связанного каталога

Вы можете указать теги своего каталога, позвонив по этому URL:

http://YourPrivateRegistyIP:5000/v2/<name>/tags/list

Ответ будет в следующем формате:

{
"name": <name>,
"tags": [
    <tag>,
    ...
]

}

Шаг 3: Отобразить значение манифеста для связанного тега

Вы можете запустить эту команду в контейнере реестра докеров:

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 ($3)}'

Ответ будет в следующем формате:

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  

Вот мой config.yml

[email protected]:/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

Ответ 5

Это действительно уродливо, но он работает, текст протестирован в реестре: 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 $1
    
  • Удалить манифесты:

    rm -rf ./repositories/$NAME/_manifests/tags/$VERSION
    
  • Выход

    exit
    
  • Запустите GC:

    docker exec -it registry  bin/registry garbage-collect  /etc/docker/registry/config.yml
    
  • Если все сделано правильно, отображается некоторая информация об удаленных блобах.

Ответ 6

Есть несколько клиентов (в 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

UPDATE: здесь короткое введение на deckschrubber.

Ответ 7

Это изображение докеры включает в себя bash script, который можно использовать для удаления изображений из удаленного реестра v2: https://hub.docker.com/r/vidarl/remove_image_from_registry/