Как отправить изображение в реестр Docker с помощью API реестра Docker v2
Я пишу API-интерфейс реестра Docker для извлечения изображений из одного частного реестра и отправки их в другой.
Основываясь на документации сначала мне нужно вытащить манифест и слои для image:tag
. После создания изображения я успешно загрузил все слои для определенного image:tag
и манифест.
После нажатия на изображение я выполнил следующие действия:
-
POST/v2/<name>/blobs/uploads/
(чтобы получить UUID, т.е. заголовок Location
) -
HEAD/v2/<name>/blobs/<digest>
(проверьте, существует ли он уже в реестре) -
PUT/v2/<name>/blobs/uploads/<uuid>?digest=<digest>
(Monolithic Upload
)
Что мне не ясно, так это следующее:
- Является ли
UUID
уникальным для каждого отдельного слоя, который я нажимаю, или он повторно используется для всех слоев (например, нужно ли мне запускать новый POST для каждого слоя и получать новый UUID
прежде чем я попытаюсь загрузить его?). - В разделе " Завершенная загрузка " указано
Чтобы загрузка считалась завершенной, клиент должен отправить запрос PUT на конечную точку загрузки с параметром дайджеста.
Однако, как уже упоминалось, я использую Monolithic Upload, который использует PUT
и будет таким же запросом, как показано в разделе Completed Upload. Таким образом, выполняя монолитную загрузку, я также одновременно завершаю загрузку?
проблема
-
Когда я BLOB_UNKNOWN
все вышеперечисленные шаги, я получаю BLOB_UNKNOWN
об ошибке BLOB_UNKNOWN
при загрузке дайджеста, например:
{"errors:" [{"code": "BLOB_UNKNOWN", "message": "blob неизвестно реестру", "detail": {"digest":}},...]}
Согласно документации эта ошибка возникает при нажатии манифеста и один из слоев в манифесте неизвестны:
Если один или несколько слоев неизвестны реестру, возвращаются ошибки BLOB_UNKNOWN. Поле подробного ответа об ошибке будет иметь поле дайджеста, идентифицирующее отсутствующий большой двоичный объект. Ошибка возвращается для каждого неизвестного большого двоичного объекта. Формат ответа следующий:
Что меня смущает в этом
- Я выдвигаю дайджест (он же слой), а не манифест, так почему эта ошибка возвращается?
- Я ожидаю, что BLOB-объект будет неизвестен, потому что я помещаю новое изображение в реестр
На данный момент я собираюсь использовать докер-клиент, но я не нашел в Интернете никаких примеров обёрток, чтобы посмотреть, как это происходит. Предположительно, мне не хватает какой-то логики или недоразумений в документах, но я не уверен, где я ошибаюсь?
Ответы
Ответ 1
Вау, приятно знать, что я не единственный, кто потерял в пустоте API V2...
Я реализую подобную библиотеку и столкнулась с той же проблемой. Из моего понимания документации есть две монолитные загрузки: один вариант обмена POST
(упомянутый внизу документов) и два варианта обмена POST
+ PUT
(упомянутый вверху документов).
Я не смог заставить работать только метод POST. В моем случае я использовал его для загрузки манифеста изображения после блобов слоя и до манифеста реестра. В то время как POST выглядит успешным и возвращает 202, регистрация отладки в реестре показывает, что он никогда не реплицировался из места размещения в хранилище данных (как это происходит после частичной загрузки). Последующая попытка загрузить манифест завершается неудачно с 400, и отладка журнала "BLOB-объектов, неизвестных реестру".
Однако я смог обойти эту проблему, используя метод POST + PUT.
Ключевые разделы в документах для меня были:
Хотя для заголовка Location указан формат URI (/v2//blobs/uploads/), клиенты должны воспринимать его как непрозрачный URL и никогда не пытаться его собрать.
а также
Монолитная загрузка - это просто фрагментная загрузка с одним фрагментом...
Следуя этим двум инструкциям, я создал новый заголовок Location (и UUID) с помощью POST, добавил значение дайджеста и завершил загрузку, поместив BLOB-объект в измененное местоположение.
Примечание: просматривая журналы отладки реестра, интерфейс командной строки док-станции проверяет наличие больших двоичных объектов перед началом новой загрузки (и после завершения загрузки также - при условии двойной проверки кода состояния).